When I said "rewrite rules" I meant strategies.
On Tue, Feb 5, 2013 at 7:01 PM, Matthew Rocklin <[email protected]> wrote: > Rewrite rules don't respect the canonicalization that happens at > expression construction time. If this is important to you then inject the > `rebuild` rule which effectively does type(x)(*map(rebuild, x.args)) > > Here is my solution to your problem > > In [1]: from sympy.rules import chain, rebuild, debug, typed > In [2]: from sympy.rules.traverse import bottom_up > In [3]: e = y*(x + 3) - y > In [4]: fn = bottom_up(chain(rebuild, typed({Add: lambda x:S.One}))) # > without debug > In [4]: fn = bottom_up(chain(*map(debug, (rebuild, typed({Add: lambda > x:S.One}))))) > In [5]: fn(e) > Rule: switch_rl > In: x + 3 > Out: 1 > > Rule: rebuild > In: y > Out: y > > Rule: rebuild > In: -y + y > Out: 0 > > This function first rebuilds/canonicalizes the expr, then turns the node > into S.One if the type is Add. It applies this function throught the tree, > starting at the leaves and working upwards. I've injected a debug strategy > so that you see whenever one of the bottom level rules activates. > > The first rebuild seems to be y*1 -> y. SymPy printing doesn't respect 1s > in Muls > > In [36]: str(Mul(y, 1, evaluate=False)) > Out[36]: y > > > > On Tue, Feb 5, 2013 at 6:44 PM, smichr <[email protected]> wrote: > >> I did the following bottom_up traversal and got an unexpected result: >> >> >>> e >> y*(x + 3) - y >> >>> bottom_up(condition(lambda x:x.is_Add, lambda x:S.One))(e) >> 1 >> >> I confirmed with the debugger that Add(-y, y) is created but apparently >> in an unevaluated manner. If it were evaluated, that should have collapsed >> to 0 and then there would be no Add to be identified as 1. If I try to slip >> a recalculation of the x I get an error: >> >> >>> cond = lambda x:Add(*Add.make_args(x)).is_Add >> >>> bottom_up(condition(cond, lambda x:S.One))(e) >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> File "sympy\rules\traverse.py", line 19, in bottom_up_rl >> return rule(new(type(expr), *map(bottom_up_rl, expr.args))) >> File "sympy\rules\strat_pure.py", line 27, in conditioned_rl >> if cond(expr): >> File "<stdin>", line 1, in <lambda> >> File "sympy\core\cache.py", line 92, in wrapper >> func_cache_it_cache[k] = r = func(*args, **kw_args) >> File "sympy\core\operations.py", line 38, in __new__ >> c_part, nc_part, order_symbols = cls.flatten(args) >> File "sympy\core\add.py", line 179, in flatten >> noncommutative = noncommutative or not s.is_commutative >> AttributeError: is_commutative >> >> /c >> >> -- >> You received this message because you are subscribed to the Google Groups >> "sympy" group. >> To unsubscribe from this group and stop receiving emails from it, send an >> email to [email protected]. >> To post to this group, send email to [email protected]. >> Visit this group at http://groups.google.com/group/sympy?hl=en. >> For more options, visit https://groups.google.com/groups/opt_out. >> >> >> > > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sympy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
