|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.