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.