Parsing Julia Expressions to Symbolic Expressions
Julia expressions such as :(y - x)
are fundamentally different from symbolic expressions, as they do not have an algebra defined on them. Thus, it can be very helpful when building domain-specific languages (DSLs) and parsing files to convert from Julia expressions to Symbolics.jl expressions for further manipulation. Towards this end is the parse_expr_to_symbolic
which performs the parsing.
Take the limitations mentioned in the parse_expr_to_symbolic
docstrings seriously! Because Julia expressions contain no symbolic metadata, there is limited information and thus the parsing requires heuristics to work.
Symbolics.parse_expr_to_symbolic
— Functionparse_expr_to_symbolic(ex, mod::Module)
Applies the parse_expr_to_symbolic
function in the current module, i.e. parse_expr_to_symbolic(ex, mod)
where mod
is the module of the function caller.
Arguments
ex
: the expression to parsemod
: the module to apply the parsing in. See the limitations section for details.
Example
ex = :(y(t) ~ x(t))
parse_expr_to_symbolic(ex,Main) # gives the symbolic expression `y(t) ~ x(t)` in empty Main
# Now do a whole system
ex = [:(y ~ x)
:(y ~ -2x + 3 / z)
:(z ~ 2)]
eqs = parse_expr_to_symbolic.(ex, (Main,))
@variables x y z
ex = [y ~ x
y ~ -2x + 3 / z
z ~ 2]
all(isequal.(eqs,ex)) # true
Limitations
Symbolic-ness Tied to Environment Definitions
The parsing to a symbolic expression has to be able to recognize the difference between functions, numbers, and globals defined within one's Julia environment and those that are to be made symbolic. The way this functionality handles this problem is that it does not define anything as symbolic that is already defined in the chosen mod
module. For example, f(x,y)
will have f
as non-symbolic if the function f
(named f
) is defined in mod
, i.e. if isdefined(mod,:f)
is true. When the symbol is defined, it will be replaced by its value. Notably, this means that the parsing behavior changes depending on the environment that it is applied.
For example:
parse_expr_to_symbolic(:(x - y),@__MODULE__) # x - y
x = 2.0
parse_expr_to_symbolic(:(x - y),@__MODULE__) # 2.0 - y
This is required to detect that standard functions like -
are functions instead of symbolic symbols. For safety, one should create anonymous modules or other sub-environments to ensure no stray variables are defined.
Metadata is Blank
Because all the variables defined by the expressions are not defined with the standard @variables
, there is no metadata that is or can be associated with any of the generated variables. Instead, they all have blank metadata, but are defined in the Real
domain. Thus, the variables which come out of this parsing may not evaluate as equal to a symbolic variable defined elsewhere.
Missing docstring for @parse_expr_to_symbolic
. Check Documenter's build log for details.