I think that the binding of names, pattern variables,
rule-names, ... during pattern definition, as well
as pattern execution, is complicated: there are, in
some cases, no clearly defined best solutions, and the
temptation is to allow whatever happens naturally, and
hope it will agree with the users' expectations.
It may be that the right thing to do is to use eval
rather than meval to find the argument to IS below.
The commercial macsyma does this problem correctly,
and by tracing, looks like my suggestion. This of
course may or may not be a recommendation :)
I am suspicious of the translation-to-lisp code, and
would not ordinarily use the translated code as a guide
to what to do. I'm not sure that is what is being
proposed though.
RJF
Wolfgang Jenkner wrote:
> Richard Fateman <fateman@cs.berkeley.edu> writes:
>
>
>>(defun getdec (p e)
>>
> [...]
>
>> `(is (list '(,x) ,@(mapcar #'(lambda (r) `(list '(mquote) ,r)) z)))
>>
> [...]
>
> The patch delays the computation of the argument of IS and hence of
> the form which is eventually passed to MEVAL until the function
> defined by DEFRULE is actually run. This has the inconvenience of
> breaking the translation of (IS ...) by PATCH-UP-MEVAL-IN-FSET (see
> the NOTES below). So I tried to find another solution...
>
> First, here is a short specimen of the sort of bug reported by Zheng
> Yin. Assume foo.mac contains
>
> always(x):=true;
> matchdeclare(a,always);
> defrule(mymatch,a[0],a);
> x:y[0];
>
> Then...
>
> (C1) load("foo.mac");
> (D1) foo.mac
> (C2) :lisp(trace is meval)
> ;; Tracing function IS.
> ;; Tracing function MEVAL.
> (IS MEVAL)
> (C2) mymatch(x);
>
> 1. Trace: (MEVAL '((|$mymatch|) |$x|))
> 2. Trace: (MEVAL '|$x|)
> 2. Trace: MEVAL ==> ((|$y| SIMP ARRAY (4 "foo.mac" SRC)) 0)
> 2. Trace: (IS '((|$always|) (KAR (KAR |tr-gensym~0|))))
> 3. Trace: (MEVAL '((|$always|) (KAR (KAR |tr-gensym~0|))))
> 4. Trace: (MEVAL '(KAR (KAR |tr-gensym~0|)))
> 5. Trace: (MEVAL '(KAR |tr-gensym~0|))
> 6. Trace: (MEVAL '|tr-gensym~0|)
> 6. Trace: MEVAL ==> ((|$y| SIMP ARRAY (4 "foo.mac" SRC)) 0)
> *** - GET: 4 is not a symbol
> 1. Break [1]>
>
> Now, the problem is that MEVAL is passed an argument (in 4. Trace)
> which would evaluate to a valid Macsyma expression (viz. |$y|) but
> some intermediate form (5. Trace) does not and so MEVAL (actually
> SIMPLIFYA) is dazed and confused.
>
> At least in this case, such an intermediate form can be avoided by
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cut ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> *** matcom.lisp.orig Mon Sep 9 23:17:55 2002
> --- matcom.lisp Mon Sep 9 23:17:16 2002
> ***************
> *** 617,622 ****
> (LIST 'KDR (CADR REFLIST))))
> (COMPILEMATCH (CADR REFLIST) (CADDR P)))
> ! (T (COMPILEATOM (LIST 'KAR
> ! (LIST 'KAR E))
> (CAAR P))
> (EMIT (LIST 'SETQ
> --- 617,622 ----
> (LIST 'KDR (CADR REFLIST))))
> (COMPILEMATCH (CADR REFLIST) (CADDR P)))
> ! (T (COMPILEATOM
> ! `(kaar ,e)
> (CAAR P))
> (EMIT (LIST 'SETQ
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ cut ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> where
>
> (defmfun kaar (x) (kar (kar x)))
>
> Actually, I think it would be better to use ((KAAR) E) instead of
> (KAAR E), but in some cases the form will be evaluated instead of
> being passed to MEVAL...
>
> Is it too naive to hope that everything in matcom.lisp which is passed
> to MEVAL can be handled like this if necessary?
>
> Wolfgang
>
> NOTES: I haven't mentioned that PATCH-UP-MEVAL-IN-FSET is currently
> broken anyway (but only in a trivial way). You find a patched version
> at
>
> http://members.inode.at/wjenkner/maxima/trans4.lisp
>
> If anybody actually wants to try out these patches (before some of
> them may find their way into post-5.9.0 CVS) there are also patched
> versions of trigonometry/spangl.mac and simplification/ineq.mac
>
> http://members.inode.at/wjenkner/maxima/spangl.mac
> http://members.inode.at/wjenkner/maxima/ineq.mac
>
> which should work both in interpreted and translated form.
>