Bug report ID:635627 - subst([...] is order-dependent



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
>
>
>
>