@@ -216,21 +216,38 @@ function sparsehessian(O, vars::AbstractVector; simplify = true)
216216end
217217
218218function toexpr (O)
219- ! istree (O) && return O
220- if isa (operation (O), Differential)
221- return :(derivative ($ (toexpr (arguments (O)[1 ])),$ (toexpr (operation (O). x))))
222- elseif isa (operation (O), Sym)
223- isempty (arguments (O)) && return operation (O). name
224- return Expr (:call , toexpr (operation (O)), toexpr .(arguments (O))... )
219+ canonical, O = canonicalexpr (O)
220+ canonical && return O
221+
222+ op = operation (O)
223+ args = arguments (O)
224+ if op isa Differential
225+ return :(derivative ($ (toexpr (args[1 ])),$ (toexpr (op. x))))
226+ elseif op isa Sym
227+ isempty (args) && return nameof (op)
228+ return Expr (:call , toexpr (op), toexpr .(args)... )
225229 end
226- if operation (O) === (^ )
227- if length (arguments (O)) > 1 && arguments (O)[2 ] isa Number && arguments (O)[2 ] < 0
228- return Expr (:call , ^ , Expr (:call , inv, toexpr (arguments (O)[1 ])), - (arguments (O)[2 ]))
230+ return Expr (:call , op, toexpr .(args)... )
231+ end
232+ toexpr (s:: Sym ) = nameof (s)
233+
234+ """
235+ canonicalexpr(O) -> (canonical::Bool, expr)
236+
237+ Canonicalize `O`. Return `canonical` if `expr` is valid code to generate.
238+ """
239+ function canonicalexpr (O)
240+ ! istree (O) && return true , O
241+ op = operation (O)
242+ args = arguments (O)
243+ if op === (^ )
244+ if length (args) == 2 && args[2 ] isa Number && args[2 ] < 0
245+ expr = Expr (:call , ^ , Expr (:call , inv, toexpr (args[1 ])), - args[2 ])
246+ return true , expr
229247 end
230248 end
231- return Expr ( :call , operation (O), toexpr .( arguments (O)) ... )
249+ return false , O
232250end
233- toexpr (s:: Sym ) = nameof (s)
234251
235252function toexpr (eq:: Equation )
236253 Expr (:(= ), toexpr (eq. lhs), toexpr (eq. rhs))
0 commit comments