Bug report ID:635627 - subst([...] is order-dependent
Subject: Bug report ID:635627 - subst([...] is order-dependent
From: Joseph Cusumano
Date: Wed, 31 Mar 2010 14:10:06 -0400
Hello:
I admit up front to not having the perspective (or skills) of a
developer, so maybe I'm missing something fundamental. However, I do not
understand why this should be considered a bug. I have a fair amount of
code in Maple (which has a similar property to its substitution command)
and now Maxima that /depends /on (or, at the vary least, /assumes/) this
feature property.
I would say at the very least this should be controllable via an
external variable, e.g. "subst_sequence" equals "serial" or "parallel".
Cheers,
Joe
Dieter Kaiser wrote the following on 2:59 PM:
> We have the open bug report ID:635627 - subst([...] is order-dependent.
>
> I have tried a general algorithm which does the substitution in
> parallel. These are the steps I have implemented:
>
> 1. Switch off simplification during the phase of substitution.
> 2. Replace first the left hand side of each equation with a gensym
> and substitute the gensym into the expression.
> 3. Then replace the gensym with the right hand side of the equation.
> 4. Resimplify the new expression.
>
> With the new code we get e.g. for the examples of the bug report:
>
> (%i5) subst ([a=b,b=a], sin(a)+sin(b));
> (%o5) sin(b)+sin(a)
>
> (%i6) subst([a=0,b=0],atan2(a,b));
> atan2: atan2(0,0) is undefined.
> -- an error. To debug this try: debugmode(true);
>
> (%i7) subst(["="="+","["="*"],[x=1,x=2]);
> (%o7) (x+1)*(x+2)
>
> (%i8) subst(["["="*","="="+"],[x=1,x=2]);
> (%o8) (x+1)*(x+2)
>
> (%i9) subst([a=[1,2],b=[3,4]],a+b);
> (%o9) [4,6]
>
> In addition to the function sublis subst can do parallel substitution
> not only for atoms on the left hand side, but for expressions too:
>
> (%i10) subst([x^2=y^2,y^2=x^2],exp(x^2)+sin(y^2));
> (%o10) %e^y^2+sin(x^2)
>
> There is no change for a call of $substitute with three arguments and
> with one equation as a first argument.
>
> There is one big problem. The code of to_poly_solve expects a function
> subst, which does not do the substitution in parallel, but does the
> substitution along the list of equations.
>
> This is a typical list of equations we get in to_poly_solve.
>
> (%i3) ll;
> (%o3) [%g2652 = %i,x = %c2654,%c2654 = 2*%pi*%z2659+%pi/2]
>
> This is what to_poly_solve expects:
>
> (%i4) subst(ll,x);
> (%o4) 2*%pi*%z2659+%pi/2
>
> When I load the modified function $substitute, which does the
> substitution in parallel we get:
>
> (%i5) load("subst.lisp");
> (%o5) "subst.lisp"
>
> (%i6) subst(ll,x);
> (%o6) %c2654
>
> The last substitution for the symbol %c2654 is no longer done with the
> code which does the substitution in parallel.
>
> The testsuite has no problems. The only problem is the code of
> to_poly_solve.
>
> So, the question arises, if the substitution in parallel is desired. If
> we wish to have this feature, the code of to_poly_solve must be modified
> in a way that it does not depend on the current behavior of $substitute
> to do the substitution step by step for the equations in the list.
>
>
> This is the code of the modified routine $substitute:
>
> (defmfun $substitute (old new&optional (expr nil three-arg?))
> (cond (three-arg? (maxima-substitute old new expr))
> (t
> (let ((l old) (z new))
> (cond ((and ($listp l)
> ($listp (cadr l))
> (null (cddr l)))
> ;; A nested list.
> ($substitute (cadr l) z))
> ((and ($listp l)
> (eq (caar (cadr l)) 'mequal)
> (null (cddr l)))
> ;; A list with one equation.
> ($substitute (cadr l) z))
> ((notloreq l) (improper-arg-err l '$substitute))
> ((eq (caar l) 'mequal)
> ;; Do substitution for one equation.
> (maxima-substitute (caddr l) (cadr l) z))
> (t
> ;; We have a list of equations.
> ;; We do parallel substitution.
> (let (gensymbol genlist eqn ($simp nil))
> ;; At first substitute a gensym for the expressions
> ;; of the left hand side of the equations.
> (do ((l (cdr l) (cdr l)))
> ((null l) z)
> (setq eqn (car l))
> (when (not (eq 'mequal (caar eqn)))
> (improper-arg-err old '$substitute))
> (setq gensymbol (gensym))
> ;; Store the gensym and the new expression
> ;; into a list.
> (push (cons gensymbol (caddr eqn)) genlist)
> ;; Substitute a gensym for the old expression.
> (setq z (maxima-substitute gensymbol (cadr eqn)
> z)))
> ;; Substitute the new epressions for the gensyms.
> (do ((l genlist (cdr l)))
> ((null l)
> ;; Resimplify the new expression and
> ;; return the result.
> (let (($simp t)) (resimplify z)))
> (setq z (maxima-substitute (cdar l) (caar l)
> z))))))))))
>
> Dieter Kaiser
>
>
>
>