Lean4
/-- Recursively compute the Array of `getAddends` Arrays by recursing into the expression `sum`
looking for instance of the operation `op`.
Possibly returns duplicates!
-/
partial def getOps (sum : Expr) : MetaM (Array ((Array Expr) × Expr)) := do
let summands ← getAddends op (← inferType sum <|> return sum) sum
let (first, rest) := if summands.size == 1 then (#[], sum.getExprInputs) else (#[(summands, sum)], summands)
let rest ← rest.mapM getOps
return rest.foldl Array.append first