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