Re: puzzle with pattern matching



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.
-- 
wjenkner@inode.at