;
;************************************************************************
;
;	VPS2 -- Interpreter for OPS5
;
;
;
; This Common Lisp version of OPS5 is in the public domain.  It is based
; in part on based on a Franz Lisp implementation done by Charles L. Forgy
; at Carnegie-Mellon University, which was placed in the public domain by
; the author in accordance with CMU policies.  This version has been
; modified by George Wood, Dario Giuse, Skef Wholey, Michael Parzen,
; and Dan Kuokka.
;
; This code is made available is, and without warranty of any kind by the
; authors or by Carnegie-Mellon University.
;

;;;; This file contains the functions that match working memory
;;;; elements against productions LHS.

(in-package "OPS")



;;; External global variables

(defvar *current-token*)


;;; Internal global variables

(defvar *alpha-data-part*)
(defvar *alpha-flag-part*)
(defvar *flag-part*)
(defvar *data-part*)
(defvar *sendtocall*)
(defvar *side*)
(proclaim '(special *c1* *c2* *c3* *c4* *c5* *c6* *c7* *c8* *c9*
	   *c10* *c11* *c12* *c13* *c14* *c15* *c16* *c17* *c18* *c19*
	   *c20* *c21* *c22* *c23* *c24* *c25* *c26* *c27* *c28* *c29*
	   *c30* *c31* *c32* *c33* *c34* *c35* *c36* *c37* *c38* *c39*
	   *c40* *c41* *c42* *c43* *c44* *c45* *c46* *c47* *c48* *c49*
	   *c50* *c51* *c52* *c53* *c54* *c55* *c56* *c57* *c58* *c59*
	   *c60* *c61* *c62* *c63* *c64* *c65* *c66* *c67* *c68* *c69*
	   *c70* *c71* *c72* *c73* *c74* *c75* *c76* *c77* *c78* *c79*
	   *c80* *c81* *c82* *c83* *c84* *c85* *c86* *c87* *c88* *c89*
	   *c90* *c91* *c92* *c93* *c94* *c95* *c96* *c97* *c98* *c99*
	   *c100* *c101* *c102* *c103* *c104* *c105* *c106* *c107* *c108* *c109*
	   *c110* *c111* *c112* *c113* *c114* *c115* *c116* *c117* *c118* *c119*
	   *c120* *c121* *c122* *c123* *c124* *c125* *c126* *c127*))



;;; Network interpreter


(defun match-init ()
  (setq *current-token* 0.))


