Ordering Products
Diez B.Roggisch
deets at web.de
Mon Jul 18 04:07:03 EDT 2005
> I have to admit that I don't understand what you mean with the
> 'constant parts' of an expression?
>From what I percieved of your example it seemed to me that you wanted to
evaluate the constants like 7*9 first, so that an expression like
a * 7 * 9 * b
with variables a,b is evaluated like this:
a * 63 * b
So my suggestion was simply to make the *-operator more precedent when
in between two constants. What I mean with constants here are of course
integer/float literals. The concept of a differing operator precedence
can be extended to arbitray elements when their types are known - which
should be possible when variable values are known at parsing
time.
> The associativity of __mul__ is trivially fullfilled for the dummy
> class M if an additional __eq__ method is defined by comparing factor
> lists because those lists are always flat:
I don't care about that, as my approach deosn't use python's built-in parser
- it can't, as that wouldn't allow to re-define operator precedence.
What you do is to
simply collect the factors as list. But what you need (IMHO) is a parsing
tree (AST) that reflects your desired behaviour by introducing a different
precedence thus that the expression
a * 7 *9 * b
is not evaluated like
((a*7)*9)*b
(which is a tree, and the standard way of evaluationg due to built-in parsers
precedence rules) but as
a*(7*9)*b
which is also a tree.
> The sorting ( or better 'grouping' which can be represented by sorting
> in a special way ) of factors in question is really a matter of
> (non-)commutativity. For more advanced expressions also group
> properties are important:
No, IMHO associativity is the important thing here - if
(a * 7) * 9
yields a different solution than
a *(7*9)
your reordering can't be done - in the same way as re-arranging
factors a*b to b*a only works if the commute - or, to put in in
algebraic terms, the group is abelian.
> If a,b are in a center of a group G ( i.e. they commute with any
> element of G ) and G supplies an __add__ ( besides a __mul__ and is
> therefore a ring ) also a+b is in the center of G and (a+b)*c = c*(a+b)
> holds for any c in G.
>
> It would be nice ( and much more efficient ) not to force expansion of
> the product assuming distributivity of __add__ and __mul__ and
> factorization after the transposition of the single factors but
> recognizing immediately that a+b is in the center of G because the
> center is a subgroup of G.
Well, you don't need to expand that product - the subexpression a+b is
evaluated first. If you can sort of "cache" that evaluation's result because
the expressions involved are of a constant nature, you can do so.
The rason (a+b) is evaluated first (at least in the standard python parser,
and in my proposed special parser) is that the parentheses ensure that.
To sum things up a little: I propose not using the python built-in parser
which results in you having to overload operators and lose control
of precedence, but by introducing your own parser, that can do the
trick of re-arranging the operators based on not only the "usual" precedence
(* binds stronger than +), but by a type-based parser that can even change
precedence of the same operator between different argument types is's
applied to. That might sound complicated, but I think the grammar
I gave in my last post shows the concept pretty well.
regards,
Diez
More information about the Python-list
mailing list