Annotation of 43BSD/ucb/lisp/pearl/match.l, revision 1.1

1.1     ! root        1: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; match.l ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             2: ; Functions for matching, comparing, and testing structures.
        !             3: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !             4: ; Copyright (c) 1983 ,  The Regents of the University of California.
        !             5: ; All rights reserved.  
        !             6: ; Authors: Joseph Faletti and Michael Deering.
        !             7: ; Unification added by David Chin.
        !             8: 
        !             9: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !            10: ; Functions which accomplish unification of two variables.
        !            11: 
        !            12: ; Turns on unification (irrevocably).
        !            13: (de useunification ()
        !            14:   (setq *unifyunbounds* t)
        !            15:   'UsingUnification)
        !            16: 
        !            17: ; sets all variables in the var list of the equiv class (first arg) which are
        !            18: ; still bound to the equiv class to the new value (second arg).
        !            19: (defmacro setequivclass (equiv value)
        !            20:   `(mapc (funl (var)
        !            21:               (cond ((dtpr var)  ; a local var cell
        !            22:                      ; If bound to equiv class, then save the old value
        !            23:                      ;   and set the var to value.
        !            24:                      (and (eq (cdr var) ,equiv)
        !            25:                           (push (cons var (cdr var)) *equivsavestack*)
        !            26:                           (rplacd var ,value)))
        !            27:                     ( t ; otherwise a global var.
        !            28:                         (and (eq (eval var) ,equiv)
        !            29:                              (push (cons var (eval var)) *equivsavestack*)
        !            30:                              (set var ,value)))))
        !            31:         (cdr ,equiv)))
        !            32: 
        !            33: ; unifies two unbound variables (0, one or both may already be equiv classes).
        !            34: (dm unifytwovars (none)
        !            35:   '(progn (setq xval (cond ((dtpr xvar) (cdr xvar))
        !            36:                           ( t (eval xvar))))
        !            37:          (setq yval (cond ((dtpr yvar) (cdr yvar))
        !            38:                           ( t (eval yvar))))
        !            39:          (cond ((eq xvar yvar)
        !            40:                 ; Same variable, so leave xvar and yvar alone.
        !            41:                 (setq newval nil))
        !            42:                ; Both values are unbound so create a new equiv class.
        !            43:                ((and (eq xval (punbound))
        !            44:                      (eq yval (punbound)))
        !            45:                 (setq newval (cons (equivclass) (list xvar yvar))))
        !            46:                ; Same equiv class (not "unbound"), so leave xvar & yvar alone.
        !            47:                ((eq xval yval)
        !            48:                 (setq newval nil))
        !            49:                ; Both are equiv classes, so merge into a new equiv class.
        !            50:                ((and (pboundp xval)
        !            51:                      (pboundp yval))
        !            52:                 (setq newval
        !            53:                       (cons (equivclass)
        !            54:                             (cond ((<& (length (cdr xval))
        !            55:                                        (length (cdr yval)))
        !            56:                                    (append (cdr xval) (cdr yval)))
        !            57:                                   ( t (append (cdr yval) (cdr xval))))))
        !            58:                 ; And change the equiv class for the other vars in the list.
        !            59:                 (setequivclass xval newval)
        !            60:                 (setequivclass yval newval))
        !            61:                ((punboundatomp xval) ; xvar is not an equiv class.
        !            62:                 (cond ((memq xvar (cdr yval)) ; but used to be in yvar's.
        !            63:                        (setq newval yval))
        !            64:                       ( t ; else build a new equiv class with yvar added.
        !            65:                           (setq newval (cons (equivclass)
        !            66:                                              (cons xvar (cdr yval))))
        !            67:                           (setequivclass yval newval))))
        !            68:                ( t ; otherwise yvar is not an equiv class.
        !            69:                    (cond ((memq yvar (cdr xval)) ; but used to be in xvar's.
        !            70:                           (setq newval xval))
        !            71:                          ( t ; else build a new equiv class with xvar added.
        !            72:                              (setq newval (cons (equivclass)
        !            73:                                                 (cons yvar (cdr xval))))
        !            74:                              (setequivclass xval newval)))))
        !            75:          ; Set the variables to a new equiv class created above.
        !            76:          (and newval
        !            77:               (progn
        !            78:                ; Save the old values in case match fails
        !            79:                (push (cons xvar xval) *equivsavestack*)
        !            80:                (push (cons yvar yval) *equivsavestack*)
        !            81:                ; And set variables (either local or global).
        !            82:                (cond ((dtpr xvar) (rplacd xvar newval))
        !            83:                      ( t (set xvar newval)))
        !            84:                (cond ((dtpr yvar) (rplacd yvar newval))
        !            85:                      ( t (set yvar newval)))))
        !            86:          ))
        !            87: 
        !            88: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !            89: ; Low level macros for matching.
        !            90: 
        !            91: ; Fast macro for minimum of two lengths.
        !            92: (defmacro min& (n1 n2)
        !            93:   `(let ((min ,n1)
        !            94:         (other ,n2))
        !            95:        (and (>& min other)
        !            96:             (setq min other))
        !            97:        min))
        !            98: 
        !            99: ; Unbind all vars on the item's assoc list
        !           100: (defmacro unbindvars (item)
        !           101:   `(mapc (funl (cell) (rplacd cell (punbound))) (getalist ,item)))
        !           102: 
        !           103: ; Set the GLOBAL or VAR variable to the value.
        !           104: (defmacro varset (var val)
        !           105:   `(let ((localvar ,var)
        !           106:         (localval ,val)
        !           107:         savevarval)
        !           108:        (cond ((dtpr localvar)
        !           109:               (setq savevarval (cdr localvar))
        !           110:               (rplacd localvar localval))
        !           111:              ( t (push localvar *globalsavestack*)
        !           112:                  (setq savevarval (eval localvar))
        !           113:                  (set localvar localval)))
        !           114:        (and *unifyunbounds*
        !           115:             (equivclassp savevarval)
        !           116:             (setequivclass savevarval localval))))
        !           117: 
        !           118: ; Set the GLOBAL or VAR adjunct variable to the value.
        !           119: (defmacro adjvarset (var val)
        !           120:   `(let ((localvar ,var)
        !           121:         (localval ,val)
        !           122:         savevarval)
        !           123:        (and localvar
        !           124:             (progn (cond ((dtpr localvar)
        !           125:                           (setq savevarval (cdr localvar))
        !           126:                           (rplacd localvar localval))
        !           127:                          ( t (push localvar *globalsavestack*)
        !           128:                              (setq savevarval (eval localvar))
        !           129:                              (set localvar localval)))
        !           130:                    (and *unifyunbounds*
        !           131:                         (equivclassp savevarval)
        !           132:                         (setequivclass savevarval localval))))))
        !           133: 
        !           134: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !           135: ; Macros for matching individual values.
        !           136: 
        !           137: ; Check whether VAL is consistent with the predicates in PREDLIST.
        !           138: (defmacro consistentvalue (val predlist type item defblock)
        !           139:   `(prog (restriction)
        !           140:         loop
        !           141:         (cond ((null ,predlist) (return t)) ; all predicates were true.
        !           142:               ; Otherwise, execute the next one.
        !           143:               ((cond ((reallitatom (setq restriction (pop ,predlist)))
        !           144:                       ; The name of a function to be applied.
        !           145:                       (apply* restriction (ncons ,val)))
        !           146:                      ; An s-expression predicate -- fill in and execute.
        !           147:                      ((dtpr restriction)
        !           148:                       (eval (fillin1 restriction ,val ,item ,defblock)))
        !           149:                      ; Otherwise, a value.
        !           150:                      ( t
        !           151:                       (selectq ,type
        !           152:                                (0 (or (let ((def (getdefinition ,val)))
        !           153:                                            (eq restriction def))
        !           154:                                       (disguisedas ,val restriction)))
        !           155:                                (1 (disguisedas ,val restriction))
        !           156:                                (2 (\=& restriction ,val))
        !           157:                                (3 (eq restriction ,val))
        !           158:                                (otherwise
        !           159:                                 ; A better way needed ?? Never done????
        !           160:                                 (eq restriction (car ,val))))))
        !           161:                (go loop))
        !           162:               ; Otherwise this predicate failed, so we fail.
        !           163:               ( t (return nil)))))
        !           164: 
        !           165: ; Check two values for "equality".
        !           166: (defmacro equalvalue (xval yval type)
        !           167:   `(selectq ,type
        !           168:            (0 (basicmatch ,xval ,yval))
        !           169:            (1 (eq ,xval ,yval))
        !           170:            (2 (\=& ,xval ,yval))
        !           171:            (3 (equal ,xval ,yval))
        !           172:            (otherwise
        !           173:             ; A better way needed!!!!!!!!!!!!!!!!!!!  something like:
        !           174:             ; (apply (function and)
        !           175:             ;        (mapcar (function equalvalue) ,xval ,yval (strip ,type)))
        !           176:             t)))
        !           177: 
        !           178: ; Check to see if two slots whose number is passed are matchable,
        !           179: ; binding any variables and running any predicates.
        !           180: ; Assumes slotnum, item1, item2, def1, def2 already set and others declared
        !           181: ;    in main PROG.  The local PROG is necessary for slothooks processing.
        !           182: (dm compatible (none)
        !           183:   '(prog ()
        !           184:         ; *val and *var are both set by these calls.
        !           185:         ; *var are set to nil if no local, global, or adjunct variable.
        !           186:         (setq xval (getvarandvalue slotnum item1 'xvar))
        !           187:         (setq yval (getvarandvalue slotnum item2 'yvar))
        !           188:         ;
        !           189:         ; *ANY* => always match
        !           190:         (and (or (eq xvar *any*conscell*)
        !           191:                  (eq yvar *any*conscell*))
        !           192:              (return t))
        !           193:         ;
        !           194:         ; If both are unbound, return *matchunboundsresult* (initially nil).
        !           195:         (setq xvalunbound (punboundatomp xval))
        !           196:         (setq yvalunbound (punboundatomp yval))
        !           197:         (setq bothunbound (and xvalunbound yvalunbound))
        !           198:         (and bothunbound
        !           199:              (or *unifyunbounds*
        !           200:                  (return *matchunboundsresult*)))
        !           201:         ;
        !           202:         ; Get the slots' common type and individual predicates.
        !           203:         (setq slottype (getslottype slotnum def1))
        !           204:         (setq xpredlist (getpred slotnum item1))
        !           205:         (setq ypredlist (getpred slotnum item2))
        !           206:         (doslothooks2< '<match *runmatchhooks*)
        !           207:         ;
        !           208:         ; Otherwise we check to see if one of the slots can be
        !           209:         ;     bound to the other.
        !           210:         (cond (bothunbound ; Two unbound variables to be unified.
        !           211:                            (unifytwovars)
        !           212:                            (setq result t))
        !           213:               (xvalunbound ; Match x's variable against y's value.
        !           214:                (and (setq result
        !           215:                           (consistentvalue yval xpredlist slottype item2 def2))
        !           216:                     (varset xvar yval)))
        !           217:               (yvalunbound ; Match y's variable against x's value.
        !           218:                (and (setq result
        !           219:                           (consistentvalue xval ypredlist slottype item1 def1))
        !           220:                     (varset yvar xval)))
        !           221:               ( t  ; both are bound values -- check "equality".
        !           222:                    (and (setq result (equalvalue xval yval slottype))
        !           223:                         ; and set the adjunct variables (if any)
        !           224:                         (progn (adjvarset xvar yval)
        !           225:                                (adjvarset yvar xval)))))
        !           226:         (doslothooks2> '>match *runmatchhooks*)
        !           227:         (return result)))
        !           228: 
        !           229: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !           230: ; Principle match functions.
        !           231: 
        !           232: ; Match two structures slot by slot, WITHOUT unbinding variables first,
        !           233: ; but binding along the way.
        !           234: (de basicmatch (item1 item2)
        !           235:   (prog (newitem1 newitem2 result slottype xvar yvar xval yval def1 def2
        !           236:                  xvalunbound yvalunbound length
        !           237:                  newxval newyval xpredlist ypredlist xhooks yhooks
        !           238:                  newval bothunbound)
        !           239:        (setq def1 (getdefinition item1))
        !           240:        (setq def2 (getdefinition item2))
        !           241:        (setq length (getstructlength def1))
        !           242:        (dobasehooks2< '<match *runmatchhooks*)
        !           243:        (cond ((eq item1 item2) (setq result t)) ; Same structure -> t.
        !           244:              ; Not even related -> nil.
        !           245:              ((not (eq def1 def2)) (setq result nil))
        !           246:              ; No slots -> t.
        !           247:              ((\=& 0 length) (setq result t))
        !           248:              ; Otherwise, compare slot by slot.
        !           249:              ( t (setq result
        !           250:                        (for slotnum 1 length
        !           251:                             (or (compatible)
        !           252:                                 (return nil))))))
        !           253:        (dobasehooks2> '>match *runmatchhooks*)
        !           254:        (return result)))
        !           255: 
        !           256: ; Match two structures slot by slot, unbinding variables first.
        !           257: (de standardmatch (item1 item2)
        !           258:   (prog (newitem1 newitem2 result slottype xvar yvar xval yval def1 def2
        !           259:                  xvalunbound yvalunbound length *globalsavestack*
        !           260:                  newxval newyval xpredlist ypredlist xhooks yhooks
        !           261:                  newval bothunbound *equivsavestack*)
        !           262:        (unbindvars item1)
        !           263:        (unbindvars item2)
        !           264:        (setq def1 (getdefinition item1))
        !           265:        (setq def2 (getdefinition item2))
        !           266:        (setq length (getstructlength def1))
        !           267:        (dobasehooks2< '<match *runmatchhooks*)
        !           268:        (cond ((eq item1 item2) (setq result t)) ; Same structure -> t.
        !           269:              ; Not even related -> nil.
        !           270:              ((not (eq def1 def2)) (setq result nil))
        !           271:              ; No slots -> t.
        !           272:              ((\=& 0 length) (setq result t))
        !           273:              ; Otherwise, compare slot by slot.
        !           274:              ( t (setq result
        !           275:                        (for slotnum 1 length
        !           276:                             (or (compatible)
        !           277:                                 (return nil))))))
        !           278:        (dobasehooks2> '>match *runmatchhooks*)
        !           279:        (or result 
        !           280:            ; Clean up the variables because of the failure.
        !           281:            (progn (unbindvars item1)
        !           282:                   (unbindvars item2)
        !           283:                   (and *globalsavestack*
        !           284:                        (mapc (funl (var)
        !           285:                                    (set var (punbound)))
        !           286:                              *globalsavestack*))
        !           287:                   ; *equivsavestack* is only non-nil when *unifyunbounds* is t.
        !           288:                   (and *equivsavestack*
        !           289:                        (mapc (funl (pair)
        !           290:                                    (cond ((dtpr (car pair))
        !           291:                                           (rplacd (car pair) (cdr pair)))
        !           292:                                          ( t (set (car pair) (cdr pair)))))
        !           293:                              *equivsavestack*))))
        !           294:        (return result)))
        !           295: 
        !           296: (aliasdef 'match 'standardmatch)
        !           297: 
        !           298: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !           299: ; Functions similar to above but for expanded structures.
        !           300: 
        !           301: ; Check to see either defblock is an expansion of the other.
        !           302: (defmacro relatedhier (defblock1 defblock2)
        !           303:   `(or (eq ,defblock1 ,defblock2)
        !           304:        (memq ,defblock2 (getexpansionlist ,defblock1))
        !           305:        (memq ,defblock1 (getexpansionlist ,defblock2))))
        !           306: 
        !           307: ; Check whether VAL is consistent with the predicates in PREDLIST.
        !           308: (defmacro expconsistentvalue (val predlist type item defblock)
        !           309:   `(prog (restriction)
        !           310:         loop
        !           311:         (cond ((null ,predlist) (return t)) ; all predicates were true.
        !           312:               ; Otherwise, execute the next one.
        !           313:               ((cond ((reallitatom (setq restriction (pop ,predlist)))
        !           314:                       ; The name of a function to be applied.
        !           315:                       (apply* restriction (ncons ,val)))
        !           316:                      ; An s-expression predicate -- fill in and execute.
        !           317:                      ((dtpr restriction)
        !           318:                       (eval (fillin1 restriction ,val ,item ,defblock)))
        !           319:                      ; Otherwise, a value.
        !           320:                      ( t
        !           321:                       (selectq ,type
        !           322:                                (0 (or (let ((def (getdefinition ,val)))
        !           323:                                            (relatedhier restriction def))
        !           324:                                       (disguisedas ,val restriction)))
        !           325:                                (1 (disguisedas ,val restriction))
        !           326:                                (2 (\=& restriction ,val))
        !           327:                                (3 (eq restriction ,val))
        !           328:                                (otherwise
        !           329:                                 ; A better way needed ?? Never done????
        !           330:                                 (eq restriction (car ,val))))))
        !           331:                (go loop))
        !           332:               ; Otherwise this predicate failed, so we fail.
        !           333:               ( t (return nil)))))
        !           334: 
        !           335: ; Check two values for "equality".
        !           336: (defmacro expequalvalue (xval yval type)
        !           337:   `(selectq ,type
        !           338:            (0 (basicexpandedmatch ,xval ,yval))
        !           339:            (1 (eq ,xval ,yval))
        !           340:            (2 (\=& ,xval ,yval))
        !           341:            (3 (equal ,xval ,yval))
        !           342:            (otherwise
        !           343:             ; A better way needed!!!!!!!!!!!!!!!!!!!  something like:
        !           344:             ; (apply (function and)
        !           345:             ;    (mapcar (function expequalvalue) ,xval ,yval (strip ,type)))
        !           346:             t)))
        !           347: 
        !           348: ; Check to see if two slots whose number is passed are matchable,
        !           349: ; binding any variables and running any predicates.
        !           350: ; Assumes slotnum, item1, item2, def1, def2 already set and others declared
        !           351: ;    in main PROG.  The local PROG is necessary for slothooks processing.
        !           352: (dm expcompatible (none)
        !           353:   '(prog ()
        !           354:         ; *val and *var are both set by these calls.
        !           355:         ; *var are set to nil if no local, global, or adjunct variable.
        !           356:         (setq xval (getvarandvalue slotnum item1 'xvar))
        !           357:         (setq yval (getvarandvalue slotnum item2 'yvar))
        !           358:         ;
        !           359:         ; *ANY* => always match
        !           360:         (and (or (eq xvar *any*conscell*)
        !           361:                  (eq yvar *any*conscell*))
        !           362:              (return t))
        !           363:         ;
        !           364:         ; If both are unbound, return *matchunboundsresult* (initially nil).
        !           365:         (setq xvalunbound (punboundatomp xval))
        !           366:         (setq yvalunbound (punboundatomp yval))
        !           367:         (setq bothunbound (and xvalunbound yvalunbound))
        !           368:         (and bothunbound
        !           369:              (or *unifyunbounds*
        !           370:                  (return *matchunboundsresult*)))
        !           371:         ;
        !           372:         ; Get the slots' common type and individual predicates.
        !           373:         (setq slottype (getslottype slotnum def1))
        !           374:         (setq xpredlist (getpred slotnum item1))
        !           375:         (setq ypredlist (getpred slotnum item2))
        !           376:         (doslothooks2< '<match *runmatchhooks*)
        !           377:         ;
        !           378:         ; Otherwise we check to see if one of the slots can be
        !           379:         ;     bound to the other.
        !           380:         (cond (bothunbound ; Two unbound variables to be unified.
        !           381:                            (unifytwovars)
        !           382:                            (setq result t))
        !           383:               (xvalunbound ; Match x's variable against y's value.
        !           384:                (and (setq result
        !           385:                           (expconsistentvalue yval xpredlist slottype
        !           386:                                               item2 def2))
        !           387:                     (varset xvar yval)))
        !           388:               (yvalunbound ; Match y's variable against x's value.
        !           389:                (and (setq result
        !           390:                           (expconsistentvalue xval ypredlist slottype
        !           391:                                               item1 def1))
        !           392:                     (varset yvar xval)))
        !           393:               ( t  ; both are bound values -- check "equality".
        !           394:                    (and (setq result (expequalvalue xval yval slottype))
        !           395:                         ; and set the adjunct variables (if any)
        !           396:                         (progn (adjvarset xvar yval)
        !           397:                                (adjvarset yvar xval)))))
        !           398:         (doslothooks2> '>match *runmatchhooks*)
        !           399:         (return result)))
        !           400: 
        !           401: ; Match two structures slot by slot, WITHOUT unbinding variables first,
        !           402: ; but binding along the way.
        !           403: (de basicexpandedmatch (item1 item2)
        !           404:   (prog (newitem1 newitem2 result slottype xvar yvar xval yval def1 def2
        !           405:                  xvalunbound yvalunbound length
        !           406:                  newxval newyval xpredlist ypredlist xhooks yhooks
        !           407:                  newval bothunbound)
        !           408:        (setq def1 (getdefinition item1))
        !           409:        (setq def2 (getdefinition item2))
        !           410:        (setq length (min& (getstructlength def1)
        !           411:                           (getstructlength def2)))
        !           412:        (dobasehooks2< '<match *runmatchhooks*)
        !           413:        (cond ((eq item1 item2) (setq result t)) ; Same structure -> t.
        !           414:              ; Not even related hierarchically -> nil.
        !           415:              ((not (relatedhier def1 def2)) (setq result nil))
        !           416:              ; No slots -> t.
        !           417:              ((\=& 0 length) (setq result t))
        !           418:              ; Otherwise, compare slot by slot.
        !           419:              ( t (setq result
        !           420:                        (for slotnum 1 length
        !           421:                             (or (expcompatible)
        !           422:                                 (return nil))))))
        !           423:        (dobasehooks2> '>match *runmatchhooks*)
        !           424:        (return result)))
        !           425: 
        !           426: ; Match two structures slot by slot, unbinding variables first.
        !           427: (de standardexpandedmatch (item1 item2)
        !           428:   (prog (newitem1 newitem2 result slottype xvar yvar xval yval def1 def2
        !           429:                  xvalunbound yvalunbound length *globalsavestack*
        !           430:                  newxval newyval xpredlist ypredlist xhooks yhooks
        !           431:                  newval bothunbound *equivsavestack*)
        !           432:        (unbindvars item1)
        !           433:        (unbindvars item2)
        !           434:        (setq def1 (getdefinition item1))
        !           435:        (setq def2 (getdefinition item2))
        !           436:        (setq length (min& (getstructlength def1)
        !           437:                           (getstructlength def2)))
        !           438:        (dobasehooks2< '<match *runmatchhooks*)
        !           439:        (cond ((eq item1 item2) (setq result t)) ; Same structure -> t.
        !           440:              ; Not even related hierarchically -> nil.
        !           441:              ((not (relatedhier def1 def2)) (setq result nil))
        !           442:              ; No slots -> t.
        !           443:              ((\=& 0 length) (setq result t))
        !           444:              ; Otherwise, compare slot by slot.
        !           445:              ( t (setq result
        !           446:                        (for slotnum 1 length
        !           447:                             (or (expcompatible)
        !           448:                                 (return nil))))))
        !           449:        (dobasehooks2> '>match *runmatchhooks*)
        !           450:        (or result 
        !           451:            ; Clean up the variables because of the failure.
        !           452:            (progn (unbindvars item1)
        !           453:                   (unbindvars item2)
        !           454:                   (and *globalsavestack*
        !           455:                        (mapc (funl (var)
        !           456:                                    (set var (punbound)))
        !           457:                              *globalsavestack*))
        !           458:                   ; *equivsavestack is only non-nil when *unifyunbounds* is t.
        !           459:                   (and *equivsavestack*
        !           460:                        (mapc (funl (var)
        !           461:                                    (cond ((dtpr (car var))
        !           462:                                           (rplacd (car var) (cdr var)))
        !           463:                                          ( t (set (car var) (cdr var)))))
        !           464:                              *equivsavestack*))
        !           465:                   ))
        !           466:        (return result)))
        !           467: 
        !           468: (aliasdef 'expandedmatch 'standardexpandedmatch)
        !           469: 
        !           470: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
        !           471: ; Functions for testing for equality and other comparisons.
        !           472: 
        !           473: ; Check to see if two slots passed (with a type number) are EQUAL,
        !           474: ; NOT binding any variables OR checking any predicates.
        !           475: (dm slotequal (none)
        !           476:   '(prog ()
        !           477:         ; *val and *var are both set by these calls.
        !           478:         ; *var are set to nil if no local, global, or adjunct variable.
        !           479:         (setq xval (getvarandvalue slotnum item1 'xvar))
        !           480:         (setq yval (getvarandvalue slotnum item2 'yvar))
        !           481:         ;
        !           482:         ; If the slot of the first ITEM is unbound, fail
        !           483:         (and (punboundatomp xval)
        !           484:              (progn (msg t "Unbound variables not allowed in STREQUAL" t)
        !           485:                     (pearlbreak)))
        !           486:         ; If the slot of the second ITEM is unbound, fail
        !           487:         (and (punboundatomp yval)
        !           488:              (progn (msg t "Unbound variables not allowed in STREQUAL" t)
        !           489:                     (pearlbreak)))
        !           490:         ;
        !           491:         ; Get the slots' common type.
        !           492:         (setq slottype (getslottype slotnum def1))
        !           493:         (doslothooks2< '<strequal *runstrequalhooks*)
        !           494:         (setq result
        !           495:               (selectq slottype
        !           496:                        (0 (strequal xval yval))
        !           497:                        (1 (eq xval yval))
        !           498:                        (2 (\=& xval yval))
        !           499:                        (3 (equal xval yval))
        !           500:                        (otherwise
        !           501:                         ; A better way needed!!!!!!!!!!!!!!!!!!!
        !           502:                         (equal xval yval))))
        !           503:         (doslothooks2> '>strequal *runstrequalhooks*)
        !           504:         (return result)))
        !           505: 
        !           506: ; Test two structures for "EQUAL"ity slot by slot, without unbinding
        !           507: ; variables first, and NOT binding along the way.
        !           508: (de strequal (item1 item2)
        !           509:   (prog (newitem1 newitem2 result slottype xvar yvar xval yval
        !           510:                  def1 def2 length newxval newyval xhooks yhooks)
        !           511:        (setq def1 (getdefinition item1))
        !           512:        (setq def2 (getdefinition item2))
        !           513:        (setq length (getstructlength def1))
        !           514:        (dobasehooks2< '<strequal *runmatchhooks*)
        !           515:        (cond ((eq item1 item2) (setq result t)) ; Same structure -> t.
        !           516:              ; Not even same type -> nil.
        !           517:              ((neq def1 def2) (setq result nil))
        !           518:              ; No slots -> t.
        !           519:              ((\=& 0 length) (setq result t))
        !           520:              ; Otherwise, compare slot by slot.
        !           521:              ( t (setq result
        !           522:                        (for slotnum 1 length
        !           523:                             (or (slotequal)
        !           524:                                 (return nil))))))
        !           525:        (dobasehooks2> '>strequal *runmatchhooks*)
        !           526:        (return result)))
        !           527: 
        !           528: ; Check to see if ITEM1 is an expansion of ITEM2.
        !           529: (de isanexpanded (item1 item2)
        !           530:   (let ((defblock1 (getdefinition item1))
        !           531:        (defblock2 (getdefinition item2)))
        !           532:        (or (eq defblock1 defblock2)
        !           533:           (memq defblock1 (getexpansionlist defblock2)))))
        !           534: 
        !           535: ; Check to see if ITEM1 is (an expansion of) the base with name NAME.
        !           536: (de isa (item1 name)
        !           537:   (let ((defblock (getdefinition item1))
        !           538:        (typedef (eval (defatom name))))
        !           539:        (or (eq defblock typedef)
        !           540:           (memq defblock (getexpansionlist typedef)))))
        !           541: 
        !           542: ; Test item to see if it's a nilstruct.
        !           543: (de nullstruct (item)
        !           544:   (eq (getdefinition item)
        !           545:       (eval (defatom 'nilstruct))))
        !           546: 
        !           547: ; Test item to see if it's a nilsym.
        !           548: (de nullsym (item)
        !           549:   (eq item
        !           550:       (eval (symatom 'nilsym))))
        !           551: 
        !           552: (de memmatch (item list)
        !           553:   (cond ((null list) nil)
        !           554:        ((not (dtpr list)) nil)
        !           555:        ((match item (car list)) list)
        !           556:        ( t (memmatch item (cdr list)))))
        !           557: 
        !           558: (de memstrequal (item list)
        !           559:   (cond ((null list) nil)
        !           560:        ((not (dtpr list)) nil)
        !           561:        ((strequal item (car list)) list)
        !           562:        ( t (memstrequal item (cdr list)))))
        !           563: 
        !           564: ; vi: set lisp:

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.