docs: def expr_to_json(expr):
      """
      Converts a Sympy expression to a json-compatible tree-structure.
      """
      if isinstance(expr, symbolics.Mul):
          return {"type": "Mul", "args": [expr_to_json(arg) for arg in expr.args]}
      elif isinstance(expr, symbolics.Add):
          return {"type": "Add", "args": [expr_to_json(arg) for arg in expr.args]}
      elif isinstance(expr, symbolics.Symbol):
          return {"type": "Symbol", "name": expr.name}
      elif isinstance(expr, symbolics.Pow):
          return {"type": "Pow", "args": [expr_to_json(arg) for arg in expr.args]}
      elif isinstance(expr, (float, int)):
          return {"type": "Number", "value": expr}
      elif isinstance(expr, symbolics.Real):
          return {"type": "Number", "value": float(expr)}
      elif isinstance(expr, symbolics.Integer):
          return {"type": "Number", "value": int(expr)}
      else:
          raise NotImplementedError("Type not implemented: " + str(type(expr)))