""" default_symbolics_mapping :: Dict{String,Any} Default mapping of SBML function names to Julia functions, represented as a dictionary from Strings (SBML names) to anything `eval`uable as Julia&Symbolics functions, such as symbols and expressions. The default mapping only contains the basic SBML functions that are unambiguously represented in Julia; it is supposed to be extended by the user if more functions need to be supported. """ const default_symbolics_mapping = Dict{String,Any}( "*" => :*, "+" => :+, "-" => :-, "/" => :/, "abs" => :abs, "arccos" => :acos, "arccosh" => :acosh, "arccot" => :acot, "arccoth" => :acoth, "arccsc" => :acsc, "arccsch" => :acsch, "arcsec" => :asec, "arcsech" => :asech, "arcsin" => :asin, "arcsinh" => :asinh, "arctan" => :atan, "arctanh" => :atanh, "ceiling" => :ceil, "cos" => :cos, "cosh" => :cosh, "cot" => :cot, "coth" => :coth, "csc" => :csc, "csch" => :csch, "eq" => :isequal, "exp" => :exp, "factorial" => :factorial, "floor" => :floor, "geq" => :>=, "gt" => :>, "leq" => :<=, "ln" => :log, "log" => :sbmlLog, "lt" => :<, "piecewise" => :(Core.ifelse), "power" => :^, "root" => :sbmlRoot, "sech" => :sech, "sec" => :sec, "sinh" => :sinh, "sin" => :sin, "tanh" => :tanh, "tan" => :tan, ) sbmlLog(x) = log(x, 10) sbmlLog(base, x) = log(base, x) sbmlRoot(x) = sqrt(x) sbmlRoot(power, x) = x^(1 / power) allowed_sym(x, allowed_funs) = haskey(allowed_funs, x) ? allowed_funs[x] : throw(DomainError(x, "Unknown SBML function")) """ const default_symbolics_constants::Dict{String, Any} A dictionary of default constants filled in place of SBML Math constants in the symbolics conversion. """ const default_symbolics_constants = Dict{String,Any}("true" => true, "false" => false, "pi" => pi, "e" => exp(1)) """ Base.convert( ::Type{Num}, x::SBML.Math; mapping = default_symbolics_mapping, convert_time = (x::SBML.MathTime) -> Num(Variable(Symbol(x.id))).val, convert_const = (x::SBML.MathConst) -> Num(default_symbolics_constants[x.id]), ) Convert SBML.[`Math`](@ref) to `Num` type from Symbolics package. The conversion of functions can be customized by supplying a custom mapping; if nothing is supplied, [`default_symbolics_mapping`](@ref) that translates basic functions to their Julia equivalents is assumed. Translation of [`MathLambda`](@ref) is not supported by Symbolics. [`MathTime`](@ref) is handled specially, the function from the argument `convert_time` is called to possibly specify any desired behavior. By default, it just creates a variable with the same name as the time variable name stored in SBML. """ function Base.convert( ::Type{Num}, x::SBML.Math; mapping = default_symbolics_mapping, convert_time = (x::SBML.MathTime) -> Num(Variable(Symbol(x.id))).val, convert_const = (x::SBML.MathConst) -> Num(default_symbolics_constants[x.id]), ) conv(x::SBML.MathApply) = eval(allowed_sym(x.fn, mapping))(conv.(x.args)...) conv(x::SBML.MathTime) = convert_time(x) conv(x::SBML.MathConst) = convert_const(x) conv(x::SBML.MathIdent) = Num(Variable(Symbol(x.id))).val conv(x::SBML.MathVal) = Num(x.val) conv(x::SBML.MathLambda) = throw(DomainError(x, "can't translate lambdas to symbolics")) conv(x) end