Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplifying the result of ReplaceAll sometimes fails with 'SympyExpression' object has no attribute 'expr' #920

Open
HolyBlackCat opened this issue Sep 19, 2023 · 1 comment

Comments

@HolyBlackCat
Copy link

Description

How to Reproduce

Type following expressions:

eq = {X[a],Y[a]}*x+{X[b],Y[b]}=={X[c],Y[c]}*y
sol = Simplify[Solve[Thread[eq], {x,y}]] (* Simplify works here *)
Simplify[X0*x+Y0*y //. sol] (* And doesn't work after replacement *)

Output Given

In[1]:= eq = {X[a],Y[a]}*x+{X[b],Y[b]}=={X[c],Y[c]}*y
Out[1]= {x X[a] + X[b], x Y[a] + Y[b]} ⩵ {y X[c], y Y[c]}

In[2]:= sol = Simplify[Solve[Thread[eq], {x,y}]] (* Simplify works here *)
Out[2]= {{x → (X[c] Y[b] - X[b] Y[c]) / (X[a] Y[c] - X[c] Y[a]), y → (X[a] Y[b] - X[b] Y[a]) / (X[a] Y[c] - X[c] Y[a])}}

In[3]:= Simplify[X0*x+Y0*y //. sol] (* And doesn't work after replacement *)

Then it crashes:

Traceback (most recent call last):
  File "/usr/local/bin/mathicsscript", line 33, in <module>
    sys.exit(load_entry_point('mathicsscript', 'console_scripts', 'mathicsscript')())
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1157, in __call__
    return self.main(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1078, in main
    rv = self.invoke(ctx)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 1434, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python3.10/dist-packages/click/core.py", line 783, in invoke
    return __callback(*args, **kwargs)
  File "/usr/src/app/src/mathicsscript/mathicsscript/__main__.py", line 428, in main
    result = evaluation.evaluate(
  File "/usr/src/app/mathics-core/mathics/core/evaluation.py", line 294, in evaluate
    result = run_with_timeout_and_stack(evaluate, timeout, self)
  File "/usr/src/app/mathics-core/mathics/core/evaluation.py", line 110, in run_with_timeout_and_stack
    return request()
  File "/usr/src/app/mathics-core/mathics/core/evaluation.py", line 267, in evaluate
    self.last_eval = query.evaluate(self)
  File "/usr/src/app/mathics-core/mathics/core/expression.py", line 507, in evaluate
    expr, reevaluate = expr.rewrite_apply_eval_step(evaluation)
  File "/usr/src/app/mathics-core/mathics/core/list.py", line 154, in rewrite_apply_eval_step
    new = new.evaluate_elements(evaluation)
  File "/usr/src/app/mathics-core/mathics/core/list.py", line 103, in evaluate_elements
    new_value = element.evaluate(evaluation)
  File "/usr/src/app/mathics-core/mathics/core/expression.py", line 507, in evaluate
    expr, reevaluate = expr.rewrite_apply_eval_step(evaluation)
  File "/usr/src/app/mathics-core/mathics/core/expression.py", line 1313, in rewrite_apply_eval_step
    result = rule.apply(new, evaluation, fully=False)
  File "/usr/src/app/mathics-core/mathics/core/rules.py", line 106, in apply
    self.pattern.match(yield_match, expression, {}, evaluation, fully=fully)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 467, in match
    self.head.match(yield_head, expression.get_head(), vars, evaluation)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 305, in match_symbol
    yield_func(vars, None)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 457, in yield_head
    self.get_pre_choices(
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 648, in get_pre_choices
    yield_choice(vars)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 435, in yield_choice
    self.match_element(
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 864, in match_element
    self.get_wrappings(
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 681, in get_wrappings
    yield_func(items[0])
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 853, in yield_wrapping
    element.match(
  File "/usr/src/app/mathics-core/mathics/builtin/patterns.py", line 1036, in match
    self.pattern.match(yield_func, expression, new_vars, evaluation)
  File "/usr/src/app/mathics-core/mathics/builtin/patterns.py", line 1262, in match
    yield_func(vars, None)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 834, in match_yield
    self.match_element(
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 864, in match_element
    self.get_wrappings(
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 692, in get_wrappings
    yield_func(sequence)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 853, in yield_wrapping
    element.match(
  File "/usr/src/app/mathics-core/mathics/builtin/patterns.py", line 1742, in match
    yield_func(new_vars, None)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 850, in match_yield
    yield_func(new_vars, items_rest)
  File "/usr/src/app/mathics-core/mathics/core/pattern.py", line 827, in element_yield
    yield_func(
  File "/usr/src/app/mathics-core/mathics/core/rules.py", line 78, in yield_match
    new_expression = self.do_replace(expression, vars, options, evaluation)
  File "/usr/src/app/mathics-core/mathics/core/rules.py", line 267, in do_replace
    return self.function(evaluation=evaluation, options=options, **vars_noctx)
  File "/usr/src/app/mathics-core/mathics/builtin/numbers/algebra.py", line 1672, in eval
    return self.do_apply(expr, evaluation, options)
  File "/usr/src/app/mathics-core/mathics/builtin/numbers/algebra.py", line 1726, in do_apply
    sympy_result = sympy.simplify(sympy_expr, measure=complexity_function)
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/simplify.py", line 725, in simplify
    short = shorter(powsimp(expr, combine='exp', deep=True), powsimp(expr), expr)
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 117, in powsimp
    expr = expr.func(*[recurse(w) for w in expr.args])
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 117, in <listcomp>
    expr = expr.func(*[recurse(w) for w in expr.args])
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 108, in recurse
    return powsimp(arg, _deep, _combine, _force, _measure)
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 117, in powsimp
    expr = expr.func(*[recurse(w) for w in expr.args])
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 117, in <listcomp>
    expr = expr.func(*[recurse(w) for w in expr.args])
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 108, in recurse
    return powsimp(arg, _deep, _combine, _force, _measure)
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 142, in powsimp
    b, e = [recurse(i) for i in [b, e]]
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 142, in <listcomp>
    b, e = [recurse(i) for i in [b, e]]
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 108, in recurse
    return powsimp(arg, _deep, _combine, _force, _measure)
  File "/usr/local/lib/python3.10/dist-packages/sympy/simplify/powsimp.py", line 117, in powsimp
    expr = expr.func(*[recurse(w) for w in expr.args])
  File "/usr/src/app/mathics-core/mathics/core/convert/sympy.py", line 168, in __new__
    return SympyExpression(self.expr)
AttributeError: 'SympyExpression' object has no attribute 'expr'

Expected behavior

No crash, correct simplification.

Your Environment

Docker:

Mathicscript: 7.0.0.dev0, Mathics 7.0.0dev0
on CPython 3.10.6 (main, May 29 2023, 11:10:38) [GCC 11.3.0]

Using:
SymPy 1.12, mpmath 1.3.0, numpy 1.25.0
cython 3.0.0, matplotlib 3.7.2,
Asymptote version 2.78

Additional context

This has something to do with using X[a],Y[a] instead of e.g. xa,xa; the latter does work.

I expected X[a] to be treated as an opaque variable, but perhaps, I misunderstand something about the language.

@HolyBlackCat
Copy link
Author

HolyBlackCat commented Sep 19, 2023

This has something to do with the names X0, Y0. If I use other names, such as XX, YY, it doesn't crash. 🤔

It seems adding any digit to those names causes this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant