@@ -216,21 +216,38 @@ function sparsehessian(O, vars::AbstractVector; simplify = true)
216
216
end
217
217
218
218
function 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)... )
225
229
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
229
247
end
230
248
end
231
- return Expr ( :call , operation (O), toexpr .( arguments (O)) ... )
249
+ return false , O
232
250
end
233
- toexpr (s:: Sym ) = nameof (s)
234
251
235
252
function toexpr (eq:: Equation )
236
253
Expr (:(= ), toexpr (eq. lhs), toexpr (eq. rhs))
0 commit comments