Mathics
Mathics copied to clipboard
Mathics crashes when trying to solve a differention equation whose result can't be expressed as an explicit function
The solutions for the following differential equation can't be easily expressed as explicit functions:

The solutions to this equation are given implicitly by the equation:

So, here's the bug:
In[1]:= DSolve[y'[x] == 1 + Sqrt[x^2 + y[x]^2] / x, y[x], x
Integrate::ilim: Invalid integration variable or limit(s).
Integrate::ilim: Invalid integration variable or limit(s).
File "/home/pablo/.local/bin/mathicsscript", line 293, in <module>
main()
File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.6/dist-packages/click-7.1.2-py3.6.egg/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/home/pablo/.local/bin/mathicsscript", line 276, in main
result = evaluation.evaluate(query, timeout=settings.TIMEOUT)
File "/home/pablo/Documents/Mathics/mathics/core/evaluation.py", line 291, in evaluate
result = run_with_timeout_and_stack(evaluate, timeout)
File "/home/pablo/Documents/Mathics/mathics/core/evaluation.py", line 95, in run_with_timeout_and_stack
return request()
File "/home/pablo/Documents/Mathics/mathics/core/evaluation.py", line 269, in evaluate
result = query.evaluate(self)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
expr, reevaluate = expr.evaluate_next(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
eval_range(range(len(leaves)))
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
leaves[index] = leaf.evaluate(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
expr, reevaluate = expr.evaluate_next(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
eval_range(range(len(leaves)))
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
leaves[index] = leaf.evaluate(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
expr, reevaluate = expr.evaluate_next(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
eval_range(range(len(leaves)))
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
leaves[index] = leaf.evaluate(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
expr, reevaluate = expr.evaluate_next(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1154, in evaluate_next
eval_range(range(len(leaves)))
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1142, in eval_range
leaves[index] = leaf.evaluate(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1094, in evaluate
expr, reevaluate = expr.evaluate_next(evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 1222, in evaluate_next
result = rule.apply(new, evaluation, fully=False)
File "/home/pablo/Documents/Mathics/mathics/core/rules.py", line 64, in apply
yield_match, expression, {}, evaluation, fully=fully)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 239, in match
yield_head, expression.get_head(), vars, evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 137, in match
yield_func(vars, None)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 231, in yield_head
yield_choice, expression, attributes, head_vars)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 358, in get_pre_choices
yield_func(vars)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 220, in yield_choice
wrap_oneid=expression.get_head_name() != 'System`MakeBoxes')
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 519, in match_leaf
include_flattened=include_flattened)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 379, in get_wrappings
yield_func(items[0])
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 515, in yield_wrapping
leaf_count=leaf_count, wrap_oneid=wrap_oneid)
File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 770, in match
self.pattern.match(yield_func, expression, new_vars, evaluation)
File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 955, in match
yield_func(vars, None)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 507, in match_yield
leaf_count=leaf_count, wrap_oneid=wrap_oneid)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 519, in match_leaf
include_flattened=include_flattened)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 379, in get_wrappings
yield_func(items[0])
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 515, in yield_wrapping
leaf_count=leaf_count, wrap_oneid=wrap_oneid)
File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 770, in match
self.pattern.match(yield_func, expression, new_vars, evaluation)
File "/home/pablo/Documents/Mathics/mathics/builtin/patterns.py", line 955, in match
yield_func(vars, None)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 510, in match_yield
yield_func(new_vars, items_rest)
File "/home/pablo/Documents/Mathics/mathics/core/pattern.py", line 499, in leaf_yield
(list(chain(rest_expression[0], items_rest[0])), next_rest[1]))
File "/home/pablo/Documents/Mathics/mathics/core/rules.py", line 40, in yield_match
new_expression = self.do_replace(expression, vars, options, evaluation)
File "/home/pablo/Documents/Mathics/mathics/core/rules.py", line 129, in do_replace
return self.function(evaluation=evaluation, **vars_noctx)
File "/home/pablo/Documents/Mathics/mathics/builtin/arithmetic.py", line 847, in apply_check
result = self.apply(Expression('Sequence', x, y), evaluation)
File "/home/pablo/Documents/Mathics/mathics/builtin/arithmetic.py", line 50, in apply
result = Expression(self.get_name(), *args).to_sympy()
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
sympy_expr = builtin.to_sympy(self, **kwargs)
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in to_sympy
sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in <listcomp>
sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
sympy_expr = builtin.to_sympy(self, **kwargs)
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in to_sympy
sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in <listcomp>
sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
sympy_expr = builtin.to_sympy(self, **kwargs)
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in to_sympy
sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 468, in <listcomp>
sympy_args = [leaf.to_sympy(**kwargs) for leaf in leaves]
File "/home/pablo/Documents/Mathics/mathics/core/expression.py", line 889, in to_sympy
sympy_expr = builtin.to_sympy(self, **kwargs)
File "/home/pablo/Documents/Mathics/mathics/builtin/base.py", line 472, in to_sympy
return sympy_function(*sympy_args)
File "/home/pablo/.local/lib/python3.6/site-packages/sympy/integrals/integrals.py", line 87, in __new__
obj = AddWithLimits.__new__(cls, function, *symbols, **assumptions)
File "/home/pablo/.local/lib/python3.6/site-packages/sympy/concrete/expr_with_limits.py", line 494, in __new__
pre = _common_new(cls, function, *symbols, **assumptions)
File "/home/pablo/.local/lib/python3.6/site-packages/sympy/concrete/expr_with_limits.py", line 48, in _common_new
limits, orientation = _process_limits(*symbols)
File "/home/pablo/.local/lib/python3.6/site-packages/sympy/concrete/expr_with_limits.py", line 156, in _process_limits
raise ValueError('Invalid limits given: %s' % str(symbols))
ValueError: Invalid limits given: (SympyExpression(_Mathics_User_System`List, _u2, _Mathics_User_Global`x/SympyExpression(_Mathics_User_Global`y, _Mathics_User_Global`x)),)
By digging around a bit, I was able to figure out that it's a bug in SymPy. After processing the differential equation, SymPy returns this:
[Eq(_Mathics_User_Global`y(_Mathics_User_Global`x), C1*exp(-Integral(sqrt(_u2**2 + 1)/(_u2*(_u2 + sqrt(_u2**2 + 1) - 1)), (_u2, _Mathics_User_Global`x/_Mathics_User_Global`y(_Mathics_User_Global`x))) - Integral(1/(_u2 + sqrt(_u2**2 + 1) - 1), (_u2, _Mathics_User_Global`x/_Mathics_User_Global`y(_Mathics_User_Global`x)))))]
This is malformed output. First of all, it mentions a variable called _u2 (which I assume is a temporary substitution variable _u2 = y/x SymPy uses internally). Also, the expression Integral(..., (_u2, y/x)) doesn't make much sense.