home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume12 / ops5 / part02 < prev    next >
Encoding:
Internet Message Format  |  1987-10-12  |  27.7 KB

  1. Subject:  v12i017:  OPS5 in Common Lisp, Part02/05
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rs@uunet.UU.NET
  5.  
  6. Submitted-by: eric@dlcdev.UUCP (eric van tassell)
  7. Posting-number: Volume 12, Issue 17
  8. Archive-name: ops5/part02
  9.  
  10.  
  11. ; File OPS5.common.1.lsp: part 1 of OPS5 in Common Lisp
  12. ; ----------
  13.  
  14.  
  15. ;    VPS2 -- Interpreter for OPS5
  16. ;
  17. ;    Copyright (C) 1979, 1980, 1981
  18. ;    Charles L. Forgy,  Pittsburgh, Pennsylvania
  19.  
  20.  
  21.  
  22. ; Users of this interpreter are requested to contact
  23.  
  24. ;
  25. ;    Charles Forgy
  26. ;    Computer Science Department
  27. ;    Carnegie-Mellon University
  28. ;    Pittsburgh, PA  15213
  29. ; or
  30. ;    Forgy@CMUA
  31. ; so that they can be added to the mailing list for OPS5.  The mailing list
  32. ; is needed when new versions of the interpreter or manual are released.
  33.  
  34.  
  35.  
  36. ;;; Definitions
  37.  
  38. ;#+ vax (defun putprop(name val att)
  39. ;   (setf (get name att) val))
  40.  
  41.  
  42.  
  43. (proclaim '(special *matrix* *feature-count* *pcount* *vars* *cur-vars*
  44.           *curcond* *subnum* *last-node* *last-branch* *first-node*
  45.           *sendtocall* *flag-part* *alpha-flag-part* *data-part*
  46.           *alpha-data-part* *ce-vars* *virtual-cnt* *real-cnt*
  47.           *current-token* *c1* *c2* *c3* *c4* *c5* *c6* *c7* *c8* *c9*
  48.           *c10* *c11* *c12* *c13* *c14* *c15* *c16* *c17* *c18* *c19*
  49.           *c20* *c21* *c22* *c23* *c24* *c25* *c26* *c27* *c28* *c29*
  50.           *c30* *c31* *c32* *c33* *c34* *c35* *c36* *c37* *c38* *c39*
  51.           *c40* *c41* *c42* *c43* *c44* *c45* *c46* *c47* *c48* *c49*
  52.           *c50* *c51* *c52* *c53* *c54* *c55* *c56* *c57* *c58* *c59*
  53.           *c60* *c61* *c62* *c63* *c64* *record-array* *result-array* 
  54.           *max-cs* *total-cs* *limit-cs* *cr-temp* *side*
  55.           *conflict-set* *halt-flag* *phase* *critical*
  56.           *cycle-count* *total-token* *max-token* *refracts* 
  57.           *limit-token* *total-wm* *current-wm* *max-wm*
  58.           *action-count* *wmpart-list* *wm* *data-matched* *p-name*
  59.           *variable-memory* *ce-variable-memory* 
  60.           *max-index* ; number of right-most field in wm element 
  61.           *next-index* *size-result-array* *rest* *build-trace* *last*
  62.           *ptrace* *wtrace* *in-rhs* *recording* *accept-file* *trace-file* 
  63.           *mtrace* *madeby* ; used to trace and record makers of elements
  64.           *write-file* *record-index* *max-record-index* *old-wm*
  65.           *record* *filters* *break-flag* *strategy* *remaining-cycles*
  66.       *wm-filter* *rhs-bound-vars* *rhs-bound-ce-vars* *ppline* 
  67.       *ce-count* *brkpts* *class-list* *buckets* *action-type*
  68.           *literals*   ;stores literal definitions
  69.           *pnames*     ;stores production names
  70.       *externals*  ;tracks external declarations 
  71.           *vector-attributes*  ;list of vector-attributes
  72.       ))
  73.  
  74. ;(declare (localf ce-gelm gelm peek-sublex sublex
  75. ;          eval-nodelist sendto and-left and-right not-left not-right
  76. ;          top-levels-eq add-token real-add-token remove-old
  77. ;          remove-old-num remove-old-no-num removecs insertcs dsort
  78. ;          best-of best-of* conflict-set-compare =alg ))
  79.  
  80.  
  81. ;;; Functions that were revised so that they would compile efficiently
  82.  
  83.  
  84. ;* The function == is machine dependent\!
  85. ;* This function compares small integers for equality.  It uses EQ
  86. ;* so that it will be fast, and it will consequently not work on all
  87. ;* Lisps.  It works in Franz Lisp for integers in [-128, 127]
  88.  
  89.  
  90. ;(defun == (&rest z) (= (cadr z) (caddr z)))
  91. (defun == (x y) (= x y))
  92.  
  93. ; =ALG returns T if A and B are algebraicly equal.
  94.  
  95. (defun =alg (a b) (= a b))
  96.  
  97. (defmacro fast-symeval (&rest z)
  98.      `(cond ((eq ,(car z) '*c1*) *c1*)
  99.         ((eq ,(car z) '*c2*) *c2*)
  100.         ((eq ,(car z) '*c3*) *c3*)
  101.         ((eq ,(car z) '*c4*) *c4*)
  102.         ((eq ,(car z) '*c5*) *c5*)
  103.         ((eq ,(car z) '*c6*) *c6*)
  104.         ((eq ,(car z) '*c7*) *c7*)
  105.         (t (eval ,(car z)))  ))
  106.  
  107. ; getvector and putvector are fast routines for using one-dimensional
  108. ; arrays.  these routines do no checking; they assume
  109. ;    1. the array is a vector with 0 being the index of the first
  110. ;       element
  111. ;    2. the vector holds arbitrary list values
  112. ;defun versions are useful for tracing
  113.  
  114. ; Example call: (putvector array index value)
  115.  
  116. (defmacro putvector (array_ref ind var)
  117.       `(setf (aref ,array_ref ,ind) ,var))
  118.  
  119. ;(defun putvector (array_ref ind var)
  120. ;      (setf (aref array_ref ind) var))
  121.  
  122. ; Example call: (getvector name index)
  123.  
  124. ;(defmacro getvector(&rest z)
  125. ;     (list 'cxr (caddr z) (cadr z)))
  126.  
  127. (defmacro getvector(array_ref ind)
  128.       `(aref ,array_ref ,ind))
  129.  
  130. ;(defun getvector (array_ref ind)
  131.  ;       (aref array_ref ind))
  132.  
  133. (defun ce-gelm (x k)
  134.   (prog nil
  135.    loop (and (== k 1.) (return (car x)))
  136.         (setq k (1- k))
  137.         (setq x (cdr x))
  138.         (go loop))) 
  139.  
  140. ; The loops in gelm were unwound so that fewer calls on DIFFERENCE
  141. ; would be needed
  142.  
  143. (defun gelm (x k)
  144.   (prog (ce sub)
  145.         (setq ce  (floor (/ k 10000)))
  146.         (setq sub (- k (* ce 10000)))
  147.  celoop (and (== ce 0) (go ph2))
  148.         (setq x (cdr x))
  149.         (and (== ce 1) (go ph2))
  150.         (setq x (cdr x))
  151.         (and (== ce 2) (go ph2))
  152.         (setq x (cdr x))
  153.         (and (== ce 3) (go ph2))
  154.         (setq x (cdr x))
  155.         (and (== ce 4) (go ph2))
  156.         (setq ce (- ce 4))
  157.         (go celoop)
  158.    ph2  (setq x (car x))
  159.    subloop (and (== sub 0) (go finis))
  160.         (setq x (cdr x))
  161.         (and (== sub 1) (go finis))
  162.         (setq x (cdr x))
  163.         (and (== sub 2) (go finis))
  164.         (setq x (cdr x))
  165.         (and (== sub 3) (go finis))
  166.         (setq x (cdr x))
  167.         (and (== sub 4) (go finis))
  168.         (setq x (cdr x))
  169.         (and (== sub 5) (go finis))
  170.         (setq x (cdr x))
  171.         (and (== sub 6) (go finis))
  172.         (setq x (cdr x))
  173.         (and (== sub 7) (go finis))
  174.         (setq x (cdr x))
  175.         (and (== sub 8) (go finis))
  176.         (setq sub (- sub 8))
  177.         (go subloop)
  178.    finis (return (car x)))) 
  179.  
  180.  
  181. ;;; Utility functions
  182.  
  183.  
  184.  
  185. (defun printline (x) (mapc (function printline*) x)) 
  186.  
  187. (defun printline* (y) (princ '| |) (print y)) 
  188.  
  189. (defun printlinec (x) (mapc (function printlinec*) x)) 
  190.  
  191. (defun printlinec* (y) (princ '| |) (princ y)) 
  192.  
  193. ; intersect two lists using eq for the equality test
  194.  
  195. (defun interq (x y)
  196.   (intersection x y :test #'eq))
  197.  
  198. (defun enter (x ll)
  199.    (and (not (member x ll :test #'equal))
  200.        (push x ll)))
  201.  
  202.  
  203. ;Hack read-macro tables to accept single characters -- right out of CL book.
  204. (defun single-macro-character (stream char)
  205.    (declare (ignore stream))
  206.    (character char))
  207.  
  208. (defun i-g-v nil
  209.  (prog (x)
  210.         (set-macro-character #\{ #'single-macro-character )
  211.         (set-macro-character #\} #'single-macro-character )
  212.         (set-macro-character #\^ #'single-macro-character )
  213. ;    (setsyntax '\{ 66.) ;These are already normal characters in CL
  214. ;    (setsyntax '\} 66.)
  215. ;    (setsyntax '^ 66.)
  216.     (setq *buckets* 64.)        ; OPS5 allows 64 named slots
  217.     (setq *accept-file* nil)
  218.     (setq *write-file* nil)
  219.     (setq *trace-file* nil)
  220.         (and (boundp '*class-list*)
  221.           (mapc #'(lambda(class) (putprop class nil 'att-list)) *class-list*))
  222.     (setq *class-list* nil)
  223.     (setq *brkpts* nil)
  224.     (setq *strategy* 'lex)
  225.       (setq *in-rhs* nil)
  226.       (setq *ptrace* t)
  227.       (setq *wtrace* nil)
  228.     (setq *mtrace* t)            ; turn on made-by tracing
  229.     (setq *madeby* nil)          ; record makers of wm elements
  230.       (setq *recording* nil)
  231.         (setq *refracts* nil)
  232.     (setq *real-cnt* (setq *virtual-cnt* 0.))
  233.     (setq *max-cs* (setq *total-cs* 0.))
  234.       (setq *limit-token* 1000000.)
  235.     (setq *limit-cs* 1000000.)
  236.     (setq *critical* nil)
  237.     (setq *build-trace* nil)
  238.     (setq *wmpart-list* nil)
  239.         (setq *pnames* nil)
  240.         (setq *literals* nil) ; records literal definitions
  241.     (setq *externals* nil) ; records external definitions
  242.     (setq *vector-attributes* nil) ;records vector attributes
  243.     (setq *size-result-array* 127.)
  244.     (setq *result-array* (make-array 128))
  245.     (setq *record-array* (make-array 128))
  246.     (setq x 0)
  247.         (setq *pnames* nil)     ; list of production names
  248.   loop    (putvector *result-array* x nil)
  249.     (setq x (1+ x))
  250.     (and (not (> x *size-result-array*)) (go loop))
  251.     (make-bottom-node)
  252.     (setq *pcount* 0.)
  253.     (initialize-record)
  254.     (setq *cycle-count* (setq *action-count* 0.))
  255.     (setq *total-token*
  256.            (setq *max-token* (setq *current-token* 0.)))
  257.     (setq *total-cs* (setq *max-cs* 0.))
  258.     (setq *total-wm* (setq *max-wm* (setq *current-wm* 0.)))
  259.     (setq *conflict-set* nil)
  260.     (setq *wmpart-list* nil)
  261.     (setq *p-name* nil)
  262.     (setq *remaining-cycles* 1000000)
  263. ))
  264.  
  265. ; if the size of result-array changes, change the line in i-g-v which
  266. ; sets the value of *size-result-array*
  267.  
  268. (defun %warn (what where)
  269.   (prog nil
  270.     (terpri)
  271.     (princ '?)
  272.     (and *p-name* (princ *p-name*))
  273.     (princ '|..|)
  274.     (princ where)
  275.     (princ '|..|)
  276.     (princ what)
  277.     (return where))) 
  278.  
  279. (defun %error (what where)
  280.     (%warn what where)
  281.     (throw '!error! nil)) 
  282.  
  283.  
  284. (defun top-levels-eq (la lb)
  285.   (prog nil
  286.    lx   (cond ((eq la lb) (return t))
  287.               ((null la) (return nil))
  288.               ((null lb) (return nil))
  289.               ((not (eq (car la) (car lb))) (return nil)))
  290.         (setq la (cdr la))
  291.         (setq lb (cdr lb))
  292.         (go lx))) 
  293.  
  294.  
  295. ;;; LITERAL and LITERALIZE
  296.  
  297. (defmacro literal (&rest z)
  298.   `(prog (atm val old args)
  299.         (setq args ',z)
  300.    top  (and (atom args) (return 'bound))
  301.         (or (eq (cadr args) '=) (return (%warn '|wrong format| args)))
  302.         (setq atm (car args))
  303.         (setq val (caddr args))
  304.         (setq args (cdddr args))
  305.         (cond ((not (numberp val))
  306.                (%warn '|can bind only to numbers| val))
  307.               ((or (not (symbolp atm)) (variablep atm))
  308.                 (%warn '|can bind only constant atoms| atm))
  309.               ((and (setq old (literal-binding-of atm)) (not (equal old val)))
  310.                (%warn '|attempt to rebind attribute| atm))
  311.               (t (putprop atm val 'ops-bind )))
  312.         (go top))) 
  313.  
  314. (defmacro literalize (&rest l)
  315.   `(prog (class-name atts)
  316.     (setq class-name (car ',l))
  317.     (cond ((have-compiled-production)
  318.            (%warn '|literalize called after p| class-name)
  319.            (return nil))
  320.           ((get class-name 'att-list)
  321.            (%warn '|attempt to redefine class| class-name)
  322.        (return nil)))
  323.     (setq *class-list* (cons class-name *class-list*))
  324.     (setq atts (remove-duplicates (cdr ',l)))
  325.     (test-attribute-names atts)
  326.     (mark-conflicts atts atts)
  327.     (putprop class-name  atts 'att-list))) 
  328.  
  329. (defmacro vector-attribute  (&rest l)
  330.   `(cond ((have-compiled-production)
  331.          (%warn '|vector-attribute called after p| ',l))
  332.         (t 
  333.          (test-attribute-names ',l)
  334.      (mapc (function vector-attribute2) ',l)))) 
  335.  
  336. (defun vector-attribute2 (att) (putprop att t 'vector-attribute)
  337.                    (setq  *vector-attributes* 
  338.                    (enter att *vector-attributes*)))
  339.  
  340. (defun is-vector-attribute (att) (get att 'vector-attribute))
  341.  
  342. (defun test-attribute-names (l)
  343.   (mapc (function test-attribute-names2) l)) 
  344.  
  345. (defun test-attribute-names2 (atm)
  346.   (cond ((or (not (symbolp atm)) (variablep atm))
  347.          (%warn '|can bind only constant atoms| atm)))) 
  348.  
  349. (defun finish-literalize nil
  350.   (cond ((not (null *class-list*))
  351.          (mapc (function note-user-assigns) *class-list*)
  352.          (mapc (function assign-scalars) *class-list*)
  353.          (mapc (function assign-vectors) *class-list*)
  354.          (mapc (function put-ppdat) *class-list*)
  355.          (mapc (function erase-literal-info) *class-list*)
  356.          (setq *class-list* nil)
  357.          (setq *buckets* nil)))) 
  358.  
  359. (defun have-compiled-production nil (not (zerop *pcount*))) 
  360.  
  361. (defun put-ppdat (class)
  362.   (prog (al att ppdat)
  363.         (setq ppdat nil)
  364.         (setq al (get class 'att-list))
  365.    top  (cond ((not (atom al))
  366.                (setq att (car al))
  367.                (setq al (cdr al))
  368.                (setq ppdat
  369.                      (cons (cons (literal-binding-of att) att)
  370.                            ppdat))
  371.                (go top)))
  372.         (putprop class ppdat 'ppdat))) 
  373.  
  374. ; note-user-assigns and note-user-vector-assigns are needed only when
  375. ; literal and literalize are both used in a program.  They make sure that
  376. ; the assignments that are made explicitly with literal do not cause problems
  377. ; for the literalized classes.
  378.  
  379. (defun note-user-assigns (class)
  380.   (mapc (function note-user-assigns2) (get class 'att-list)))
  381.  
  382. (defun note-user-assigns2 (att)
  383.   (prog (num conf buck clash)
  384.         (setq num (literal-binding-of att))
  385.     (and (null num) (return nil))
  386.     (setq conf (get att 'conflicts))
  387.     (setq buck (store-binding att num))
  388.     (setq clash (find-common-atom buck conf))
  389.     (and clash
  390.          (%warn '|attributes in a class assigned the same number|
  391.                 (cons att clash)))
  392.         (return nil)))
  393.  
  394. (defun note-user-vector-assigns (att given needed)
  395.   (and (> needed given)
  396.        (%warn '|vector attribute assigned too small a value in literal| att)))
  397.  
  398. (defun assign-scalars (class)
  399.   (mapc (function assign-scalars2) (get class 'att-list))) 
  400.  
  401. (defun assign-scalars2 (att)
  402.   (prog (tlist num bucket conf)
  403.         (and (literal-binding-of att) (return nil))
  404.         (and (is-vector-attribute att) (return nil))
  405.         (setq tlist (buckets))
  406.         (setq conf (get att 'conflicts))
  407.    top  (cond ((atom tlist)
  408.                (%warn '|could not generate a binding| att)
  409.                (store-binding att -1.)
  410.                (return nil)))
  411.         (setq num (caar tlist))
  412.         (setq bucket (cdar tlist))
  413.         (setq tlist (cdr tlist))
  414.         (cond ((disjoint bucket conf) (store-binding att num))
  415.         (t (go top))))) 
  416.  
  417. (defun assign-vectors (class)
  418.   (mapc (function assign-vectors2) (get class 'att-list))) 
  419.  
  420. (defun assign-vectors2 (att)
  421.   (prog (big conf new old need)
  422.         (and (not (is-vector-attribute att)) (return nil))
  423.         (setq big 1.)
  424.         (setq conf (get att 'conflicts))
  425.    top  (cond ((not (atom conf))
  426.                (setq new (car conf))
  427.                (setq conf (cdr conf))
  428.                (cond ((is-vector-attribute new)
  429.                       (%warn '|class has two vector attributes|
  430.                       (list att new)))
  431.                      (t (setq big (max (literal-binding-of new) big))))
  432.                (go top)))
  433.         (setq need (1+ big))
  434.     (setq old (literal-binding-of att))
  435.     (cond (old (note-user-vector-assigns att old need))
  436.           (t (store-binding att need)))
  437.         (return nil)))
  438.  
  439. (defun disjoint (la lb) (not (find-common-atom la lb))) 
  440.  
  441. (defun find-common-atom (la lb)
  442.   (prog nil
  443.    top  (cond ((null la) (return nil))
  444.               ((member (car la) lb :test #'eq) (return (car la)))
  445.               (t (setq la (cdr la)) (go top))))) 
  446.  
  447. (defun mark-conflicts (rem all)
  448.   (cond ((not (null rem))
  449.          (mark-conflicts2 (car rem) all)
  450.          (mark-conflicts (cdr rem) all)))) 
  451.  
  452. (defun mark-conflicts2 (atm lst)
  453.   (prog (l)
  454.         (setq l lst)
  455.    top  (and (atom l) (return nil))
  456.         (conflict atm (car l))
  457.         (setq l (cdr l))
  458.         (go top))) 
  459.  
  460. (defun conflict (a b)
  461.   (prog (old)
  462.     (setq old (get a 'conflicts))
  463.     (and (not (eq a b))
  464.          (not (member b old :test #'eq))
  465.          (putprop a (cons b old) 'conflicts )))) 
  466.  
  467. ;(defun remove-duplicates (lst)
  468. ;  (cond ((atom lst) nil)
  469. ;        ((member (car lst) (cdr lst) :test #'eq) (remove-duplicates (cdr lst)))
  470. ;        (t (cons (car lst) (remove-duplicates (cdr lst)))))) 
  471.  
  472. (defun literal-binding-of (name) (get name 'ops-bind)) 
  473.  
  474. (defun store-binding (name lit)
  475.   (putprop name lit 'ops-bind)
  476.   (add-bucket name lit)) 
  477.  
  478. (defun add-bucket (name num)
  479.   (prog (buc)
  480.     (setq buc (assoc num (buckets)))
  481.     (and (not (member name buc :test #'eq))
  482.          (rplacd buc (cons name (cdr buc))))
  483.     (return buc))) 
  484.  
  485. (defun buckets nil
  486.   (and (atom *buckets*) (setq *buckets* (make-nums *buckets*)))
  487.   *buckets*) 
  488.  
  489. (defun make-nums (k)
  490.   (prog (nums)
  491.         (setq nums nil)
  492.    l    (and (< k 2.) (return nums))
  493.         (setq nums (cons (cons k nil) nums))
  494.         (setq k (1- k))
  495.         (go l))) 
  496.  
  497. ;(defun erase-literal-info (class)
  498. ;  (mapc (function erase-literal-info2) (get class 'att-list))
  499. ;  (remprop class 'att-list)) 
  500.  
  501. ; modified to record literal info in the variable *literals*
  502. (defun erase-literal-info (class)
  503.       (setq *literals*
  504.             (cons (cons class (get class 'att-list)) *literals*))
  505.       (mapc (function erase-literal-info2) (get class 'att-list))
  506.       (remprop class 'att-list))
  507.  
  508.  
  509. (defun erase-literal-info2 (att) (remprop att 'conflicts)) 
  510.  
  511.  
  512. ;;; LHS Compiler
  513.  
  514. (defmacro p (&rest z) 
  515.  `(progn 
  516.    (finish-literalize)
  517.    (princ '*) 
  518.   ;(drain);drain probably drains a line feed
  519.    (compile-production (car ',z) (cdr ',z)))) 
  520.  
  521. (defun compile-production (name matrix)
  522.   (prog (erm)
  523.         (setq *p-name* name)
  524.         (setq erm (catch '!error! (cmp-p name matrix) ))
  525.     ; following line is modified to save production name on *pnames*
  526.         (and (null erm) (setq *pnames* (enter name *pnames*)))
  527.     (setq *p-name* nil)
  528.     (return erm)))
  529.  
  530. (defun peek-lex nil (car *matrix*)) 
  531.  
  532. (defun lex nil
  533.   (prog2 nil (car *matrix*) (setq *matrix* (cdr *matrix*)))) 
  534.  
  535. (defun end-of-p nil (atom *matrix*)) 
  536.  
  537. (defun rest-of-p nil *matrix*) 
  538.  
  539. (defun prepare-lex (prod) (setq *matrix* prod)) 
  540.  
  541.  
  542. (defun peek-sublex nil (car *curcond*)) 
  543.  
  544. (defun sublex nil
  545.   (prog2 nil (car *curcond*) (setq *curcond* (cdr *curcond*)))) 
  546.  
  547. (defun end-of-ce nil (atom *curcond*)) 
  548.  
  549. (defun rest-of-ce nil *curcond*) 
  550.  
  551. (defun prepare-sublex (ce) (setq *curcond* ce)) 
  552.  
  553. (defun make-bottom-node nil (setq *first-node* (list '&bus nil))) 
  554.  
  555. (defun cmp-p (name matrix)
  556.   (prog (m bakptrs)
  557.         (cond ((or (null name) (listp name))
  558.                (%error '|illegal production name| name))
  559.               ((equal (get name 'production) matrix)
  560.            (return nil)))
  561.         (prepare-lex matrix)
  562.         (excise-p name)
  563.         (setq bakptrs nil)
  564.         (setq *pcount* (1+ *pcount*))
  565.         (setq *feature-count* 0.)
  566.     (setq *ce-count* 0)
  567.         (setq *vars* nil)
  568.         (setq *ce-vars* nil)
  569.     (setq *rhs-bound-vars* nil)
  570.     (setq *rhs-bound-ce-vars* nil)
  571.         (setq *last-branch* nil)
  572.         (setq m (rest-of-p))
  573.    l1   (and (end-of-p) (%error '|no '-->' in production| m))
  574.         (cmp-prin)
  575.         (setq bakptrs (cons *last-branch* bakptrs))
  576.         (or (eq '--> (peek-lex)) (go l1))
  577.         (lex)
  578.     (check-rhs (rest-of-p))
  579.         (link-new-node (list '&p
  580.                              *feature-count*
  581.                              name
  582.                              (encode-dope)
  583.                              (encode-ce-dope)
  584.                              (cons 'progn (rest-of-p))))
  585.         (putprop name (cdr (nreverse bakptrs)) 'backpointers )
  586.     (putprop name matrix 'production)
  587.         (putprop name *last-node* 'topnode))) 
  588.  
  589. (defun rating-part (pnode) (cadr pnode)) 
  590.  
  591. (defun var-part (pnode) (car (cdddr pnode))) 
  592.  
  593. (defun ce-var-part (pnode) (cadr (cdddr pnode))) 
  594.  
  595. (defun rhs-part (pnode) (caddr (cdddr pnode))) 
  596.  
  597. (defun excise-p (name)
  598.   (cond ((and (symbolp name) (get name 'topnode))
  599.      (printline (list name 'is 'excised))
  600.          (setq *pcount* (1- *pcount*))
  601.          (remove-from-conflict-set name)
  602.          (kill-node (get name 'topnode))
  603.          (setq *pnames* (delete name *pnames* :test #'eq))
  604.      (remprop name 'production)
  605.      (remprop name 'backpointers)
  606.          (remprop name 'topnode)))) 
  607.  
  608. (defun kill-node (node)
  609.   (prog nil
  610.    top  (and (atom node) (return nil))
  611.         (rplaca node '&old)
  612.         (setq node (cdr node))
  613.         (go top))) 
  614.  
  615. (defun cmp-prin nil
  616.   (prog nil
  617.         (setq *last-node* *first-node*)
  618.         (cond ((null *last-branch*) (cmp-posce) (cmp-nobeta))
  619.               ((eq (peek-lex) '-) (cmp-negce) (cmp-not))
  620.               (t (cmp-posce) (cmp-and))))) 
  621.  
  622. (defun cmp-negce nil (lex) (cmp-ce)) 
  623.  
  624. (defun cmp-posce nil
  625.   (setq *ce-count* (1+ *ce-count*))
  626.   (cond ((eq (peek-lex) #\{) (cmp-ce+cevar))
  627.         (t (cmp-ce)))) 
  628.  
  629. (defun cmp-ce+cevar nil
  630.   (prog (z)
  631.         (lex)
  632.         (cond ((atom (peek-lex)) (cmp-cevar) (cmp-ce))
  633.               (t (cmp-ce) (cmp-cevar)))
  634.         (setq z (lex))
  635.         (or (eq z #\}) (%error '|missing '}'| z)))) 
  636.  
  637. (defun new-subnum (k)
  638.   (or (numberp k) (%error '|tab must be a number| k))
  639.   (setq *subnum* (round k))) 
  640.  
  641. (defun incr-subnum nil (setq *subnum* (1+ *subnum*))) 
  642.  
  643. (defun cmp-ce nil
  644.   (prog (z)
  645.         (new-subnum 0.)
  646.         (setq *cur-vars* nil)
  647.         (setq z (lex))
  648.         (and (atom z)
  649.              (%error '|atomic conditions are not allowed| z))
  650.         (prepare-sublex z)
  651.    la   (and (end-of-ce) (return nil))
  652.         (incr-subnum)
  653.         (cmp-element)
  654.         (go la))) 
  655.  
  656. (defun cmp-element nil
  657.         (and (eq (peek-sublex) #\^) (cmp-tab))
  658.         (cond ((eq (peek-sublex) '#\{) (cmp-product))
  659.               (t (cmp-atomic-or-any))))
  660.  
  661. (defun cmp-atomic-or-any nil
  662.         (cond ((eq (peek-sublex) '<<) (cmp-any))
  663.               (t (cmp-atomic))))
  664.  
  665. (defun cmp-any nil
  666.   (prog (a z)
  667.         (sublex)
  668.         (setq z nil)
  669.    la   (cond ((end-of-ce) (%error '|missing '>>'| a)))
  670.         (setq a (sublex))
  671.         (cond ((not (eq '>> a)) (setq z (cons a z)) (go la)))
  672.         (link-new-node (list '&any nil (current-field) z)))) 
  673.  
  674.  
  675. (defun cmp-tab nil
  676.   (prog (r)
  677.         (sublex)
  678.         (setq r (sublex))
  679.         (setq r ($litbind r))
  680.         (new-subnum r))) 
  681.  
  682. (defun $litbind (x)
  683.   (prog (r)
  684.         (cond ((and (symbolp x) (setq r (literal-binding-of x)))
  685.                (return r))
  686.               (t (return x))))) 
  687.  
  688. (defun get-bind (x)
  689.   (prog (r)
  690.         (cond ((and (symbolp x) (setq r (literal-binding-of x)))
  691.                (return r))
  692.               (t (return nil))))) 
  693.  
  694. (defun cmp-atomic nil
  695.   (prog (test x)
  696.         (setq x (peek-sublex))
  697.         (cond ((eq x '=) (setq test 'eq) (sublex))
  698.               ((eq x '<>) (setq test 'ne) (sublex))
  699.               ((eq x '<) (setq test 'lt) (sublex))
  700.               ((eq x '<=) (setq test 'le) (sublex))
  701.               ((eq x '>) (setq test 'gt) (sublex))
  702.               ((eq x '>=) (setq test 'ge) (sublex))
  703.               ((eq x '<=>) (setq test 'xx) (sublex))
  704.               (t (setq test 'eq)))
  705.         (cmp-symbol test))) 
  706.  
  707. (defun cmp-product nil
  708.   (prog (save)
  709.         (setq save (rest-of-ce))
  710.         (sublex)
  711.    la   (cond ((end-of-ce)
  712.                (cond ((member #\} save) 
  713.               (%error '|wrong contex for '}'| save))
  714.              (t (%error '|missing '}'| save))))
  715.               ((eq (peek-sublex) #\}) (sublex) (return nil)))
  716.         (cmp-atomic-or-any)
  717.         (go la))) 
  718.  
  719. (defun variablep (x) (and (symbolp x) (char-equal (char (symbol-name x) 0) #\<))) 
  720.  
  721. (defun cmp-symbol (test)
  722.   (prog (flag)
  723.         (setq flag t)
  724.         (cond ((eq (peek-sublex) '//) (sublex) (setq flag nil)))
  725.         (cond ((and flag (variablep (peek-sublex)))
  726.                (cmp-var test))
  727.               ((numberp (peek-sublex)) (cmp-number test))
  728.               ((symbolp (peek-sublex)) (cmp-constant test))
  729.               (t (%error '|unrecognized symbol| (sublex)))))) 
  730.  
  731. (defun concat3(x y z)
  732.    (intern (format nil "~s~s~s" x y z)))
  733.  
  734. (defun cmp-constant (test)
  735.   (or (member test '(eq ne xx) )
  736.       (%error '|non-numeric constant after numeric predicate| (sublex)))
  737.   (link-new-node (list (concat3 't test 'a)
  738.                        nil
  739.                        (current-field)
  740.                        (sublex)))) 
  741.  
  742.  
  743. (defun cmp-number (test)
  744.   (link-new-node (list (concat3 't test 'n)
  745.                        nil
  746.                        (current-field)
  747.                        (sublex)))) 
  748.  
  749. (defun current-field nil (field-name *subnum*)) 
  750.  
  751. (defun field-name (num)
  752.   (cond ((= num 1.) '*c1*)
  753.         ((= num 2.) '*c2*)
  754.         ((= num 3.) '*c3*)
  755.         ((= num 4.) '*c4*)
  756.         ((= num 5.) '*c5*)
  757.         ((= num 6.) '*c6*)
  758.         ((= num 7.) '*c7*)
  759.         ((= num 8.) '*c8*)
  760.         ((= num 9.) '*c9*)
  761.         ((= num 10.) '*c10*)
  762.         ((= num 11.) '*c11*)
  763.         ((= num 12.) '*c12*)
  764.         ((= num 13.) '*c13*)
  765.         ((= num 14.) '*c14*)
  766.         ((= num 15.) '*c15*)
  767.         ((= num 16.) '*c16*)
  768.         ((= num 17.) '*c17*)
  769.         ((= num 18.) '*c18*)
  770.         ((= num 19.) '*c19*)
  771.         ((= num 20.) '*c20*)
  772.         ((= num 21.) '*c21*)
  773.         ((= num 22.) '*c22*)
  774.         ((= num 23.) '*c23*)
  775.         ((= num 24.) '*c24*)
  776.         ((= num 25.) '*c25*)
  777.         ((= num 26.) '*c26*)
  778.         ((= num 27.) '*c27*)
  779.         ((= num 28.) '*c28*)
  780.         ((= num 29.) '*c29*)
  781.         ((= num 30.) '*c30*)
  782.         ((= num 31.) '*c31*)
  783.         ((= num 32.) '*c32*)
  784.         ((= num 33.) '*c33*)
  785.         ((= num 34.) '*c34*)
  786.         ((= num 35.) '*c35*)
  787.         ((= num 36.) '*c36*)
  788.         ((= num 37.) '*c37*)
  789.         ((= num 38.) '*c38*)
  790.         ((= num 39.) '*c39*)
  791.         ((= num 40.) '*c40*)
  792.         ((= num 41.) '*c41*)
  793.         ((= num 42.) '*c42*)
  794.         ((= num 43.) '*c43*)
  795.         ((= num 44.) '*c44*)
  796.         ((= num 45.) '*c45*)
  797.         ((= num 46.) '*c46*)
  798.         ((= num 47.) '*c47*)
  799.         ((= num 48.) '*c48*)
  800.         ((= num 49.) '*c49*)
  801.         ((= num 50.) '*c50*)
  802.         ((= num 51.) '*c51*)
  803.         ((= num 52.) '*c52*)
  804.         ((= num 53.) '*c53*)
  805.         ((= num 54.) '*c54*)
  806.         ((= num 55.) '*c55*)
  807.         ((= num 56.) '*c56*)
  808.         ((= num 57.) '*c57*)
  809.         ((= num 58.) '*c58*)
  810.         ((= num 59.) '*c59*)
  811.         ((= num 60.) '*c60*)
  812.         ((= num 61.) '*c61*)
  813.         ((= num 62.) '*c62*)
  814.         ((= num 63.) '*c63*)
  815.         ((= num 64.) '*c64*)
  816.         (t (%error '|condition is too long| (rest-of-ce))))) 
  817.  
  818.  
  819. ;;; Compiling variables
  820. ;
  821. ;
  822. ;
  823. ; *cur-vars* are the variables in the condition element currently 
  824. ; being compiled.  *vars* are the variables in the earlier condition
  825. ; elements.  *ce-vars* are the condition element variables.  note
  826. ; that the interpreter will not confuse condition element and regular
  827. ; variables even if they have the same name.
  828. ;
  829. ; *cur-vars* is a list of triples: (name predicate subelement-number)
  830. ; eg:        ( (<x> eq 3)
  831. ;          (<y> ne 1)
  832. ;          . . . )
  833. ;
  834. ; *vars* is a list of triples: (name ce-number subelement-number)
  835. ; eg:        ( (<x> 3 3)
  836. ;          (<y> 1 1)
  837. ;          . . . )
  838. ;
  839. ; *ce-vars* is a list of pairs: (name ce-number)
  840. ; eg:        ( (ce1 1)
  841. ;          (<c3> 3)
  842. ;          . . . )
  843.  
  844. (defun var-dope (var) (assoc var *vars* :test #'eq))
  845.  
  846. (defun ce-var-dope (var) (assoc var *ce-vars* :test #'eq))
  847.  
  848. (defun cmp-var (test)
  849.   (prog (old name)
  850.         (setq name (sublex))
  851.         (setq old (assoc name *cur-vars* :test #'eq))
  852.         (cond ((and old (eq (cadr old) 'eq))
  853.                (cmp-old-eq-var test old))
  854.               ((and old (eq test 'eq)) (cmp-new-eq-var name old))
  855.               (t (cmp-new-var name test))))) 
  856.  
  857. (defun cmp-new-var (name test)
  858.   (setq *cur-vars* (cons (list name test *subnum*) *cur-vars*))) 
  859.  
  860. (defun cmp-old-eq-var (test old)
  861.   (link-new-node (list (concat3 't test 's)
  862.                        nil
  863.                        (current-field)
  864.                        (field-name (caddr old))))) 
  865.  
  866. (defun cmp-new-eq-var (name old)
  867.   (prog (pred next)
  868.         (setq *cur-vars* (delete old *cur-vars* :test #'eq))
  869.         (setq next (assoc name *cur-vars* :test #'eq))
  870.         (cond (next (cmp-new-eq-var name next))
  871.               (t (cmp-new-var name 'eq)))
  872.         (setq pred (cadr old))
  873.         (link-new-node (list (concat3 't pred 's)
  874.                              nil
  875.                              (field-name (caddr old))
  876.                              (current-field))))) 
  877.  
  878. (defun cmp-cevar nil
  879.   (prog (name old)
  880.         (setq name (lex))
  881.         (setq old (assoc name *ce-vars* :test #'eq))
  882.         (and old
  883.              (%error '|condition element variable used twice| name))
  884.         (setq *ce-vars* (cons (list name 0.) *ce-vars*)))) 
  885.  
  886. (defun cmp-not nil (cmp-beta '¬)) 
  887.  
  888. (defun cmp-nobeta nil (cmp-beta nil)) 
  889.  
  890. (defun cmp-and nil (cmp-beta '&and)) 
  891.  
  892. (defun cmp-beta (kind)
  893.   (prog (tlist vdope vname vpred vpos old)
  894.         (setq tlist nil)
  895.    la   (and (atom *cur-vars*) (go lb))
  896.         (setq vdope (car *cur-vars*))
  897.         (setq *cur-vars* (cdr *cur-vars*))
  898.         (setq vname (car vdope))
  899.         (setq vpred (cadr vdope))
  900.         (setq vpos (caddr vdope))
  901.         (setq old (assoc vname *vars* :test #'eq))
  902.         (cond (old (setq tlist (add-test tlist vdope old)))
  903.               ((not (eq kind '¬)) (promote-var vdope)))
  904.         (go la)
  905.    lb   (and kind (build-beta kind tlist))
  906.         (or (eq kind '¬) (fudge))
  907.         (setq *last-branch* *last-node*))) 
  908.  
  909. (defun add-test (list new old)
  910.   (prog (ttype lloc rloc)
  911.     (setq *feature-count* (1+ *feature-count*))
  912.         (setq ttype (concat3 't (cadr new) 'b))
  913.         (setq rloc (encode-singleton (caddr new)))
  914.         (setq lloc (encode-pair (cadr old) (caddr old)))
  915.         (return (cons ttype (cons lloc (cons rloc list)))))) 
  916.  
  917.