[edA-qa mort-ora-y <eda-qa@disemia.com>, Thu, 23 Sep 2004 14:28:51 +0200]:
> I want to achieve the following:
>
> Given: (x+y+z)*c
> Simplify Where: a=x+y
> Result: (a+z)*c
subst(a-x, y, (x+y+z)*c) ==> c*(z+a)
Of course this only works when you can solve the "Where" equation for
one of the parameters.
> Ultimately I want to be able to group a lot of terms together in an
> equation (as they are constants which can be precalculated). That is,
> a larger example:
>
> q:(a+b/c+i)/(a+b)-(d-e-f)*i;
> constreplace(q,a,b,c,d,e,f)
> c1 = ...
> c2 = ...
> q = c1 + c2 * i
One way is to walk down the expression, determine for each
subexpression whether it is constant, and generate something of this
kind. Something to start with:
constWalk(expr,[consts]) :=
block([found: [], nfound: 0],
[second(cw(expr)), found]) ;
cw(expr) :=
if atom(expr)
then
if member(expr, consts)
then [true, expr]
else [false, expr]
else
block([foo : maplist(cw, args(expr))],
if apply("and", maplist(first, foo))
then block([sym : concat(const, nfound: nfound + 1)],
found: cons([sym, expr], found),
consts: cons(sym, consts),
[ true, sym ])
else [ false, apply(inpart(expr,0), maplist(second, foo)) ]) ;
constWalk((a+b/c+i)/(a+b)-(d-e-f)*i,a,b,c,d,e,f) ==>
[const2*(i+const1+a)+const5*i,
[[const5,-f-e+d],[const4,-e],[const3,-f],[const2,b+a],[const1,b/c]]]
Of course one should use commutativity and associativity of addition
to turn (i+const1+a) into (i + const6), where const6 = const1+a:
Basically you have to recognize those functions and split their
arguments into groups that are constant and those that are not.
Albert.