(defun match (flag wme)
  (sendto flag (list wme) 'left (list *first-node*)))

; note that eval-nodelist is not set up to handle building
; productions.  would have to add something like ops4's build-flag

(defun eval-nodelist (nl)
  (prog nil
    top  (and (not nl) (return nil))
    (setq *sendtocall* nil)
    (setq *last-node* (car nl))
    (apply (caar nl) (cdar nl))
    (setq nl (cdr nl))
    (go top))) 

(defun sendto (flag data side nl)
  (prog nil
    top  (and (not nl) (return nil))
    (setq *side* side)
    (setq *flag-part* flag)
    (setq *data-part* data)
    (setq *sendtocall* t)
    (setq *last-node* (car nl))
    (apply (caar nl) (cdar nl))
    (setq nl (cdr nl))
    (go top))) 

; &bus sets up the registers for the one-input nodes.  note that this
(defun &bus (outs)
  (prog (dp)
    (setq *alpha-flag-part* *flag-part*)
    (setq *alpha-data-part* *data-part*)
    (setq dp (car *data-part*))
    (setq *c1* (car dp))
    (setq dp (cdr dp))
    (setq *c2* (car dp))
    (setq dp (cdr dp))
    (setq *c3* (car dp))
    (setq dp (cdr dp))
    (setq *c4* (car dp))
    (setq dp (cdr dp))
    (setq *c5* (car dp))
    (setq dp (cdr dp))
    (setq *c6* (car dp))
    (setq dp (cdr dp))
    (setq *c7* (car dp))
    (setq dp (cdr dp))
    (setq *c8* (car dp))
    (setq dp (cdr dp))
    (setq *c9* (car dp))
    (setq dp (cdr dp))
    (setq *c10* (car dp))
    (setq dp (cdr dp))
    (setq *c11* (car dp))
    (setq dp (cdr dp))
    (setq *c12* (car dp))
    (setq dp (cdr dp))
    (setq *c13* (car dp))
    (setq dp (cdr dp))
    (setq *c14* (car dp))
    (setq dp (cdr dp))
    (setq *c15* (car dp))
    (setq dp (cdr dp))
    (setq *c16* (car dp))
    (setq dp (cdr dp))
    (setq *c17* (car dp))
    (setq dp (cdr dp))
    (setq *c18* (car dp))
    (setq dp (cdr dp))
    (setq *c19* (car dp))
    (setq dp (cdr dp))
    (setq *c20* (car dp))
    (setq dp (cdr dp))
    (setq *c21* (car dp))
    (setq dp (cdr dp))
    (setq *c22* (car dp))
    (setq dp (cdr dp))
    (setq *c23* (car dp))
    (setq dp (cdr dp))
    (setq *c24* (car dp))
    (setq dp (cdr dp))
    (setq *c25* (car dp))
    (setq dp (cdr dp))
    (setq *c26* (car dp))
    (setq dp (cdr dp))
    (setq *c27* (car dp))
    (setq dp (cdr dp))
    (setq *c28* (car dp))
    (setq dp (cdr dp))
    (setq *c29* (car dp))
    (setq dp (cdr dp))
    (setq *c30* (car dp))
    (setq dp (cdr dp))
    (setq *c31* (car dp))
    (setq dp (cdr dp))
    (setq *c32* (car dp))
    (setq dp (cdr dp))
    (setq *c33* (car dp))
    (setq dp (cdr dp))
    (setq *c34* (car dp))
    (setq dp (cdr dp))
    (setq *c35* (car dp))
    (setq dp (cdr dp))
    (setq *c36* (car dp))
    (setq dp (cdr dp))
    (setq *c37* (car dp))
    (setq dp (cdr dp))
    (setq *c38* (car dp))
    (setq dp (cdr dp))
    (setq *c39* (car dp))
    (setq dp (cdr dp))
    (setq *c40* (car dp))
    (setq dp (cdr dp))
    (setq *c41* (car dp))
    (setq dp (cdr dp))
    (setq *c42* (car dp))
    (setq dp (cdr dp))
    (setq *c43* (car dp))
    (setq dp (cdr dp))
    (setq *c44* (car dp))
    (setq dp (cdr dp))
    (setq *c45* (car dp))
    (setq dp (cdr dp))
    (setq *c46* (car dp))
    (setq dp (cdr dp))
    (setq *c47* (car dp))
    (setq dp (cdr dp))
    (setq *c48* (car dp))
    (setq dp (cdr dp))
    (setq *c49* (car dp))
    (setq dp (cdr dp))
    (setq *c50* (car dp))
    (setq dp (cdr dp))
    (setq *c51* (car dp))
    (setq dp (cdr dp))
    (setq *c52* (car dp))
    (setq dp (cdr dp))
    (setq *c53* (car dp))
    (setq dp (cdr dp))
    (setq *c54* (car dp))
    (setq dp (cdr dp))
    (setq *c55* (car dp))
    (setq dp (cdr dp))
    (setq *c56* (car dp))
    (setq dp (cdr dp))
    (setq *c57* (car dp))
    (setq dp (cdr dp))
    (setq *c58* (car dp))
    (setq dp (cdr dp))
    (setq *c59* (car dp))
    (setq dp (cdr dp))
    (setq *c60* (car dp))
    (setq dp (cdr dp))
    (setq *c61* (car dp))
    (setq dp (cdr dp))
    (setq *c62* (car dp))
    (setq dp (cdr dp))
    (setq *c63* (car dp))
    (setq dp (cdr dp))
    (setq *c64* (car dp))
    ;-------- added for 127 atr
    (setq dp (cdr dp))
    (setq *c65* (car dp))
    (setq dp (cdr dp))
    (setq *c66* (car dp))
    (setq dp (cdr dp))
    (setq *c67* (car dp))
    (setq dp (cdr dp))
    (setq *c68* (car dp))
    (setq dp (cdr dp))
    (setq *c69*(car dp))
    (setq dp (cdr dp))
    (setq *c70* (car dp))
    (setq dp (cdr dp))
    (setq *c71* (car dp))
    (setq dp (cdr dp))
    (setq *c72* (car dp))
    (setq dp (cdr dp))
    (setq *c73* (car dp))
    (setq dp (cdr dp))
    (setq *c74* (car dp))
    (setq dp (cdr dp))
    (setq *c75* (car dp))
    (setq dp (cdr dp))
    (setq *c76* (car dp))
    (setq dp (cdr dp))
    (setq *c77* (car dp))
    (setq dp (cdr dp))
    (setq *c78* (car dp))
    (setq dp (cdr dp))
    (setq *c79*(car dp))
    (setq dp (cdr dp))
    (setq *c80* (car dp))
    (setq dp (cdr dp))
    (setq *c81* (car dp))
    (setq dp (cdr dp))
    (setq *c82* (car dp))
    (setq dp (cdr dp))
    (setq *c83* (car dp))
    (setq dp (cdr dp))
    (setq *c84* (car dp))
    (setq dp (cdr dp))
    (setq *c85* (car dp))
    (setq dp (cdr dp))
    (setq *c86* (car dp))
    (setq dp (cdr dp))
    (setq *c87* (car dp))
    (setq dp (cdr dp))
    (setq *c88* (car dp))
    (setq dp (cdr dp))
    (setq *c89*(car dp))
    (setq dp (cdr dp))
    (setq *c90* (car dp))
    (setq dp (cdr dp))
    (setq *c91* (car dp))
    (setq dp (cdr dp))
    (setq *c92* (car dp))
    (setq dp (cdr dp))
    (setq *c93* (car dp))
    (setq dp (cdr dp))
    (setq *c94* (car dp))
    (setq dp (cdr dp))
    (setq *c95* (car dp))
    (setq dp (cdr dp))
    (setq *c96* (car dp))
    (setq dp (cdr dp))
    (setq *c97* (car dp))
    (setq dp (cdr dp))
    (setq *c98* (car dp))
    (setq dp (cdr dp))
    (setq *c99*(car dp))
    (setq dp (cdr dp))
    (setq *c100* (car dp))
    (setq dp (cdr dp))
    (setq *c101* (car dp))
    (setq dp (cdr dp))
    (setq *c102* (car dp))
    (setq dp (cdr dp))
    (setq *c103* (car dp))
    (setq dp (cdr dp))
    (setq *c104* (car dp))
    (setq dp (cdr dp))
    (setq *c105* (car dp))
    (setq dp (cdr dp))
    (setq *c106* (car dp))
    (setq dp (cdr dp))
    (setq *c107* (car dp))
    (setq dp (cdr dp))
    (setq *c108* (car dp))
    (setq dp (cdr dp))
    (setq *c109*(car dp))
    (setq dp (cdr dp))
    (setq *c110* (car dp))
    (setq dp (cdr dp))
    (setq *c111* (car dp))
    (setq dp (cdr dp))
    (setq *c112* (car dp))
    (setq dp (cdr dp))
    (setq *c113* (car dp))
    (setq dp (cdr dp))
    (setq *c114* (car dp))
    (setq dp (cdr dp))
    (setq *c115* (car dp))
    (setq dp (cdr dp))
    (setq *c116* (car dp))
    (setq dp (cdr dp))
    (setq *c117* (car dp))
    (setq dp (cdr dp))
    (setq *c118* (car dp))
    (setq dp (cdr dp))
    (setq *c119*(car dp))
    (setq dp (cdr dp))
    (setq *c120* (car dp))
    (setq dp (cdr dp))
    (setq *c121* (car dp))
    (setq dp (cdr dp))
    (setq *c122* (car dp))
    (setq dp (cdr dp))
    (setq *c123* (car dp))
    (setq dp (cdr dp))
    (setq *c124* (car dp))
    (setq dp (cdr dp))
    (setq *c125* (car dp))
    (setq dp (cdr dp))
    (setq *c126* (car dp))
    (setq dp (cdr dp))
    (setq *c127* (car dp))
    ;(setq dp (cdr dp))
    ;(setq *c128* (car dp))
    ;--------
    (eval-nodelist outs))) 

(defun &any (outs register const-list)
  (prog (z c)
    (setq z (fast-symeval register))
    (cond ((numberp z) (go number)))
    symbol (cond ((null const-list) (return nil))
		 ((eq (car const-list) z) (go ok))
		 (t (setq const-list (cdr const-list)) (go symbol)))
    number (cond ((null const-list) (return nil))
		 ((and (numberp (setq c (car const-list)))
		       (=alg c z))
		  (go ok))
		 (t (setq const-list (cdr const-list)) (go number)))
    ok   (eval-nodelist outs))) 

(defun teqa (outs register constant)
  (and (eq (fast-symeval register) constant) (eval-nodelist outs))) 

(defun tnea (outs register constant)
  (and (not (eq (fast-symeval register) constant)) (eval-nodelist outs))) 

(defun txxa (outs register constant)
  (declare (ignore constant))
  (and (symbolp (fast-symeval register)) (eval-nodelist outs))) 

(defun teqn (outs register constant)
  (prog (z)
    (setq z (fast-symeval register))
    (and (numberp z)
	 (=alg z constant)
	 (eval-nodelist outs)))) 

(defun tnen (outs register constant)
  (prog (z)
    (setq z (fast-symeval register))
    (and (or (not (numberp z))
	     (not (=alg z constant)))
	 (eval-nodelist outs)))) 

(defun txxn (outs register constant)
  (declare (ignore constant))
  (prog (z)
    (setq z (fast-symeval register))
    (and (numberp z) (eval-nodelist outs)))) 

(defun tltn (outs register constant)
  (prog (z)
    (setq z (fast-symeval register))
    (and (numberp z)
	 (> constant z)
	 (eval-nodelist outs)))) 

(defun tgtn (outs register constant)
  (prog (z)
    (setq z (fast-symeval register))
    (and (numberp z)
	 (> z constant)
	 (eval-nodelist outs)))) 

(defun tgen (outs register constant)
  (prog (z)
    (setq z (fast-symeval register))
    (and (numberp z)
	 (not (> constant z))
	 (eval-nodelist outs)))) 

(defun tlen (outs register constant)
  (prog (z)
    (setq z (fast-symeval register))
    (and (numberp z)
	 (not (> z constant))
	 (eval-nodelist outs)))) 

(defun teqs (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (cond ((eq a b) (eval-nodelist outs))
	  ((and (numberp a)
		(numberp b)
		(=alg a b))
	   (eval-nodelist outs))))) 

(defun tnes (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (cond ((eq a b) (return nil))
	  ((and (numberp a)
		(numberp b)
		(=alg a b))
	   (return nil))
	  (t (eval-nodelist outs))))) 

(defun txxs (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (cond ((and (numberp a) (numberp b)) (eval-nodelist outs))
	  ((and (not (numberp a)) (not (numberp b)))
	   (eval-nodelist outs))))) 

(defun tlts (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (and (numberp a)
	 (numberp b)
	 (> b a)
	 (eval-nodelist outs)))) 

(defun tgts (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (and (numberp a)
	 (numberp b)
	 (> a b)
	 (eval-nodelist outs)))) 

(defun tges (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (and (numberp a)
	 (numberp b)
	 (not (> b a))
	 (eval-nodelist outs)))) 

(defun tles (outs vara varb)
  (prog (a b)
    (setq a (fast-symeval vara))
    (setq b (fast-symeval varb))
    (and (numberp a)
	 (numberp b)
	 (not (> a b))
	 (eval-nodelist outs)))) 

(defun &two (left-outs right-outs)
  (prog (fp dp)
    (cond (*sendtocall*
	   (setq fp *flag-part*)
	   (setq dp *data-part*))
	  (t
	   (setq fp *alpha-flag-part*)
	   (setq dp *alpha-data-part*)))
    (sendto fp dp 'left left-outs)
    (sendto fp dp 'right right-outs))) 

(defun &mem (left-outs right-outs memory-list)
  (prog (fp dp)
    (cond (*sendtocall*
	   (setq fp *flag-part*)
	   (setq dp *data-part*))
	  (t
	   (setq fp *alpha-flag-part*)
	   (setq dp *alpha-data-part*)))
    (sendto fp dp 'left left-outs)
    (add-token memory-list fp dp nil)
    (sendto fp dp 'right right-outs))) 

(defun &and (outs lpred rpred tests)
  (prog (mem)
    (cond ((eq *side* 'right) (setq mem (memory-part lpred)))
	  (t (setq mem (memory-part rpred))))
    (cond ((not mem) (return nil))
	  ((eq *side* 'right) (and-right outs mem tests))
	  (t (and-left outs mem tests))))) 

(defun and-left (outs mem tests)
  (prog (fp dp memdp tlist tst lind rind res)
    (setq fp *flag-part*)
    (setq dp *data-part*)
    fail (and (null mem) (return nil))
    (setq memdp (car mem))
    (setq mem (cdr mem))
    (setq tlist tests)
    tloop (and (null tlist) (go succ))
    (setq tst (car tlist))
    (setq tlist (cdr tlist))
    (setq lind (car tlist))
    (setq tlist (cdr tlist))
    (setq rind (car tlist))
    (setq tlist (cdr tlist))
    ;###        (comment the next line differs in and-left & -right)
    (setq res (funcall tst (gelm memdp rind) (gelm dp lind)))
    (cond (res (go tloop))
	  (t (go fail)))
    succ 
    ;###	(comment the next line differs in and-left & -right)
    (sendto fp (cons (car memdp) dp) 'left outs)
    (go fail))) 

(defun and-right (outs mem tests)
  (prog (fp dp memdp tlist tst lind rind res)
    (setq fp *flag-part*)
    (setq dp *data-part*)
    fail (and (null mem) (return nil))
    (setq memdp (car mem))
    (setq mem (cdr mem))
    (setq tlist tests)
    tloop (and (null tlist) (go succ))
    (setq tst (car tlist))
    (setq tlist (cdr tlist))
    (setq lind (car tlist))
    (setq tlist (cdr tlist))
    (setq rind (car tlist))
    (setq tlist (cdr tlist))
    ;###        (comment the next line differs in and-left & -right)
    (setq res (funcall tst (gelm dp rind) (gelm memdp lind)))
    (cond (res (go tloop))
	  (t (go fail)))
    succ 
    ;###        (comment the next line differs in and-left & -right)
    (sendto fp (cons (car dp) memdp) 'right outs)
    (go fail))) 


(defun teqb (new eqvar)
  (cond ((eq new eqvar) t)
	((not (numberp new)) nil)
	((not (numberp eqvar)) nil)
	((=alg new eqvar) t)
	(t nil))) 

(defun tneb (new eqvar)
  (cond ((eq new eqvar) nil)
	((not (numberp new)) t)
	((not (numberp eqvar)) t)
	((=alg new eqvar) nil)
	(t t))) 

(defun tltb (new eqvar)
  (cond ((not (numberp new)) nil)
	((not (numberp eqvar)) nil)
	((> eqvar new) t)
	(t nil))) 

(defun tgtb (new eqvar)
  (cond ((not (numberp new)) nil)
	((not (numberp eqvar)) nil)
	((> new eqvar) t)
	(t nil))) 

(defun tgeb (new eqvar)
  (cond ((not (numberp new)) nil)
	((not (numberp eqvar)) nil)
	((not (> eqvar new)) t)
	(t nil))) 

(defun tleb (new eqvar)
  (cond ((not (numberp new)) nil)
	((not (numberp eqvar)) nil)
	((not (> new eqvar)) t)
	(t nil))) 

(defun txxb (new eqvar)
  (cond ((numberp new)
	 (cond ((numberp eqvar) t)
	       (t nil)))
	(t
	 (cond ((numberp eqvar) nil)
	       (t t))))) 


(defun &p (rating name var-dope ce-var-dope rhs)
  (declare (ignore var-dope ce-var-dope rhs))
  (prog (fp dp)
    (cond (*sendtocall*
	   (setq fp *flag-part*)
	   (setq dp *data-part*))
	  (t
	   (setq fp *alpha-flag-part*)
	   (setq dp *alpha-data-part*)))
    (and (member fp '(nil old)) (removecs name dp))
    (and fp (insertcs name dp rating)))) 

(defun &old (a b c d e)
  (declare (ignore a b c d e))
  nil) 

(defun &not (outs lmem rpred tests)
  (cond ((and (eq *side* 'right) (eq *flag-part* 'old)) nil)
	((eq *side* 'right) (not-right outs (car lmem) tests))
	(t (not-left outs (memory-part rpred) tests lmem)))) 

(defun not-left (outs mem tests own-mem)
  (prog (fp dp memdp tlist tst lind rind res c)
    (setq fp *flag-part*)
    (setq dp *data-part*)
    (setq c 0.)
    fail (and (null mem) (go fin))
    (setq memdp (car mem))
    (setq mem (cdr mem))
    (setq tlist tests)
    tloop (and (null tlist) (setq c (1+ c)) (go fail))
    (setq tst (car tlist))
    (setq tlist (cdr tlist))
    (setq lind (car tlist))
    (setq tlist (cdr tlist))
    (setq rind (car tlist))
    (setq tlist (cdr tlist))
    ;###        (comment the next line differs in not-left & -right)
    (setq res (funcall tst (gelm memdp rind) (gelm dp lind)))
    (cond (res (go tloop))
	  (t (go fail)))
    fin  (add-token own-mem fp dp c)
    (and (== c 0.) (sendto fp dp 'left outs)))) 

(defun not-right (outs mem tests)
  (prog (fp dp memdp tlist tst lind rind res newfp inc newc)
    (setq fp *flag-part*)
    (setq dp *data-part*)
    (cond ((not fp) (setq inc -1.) (setq newfp 'new))
	  ((eq fp 'new) (setq inc 1.) (setq newfp nil))
	  (t (return nil)))
    fail (and (null mem) (return nil))
    (setq memdp (car mem))
    (setq newc (cadr mem))
    (setq tlist tests)
    tloop (and (null tlist) (go succ))
    (setq tst (car tlist))
    (setq tlist (cdr tlist))
    (setq lind (car tlist))
    (setq tlist (cdr tlist))
    (setq rind (car tlist))
    (setq tlist (cdr tlist))
    ;###        (comment the next line differs in not-left & -right)
    (setq res (funcall tst (gelm dp rind) (gelm memdp lind)))
    (cond (res (go tloop))
	  (t (setq mem (cddr mem)) (go fail)))
    succ (setq newc (+ inc newc))		;"plus" changed to "+" by gdw
    (rplaca (cdr mem) newc)
    (cond ((or (and (== inc -1.) (== newc 0.))
	       (and (== inc 1.) (== newc 1.)))
	   (sendto newfp memdp 'right outs)))
    (setq mem (cddr mem))
    (go fail))) 


;;; Node memories


(defun add-token (memlis flag data-part num)
  (prog (was-present)
    (cond ((eq flag 'new)
	   (setq was-present nil)
	   (real-add-token memlis data-part num))
	  ((not flag) 
	   (setq was-present (remove-old memlis data-part num)))
	  ((eq flag 'old) (setq was-present t)))
    (return was-present))) 

(defun real-add-token (lis data-part num)
  (setq *current-token* (1+ *current-token*))
  (cond (num (rplaca lis (cons num (car lis)))))
  (rplaca lis (cons data-part (car lis)))) 

(defun remove-old (lis data num)
  (cond (num (remove-old-num lis data))
	(t (remove-old-no-num lis data)))) 

(defun remove-old-num (lis data)
  (prog (m next last)
    (setq m (car lis))
    (cond ((atom m) (return nil))
	  ((top-levels-eq data (car m))
	   (setq *current-token* (1- *current-token*))
	   (rplaca lis (cddr m))
	   (return (car m))))
    (setq next m)
    loop (setq last next)
    (setq next (cddr next))
    (cond ((atom next) (return nil))
	  ((top-levels-eq data (car next))
	   (rplacd (cdr last) (cddr next))
	   (setq *current-token* (1- *current-token*))
	   (return (car next)))
	  (t (go loop))))) 

(defun remove-old-no-num (lis data)
  (prog (m next last)
    (setq m (car lis))
    (cond ((atom m) (return nil))
	  ((top-levels-eq data (car m))
	   (setq *current-token* (1- *current-token*))
	   (rplaca lis (cdr m))
	   (return (car m))))
    (setq next m)
    loop (setq last next)
    (setq next (cdr next))
    (cond ((atom next) (return nil))
	  ((top-levels-eq data (car next))
	   (rplacd last (cdr next))
	   (setq *current-token* (1- *current-token*))
	   (return (car next)))
	  (t (go loop))))) 
