hide local variables from substitution for a user defined object



On 2013-11-28, Litvinov Sergey <slitvinov at gmail.com> wrote:

> What is the best way to get this?
>
> (%i1) my_subst(k, i, i*my_sum(i, [i]));
> (%o1)                  k my_sum(i, [i]))
>
> (%i1) my_subst(k, j,  my_sum(j*i, [i]));
> (%o1)                    my_sum(k*i, [i]))
>
> Here [i] is a list of variables local to `my_sum' and they should not
> be substituted.

Well, I dunno if this is the best way, but it is a way.
You can try 'blex' (lexical block) which is implemented by the
attached code. It is pretty simple-minded but maybe useful.

(%i2) load ("./blex.lisp") $
(%i3) e1 : blex ([i], my_sum (i, [i]));
(%o3) my_sum(i,[i])
(%i4) subst (i = k, i * e1);
(%o4) k*my_sum(i,[i])
(%i5) e2 : blex ([i], my_sum (j*i, [i]));
(%o5) my_sum(j*i,[i])
(%i6) subst (j = k, e2);
(%o6) my_sum(k*i,[i])

For what it's worth, and hope this helps.

Robert Dodier

PS.
;; blex.lisp -- lexical block for Maxima
;; copyright 2012 by Robert Dodier
;; I release this work under terms of the GNU GPL
;;
;; examples:
;; blex ([n:100], f(x) := n : n + x, g() := display(n));
;; blex ([f], f(x) := 2*x);
;; blex ([a], h(x) := a[x] : 1, i() := arrayinfo(a));

(defmspec $blex (x)
 (let*
   ((args (cdr x))
    (vars+inits (cdr (car args)))
    (vars (mapcar #'(lambda (e) (if (symbolp e) e (second e))) vars+inits))
    (inits (remove-if #'symbolp vars+inits))
    (exprs (cdr args))
    (gensym-vars (mapcar #'(lambda (s) (let ((s1 (gensym))) (setf (get s1 'reversealias) (or (get s 'reversealias) s)) s1)) vars))
    (subst-eqns (mapcar #'(lambda (x y) `((mequal) ,x ,y)) vars gensym-vars))
    (gensym-mprog ($psubstitute `((mlist) ,@ subst-eqns) `((mprog) ((mprogn) ,@ inits) ,@ exprs))))
   (meval gensym-mprog)))