|
|
1.1 ! root 1: .ND ! 2: .nr LL 75n ! 3: .nr LT 80n ! 4: .rm CF ! 5: .ds LH PEARL Documentation ! 6: .rm CH ! 7: .ds RH Page % ! 8: .po 1.00i ! 9: .ls 1 ! 10: .hy 14 ! 11: .RP ! 12: .TL ! 13: .LG ! 14: .LG ! 15: Using the PEARL AI Package ! 16: .sp 1 ! 17: .SM ! 18: \fR(\fIP\fRackage for \fIE\fRfficient \fIA\fRccess to \fIR\fRepresentations in \fIL\fRisp)* ! 19: .NL ! 20: .FS ! 21: * This research was sponsored in part by the Office of Naval Research ! 22: under contract N00014-80-C-0732 and the National Science Foundation ! 23: under grant MCS79-06543. ! 24: .FE ! 25: .AU ! 26: Michael Deering ! 27: Joseph Faletti ! 28: Robert Wilensky ! 29: .AI ! 30: Computer Science Division ! 31: Department of EECS ! 32: University of California, Berkeley ! 33: Berkeley, California 94720 ! 34: .sp 1 ! 35: February 1982 ! 36: .AB ! 37: This document is a tutorial and manual for PEARL ! 38: (Package for Efficient Access to Representations in Lisp), ! 39: an AI language developed with space and time efficiencies in mind. ! 40: PEARL provides a set of functions for creating hierarchically-defined ! 41: slot-filler representations and for efficiently and flexibly inserting ! 42: and fetching them from a forest of associative data bases. ! 43: In addition to providing the usual facilities such as demons and matching, ! 44: PEARL introduces stronger typing on slots and user-assisted hashing ! 45: mechanisms. ! 46: .AE ! 47: .NH 0 ! 48: Introduction ! 49: .PP ! 50: PEARL (Package for Efficient Access to Representations in Lisp) is ! 51: a set of functions for creating hierarchically-defined slot-filler ! 52: representations and for efficiently and flexibly inserting and fetching ! 53: them from a forest of data bases. ! 54: Its intended use is in AI programming and it has been used at Berkeley ! 55: in the development of several AI programs including PAM [7] and ! 56: PANDORA [8]. ! 57: .PP ! 58: PEARL has the expressive power found in other AI knowledge ! 59: representation languages, but is extremely time-space efficient. ! 60: For example, using a data base of 4000 entries, PEARL takes only ! 61: about 4.2 CPU milliseconds for an average unsuccessful query and ! 62: 7.3 CPU milliseconds of an average successful query on a PDP-10. ! 63: .PP ! 64: This document describes PEARL's use and is intended for the ! 65: beginning user. ! 66: (A description of the implementation of PEARL will be available ! 67: shortly.) ! 68: The best way to approach PEARL is to read this document up through ! 69: section 11 and then to take it to a terminal and reread it, typing ! 70: in the examples and observing their effects. ! 71: .PP ! 72: PEARL was implemented by Michael Deering and Joseph Faletti. ! 73: It was originally developed on a DEC PDP-10 under UCI Lisp ! 74: and was subsequently moved to a DEC VAX 11/780 under Franz Lisp ! 75: with help from Douglas Lanam and Margaret Butler. ! 76: Both PEARL and its documentation are still ! 77: being developed, improved, and debugged. ! 78: Any comments or suggestions will be appreciated. ! 79: Send them to Joe Faletti via Arpanet or Unix mail ! 80: (Kim\fB.\fRFaletti\fB@\fRBerkeley or ucbvax\fB!\fRkim\fB.\fRfaletti). ! 81: .bp ! 82: .DS ! 83: .sp 5 ! 84: .DE ! 85: .NH ! 86: Running PEARL ! 87: .PP ! 88: PEARL is implemented as a set of functions compiled and ! 89: loaded into Lisp. ! 90: Thus the full power of Lisp is available in addition to the added ! 91: power of PEARL. ! 92: .PP ! 93: Since PEARL runs under two different Lisps on two different machines, ! 94: there are a few differences between versions. ! 95: Most of these differences are in the method of starting PEARL up ! 96: and in the names of external files accessed by PEARL. ! 97: The two parts of this section describe how to start up PEARL either ! 98: under Franz Lisp or under UCI Lisp. ! 99: You need only read the section which is applicable to your Lisp. ! 100: .NH 2 ! 101: Under Franz Lisp ! 102: .PP ! 103: To access PEARL, simply run the core version of Lisp ! 104: containing PEARL. On Berkeley Unix, this is available by typing ! 105: the command: ! 106: .DS ! 107: % ~bair/bin/pearl ! 108: .DE ! 109: or, if ~bair/bin is in your search path, simply: ! 110: .DS ! 111: % pearl ! 112: .DE ! 113: During the startup process, PEARL will read in two ! 114: files, \fB.init.prl\fR and \fB.start.prl\fR, if they exist. ! 115: These files are designed for purposes similar to those ! 116: of \fI.lisprc\fR. ! 117: However, they split these functions into two groups. ! 118: In your \fI.init.prl\fR file you should include any ! 119: expressions which change the user-settable parameters to PEARL. ! 120: (For example, methods for setting the size of data bases, ! 121: the print function, and the prompt are described below.) ! 122: .PP ! 123: When you wish to have other files read in at startup time, ! 124: this usually needs to be done after PEARL's parameters are set. ! 125: PEARL is set up so that after the reading of \fI.init.prl\fR, it sets ! 126: any necessary parameters which you have not set in your .init.prl ! 127: and then reads in the file \fI.start.prl\fR if you have one. ! 128: This is where any processing which requires the ! 129: attention of PEARL (such as the existence of its data bases) ! 130: should be placed. ! 131: Thus \fI.init.prl\fR is primarily for initializing PEARL ! 132: and \fI.start.prl\fR is for starting up your use of PEARL. ! 133: \fBNote:\fR unlike most Unix programs which look for startup files ! 134: only in your home directory, thereby limitting you to only one ! 135: environment for each program, PEARL looks for each file first in ! 136: the current directory and if there is none, then it looks in your ! 137: home directory. ! 138: This allows you to tailor invocations of PEARL to the kind of work ! 139: you do in a particular directory. ! 140: .bp ! 141: .PP ! 142: After reading in these two files, PEARL will then place you in a ! 143: modified prompt-read-eval-print loop, with a default prompt of "PEARL> ". ! 144: This can be changed by setting the special variable ! 145: \fB*pearlprompt*\fR to the desired value. ! 146: If you want the standard Lisp prompt "-> " to be used by PEARL, ! 147: you must set \fI*pearlprompt*\fR to \fInil\fR in your \fI.init.prl\fR ! 148: and PEARL will do the right thing. ! 149: .PP ! 150: The primary feature of the PEARL prompt-read-eval-print loop is that ! 151: it uses a different print function. ! 152: The default function is ! 153: .DS ! 154: (lambda (*printval*) ! 155: (valprint *printval* 4) ) ! 156: .DE ! 157: but this can be changed to whatever you desire by giving ! 158: a new function definition to \fBpearlprintfn\fR. ! 159: The PEARL prompt-read-eval-print loop also contains a number of ! 160: features to improve upon the standard Lisp top level. ! 161: These include a history mechanism and are described in chapter 25. ! 162: .PP ! 163: There are quite a few functions from UCI Lisp which have been added ! 164: to PEARL to make it easier to move programs to Franz Lisp. ! 165: A list of these with brief documentation of differences is ! 166: included in an appendix. ! 167: .NH 2 ! 168: Under UCI Lisp ! 169: .PP ! 170: To access PEARL, simply run the core version of Lisp containing PEARL. ! 171: On the Berkeley KL-10 system, this is available by typing the system call ! 172: .DS ! 173: RU PEARL[5500,504,PEARL] ! 174: .DE ! 175: During the startup process, PEARL will read in two files, ! 176: INIT.PRL and START.PRL, if they exist. ! 177: The file INIT.PRL is designed for purposes similar to those ! 178: of INIT.LSP. ! 179: In this file you should include any expressions which ! 180: change the user-settable parameters to PEARL. ! 181: (For example, methods for setting the size of data bases, ! 182: the print function, and the prompt are described below.) ! 183: If you wish to use the REALLOC function to ! 184: enlarge your memory space, this call should be the ! 185: last call in your INIT.PRL file. ! 186: .PP ! 187: When you wish to have other files read in at startup ! 188: time, this usually needs to be done after the REALLOC. ! 189: The common kludge with UCI Lisp to solve this is to define ! 190: an INITFN (initialization function) which does this and then ! 191: to reset the INITFN to \fInil\fR which returns you to the ! 192: standard Lisp prompt-read-eval-print loop. ! 193: However, PEARL sets the INITFN for its own purposes so ! 194: that this common "solution" will not work. ! 195: Instead, PEARL is set up so that after the reading of INIT.PRL, ! 196: it sets any necessary parameters which you have not set in your ! 197: INIT.PRL and then reads in the file START.PRL if you have one. ! 198: This is where any processing which requires the ! 199: attention of PEARL should be placed. ! 200: Thus INIT.PRL is primarily for initializing PEARL and ! 201: START.PRL is for starting up your use of PEARL. ! 202: .PP ! 203: After reading in these two files, PEARL will then place you in a ! 204: modified prompt-read-eval-print loop, with a default prompt of "PEARL> ". ! 205: The ">" portion is the (modified) Lisp prompt which is printed ! 206: whenever \fIread\fR is invoked and can be changed ! 207: with the UCI Lisp function INITPROMPT. ! 208: The "PEARL" is PEARL's addition and can be set by ! 209: setting the special variable \fB*pearlprompt*\fR ! 210: to the desired value. ! 211: If you do not want any prompt added by PEARL other than the Lisp ! 212: prompt you must set \fI*pearlprompt*\fR to \fInil\fR in your ! 213: INIT.PRL and PEARL will do the right thing. ! 214: .PP ! 215: The main feature of the PEARL prompt-read-eval-print loop is ! 216: that it uses a different print function. ! 217: The default function is ! 218: .DS ! 219: (lambda (*printval*) ! 220: (valprint *printval* 4) ) ! 221: .DE ! 222: but this can be changed to whatever you desire by giving the ! 223: function \fBpearlprintfn\fR a new definition. ! 224: Note that \fIdskin\fR and the break package have been ! 225: changed slightly to also use of this print function. ! 226: Also, although the functions names and examples below are in ! 227: lower case, PEARL in UCI Lisp expects them all in upper ! 228: case, just as the rest of the UCI Lisp functions. ! 229: .NH ! 230: Creating Simple Objects. ! 231: .PP ! 232: PEARL allows four basic types of objects. ! 233: The first two are integers and arbitrary Lisp objects ! 234: and are created in the usual Lisp fashion. ! 235: The second two are structured types provided by PEARL, ! 236: and are stored in an internal form as blocks of memory. ! 237: These latter types are called \fBsymbols\fR and \fBstructures\fR. ! 238: .NH 2 ! 239: Defining Symbols ! 240: .PP ! 241: \fBSymbol\fRs are PEARL's internal atomic symbols. ! 242: Semantically they are like Lisp atoms, but are represented ! 243: and used differently to make PEARL more efficient. ! 244: Before they are used, symbols must ! 245: be declared (and thus defined to PEARL) by a call to the function ! 246: \fBsymbol\fR, which takes as arguments any number of atoms ! 247: whose names will be used to create symbols. ! 248: For example, ! 249: .DS ! 250: (symbol John) ! 251: .DE ! 252: creates one symbol called John and ! 253: .DS ! 254: (symbol Bob Carol Ted Alice Home ! 255: Office School Healthy NewYork) ! 256: .DE ! 257: creates several symbols at one time. ! 258: \fISymbol\fR is an nlambda (fexpr) and returns ! 259: a list containing the names of the symbols it created. ! 260: A one-argument lambda (expr) version is available as \fBsymbole\fR. ! 261: .PP ! 262: There are two ways to get at the actual (unique) symbol: ! 263: you can use the function \fBgetsymbol\fR or you can evaluate the ! 264: atom whose name is built out of the symbol name with the characters ! 265: \fBs:\fR on the front. ! 266: The function \fBsymatom\fR will build this atom for you when ! 267: given a symbol name. ! 268: For example, to set B to the symbol Bob use any of: ! 269: .DS ! 270: (setq B (getsymbol 'Bob) ) ! 271: (setq B s:Bob) ! 272: (setq B (eval (symatom 'Bob)) ! 273: .DE ! 274: .LP ! 275: Given an internal symbol, you can find out its print name by passing ! 276: it to the function \fBpname\fR (which also will return the print name ! 277: of other types of PEARL objects). ! 278: .NH 2 ! 279: Defining Structures ! 280: .PP ! 281: \fBStructure\fRs in PEARL provide the ability to define and manipulate ! 282: logical groupings of heterogeneous data and are essentially objects ! 283: with slots and slot fillers. ! 284: As such, they act more like "records" ! 285: in Pascal or "structures" in C than Lisp lists. ! 286: In reality they are more than both, but for the moment the reader ! 287: should keep records in mind. ! 288: .PP ! 289: Just as you must define the form ! 290: of a record in Pascal before defining the value of a variable whose ! 291: type is that kind of record, it is necessary to define each particular ! 292: form of structure you wish to use in PEARL before creating an ! 293: object with that form. ! 294: PEARL provides one function called \fBcreate\fR which ! 295: is used both to define kinds of structures and to ! 296: create individual instances of these structures. ! 297: (One function is provided for both because a special individual ! 298: is created as a side effect of each definition. ! 299: More on this is provided in section 7 on defaults.) ! 300: The first argument to \fIcreate\fR distinguishes ! 301: between a call which defines and one which creates an individual. ! 302: There are three kinds of defining calls (\fIbase\fR, \fIexpanded\fR ! 303: and \fIfunction\fR) and two kinds of instance-creating calls ! 304: (\fIindividual\fR, \fIpattern\fR) to \fIcreate\fR. ! 305: Only one of each (\fIbase\fR and \fIindividual\fR) is described ! 306: in this section. ! 307: The rest are left for later. ! 308: .PP ! 309: To start off with an example, let us suppose that you wish to represent ! 310: the conceptual act "PTrans" from the Conceptual Dependency (CD) notation ! 311: of Schank. ! 312: (The examples in this documentation assume a passing ! 313: familiarity with CD but lack of this should not hurt you too badly ! 314: and PEARL itself does not restrict you in any way to CD. ! 315: PTrans stands for Physical Transfer which has four "cases": actor doing ! 316: the transfer, object being transferred, original location and final ! 317: location.) ! 318: First we must define the form which PTrans structures will take. ! 319: In C this would be a type definition for the type PTrans as ! 320: follows (assuming a system-provided definition of the type \fIsymbol\fR): ! 321: .DS ! 322: struct PTrans { ! 323: symbol Actor; ! 324: symbol Object; ! 325: symbol From; ! 326: symbol To; ! 327: }; ! 328: .DE ! 329: In Pascal this would be ! 330: .DS ! 331: type PTrans = record ! 332: Actor : symbol; ! 333: Object : symbol; ! 334: From : symbol; ! 335: To : symbol ! 336: end; ! 337: .DE ! 338: .LP ! 339: In PEARL, ! 340: .DS ! 341: (create base PTrans ! 342: (Actor symbol) ! 343: (Object symbol) ! 344: (From symbol) ! 345: (To symbol) ) ! 346: .DE ! 347: does the job. ! 348: Note first of all that in order to define a new form ! 349: of structure, the first argument to \fIcreate\fR must be \fBbase\fR. ! 350: Note also that the second argument to \fIcreate\fR is the name of the ! 351: structure form to be created. ! 352: Following this is a list of (<slotname> <type>) pairs. ! 353: Structures are currently allowed to have up to 32 slots ! 354: in Franz PEARL or 18 in UCI Lisp PEARL as long as all slots ! 355: within a particular structure have mutually distinct names. ! 356: Different structures may have slots of the same name. ! 357: Thus in applications of PEARL to CD twenty different structure ! 358: types might all have an Actor slot. ! 359: .PP ! 360: Five types are allowed for slots: \fBsymbol\fR, \fBstruct\fR, ! 361: \fBint\fR, \fBlisp\fR, and \fBsetof <type>\fR. ! 362: \fISymbol\fR and \fIstruct\fR are the types just described. ! 363: \fIInt\fR is a normal Lisp integer value. ! 364: The type \fIlisp\fR allows arbitrary \fBnon-atomic\fR Lisp values. ! 365: Finally, \fIsetof <type>\fR allows you to define sets consisting ! 366: of all symbols (\fIsetof symbol\fR) or all structures (\fIsetof struct\fR) ! 367: and can be done recursively (\fIsetof setof struct\fR). ! 368: .NH ! 369: Creating Individual Instances of Defined Structures ! 370: .PP ! 371: Once you have defined a specific form of structure like PTrans, you ! 372: can create an individual PTrans using \fBindividual\fR as the first ! 373: argument to \fIcreate\fR and the name of the base structure you want ! 374: an individual instance of as the second argument. ! 375: The rest of the arguments are (<slotname> <value>) pairs in which ! 376: the <value> must be of the type that the slot was declared to be. ! 377: The slots may be listed in any order and need not be in the same ! 378: order as defined. ! 379: For example, to create an instance of John going home ! 380: from the office (i.e., John PTransing himself from the office to ! 381: home) you would use this call to \fIcreate\fR: ! 382: .DS ! 383: (create individual PTrans ! 384: (Actor John) ! 385: (Object John) ! 386: (From Office) ! 387: (To Home) ) ! 388: .DE ! 389: \fICreate\fR will return an object of type PTrans, with the slots filled ! 390: in as indicated. ! 391: The object returned has been created and stored as ! 392: a \fIhunk\fR of memory in Franz Lisp or a block of memory in Binary ! 393: Program Space in the UCI Lisp (rather than Free Storage where most ! 394: Lisp objects are stored). ! 395: Since you are using the PEARL prompt-read-eval-print loop, ! 396: the object returned by \fIcreate\fR will be printed in an external list ! 397: form, something like the above. ! 398: However, if you print a structure using the standard Lisp print ! 399: functions (as for example some break packages will do), it will ! 400: be printed by Franz Lisp in the normal way it prints hunks. ! 401: (Warning: Since the structure actually contains a circular ! 402: reference to another hunk, this will cause problems with programs ! 403: which do not set \fIprinlevel\fR in Franz Lisp so general packages which ! 404: you wish to add to PEARL should be modified to use some PEARL ! 405: print function.) ! 406: With UCI Lisp's normal print function, it will show up as an ! 407: address in Binary Program Space, looking something like "#31534". ! 408: .PP ! 409: As with any Lisp function that returns an object, ! 410: we must store (a pointer to) the result of \fIcreate\fR somewhere ! 411: (for example, in the atom Trip) ! 412: if we wish to reference it in the future. ! 413: Otherwise, the created object will be inaccessible. ! 414: (This point is clearer if you consider ! 415: that Pascal would insist that you do something with the result ! 416: of the function call, although PEARL and many languages like Lisp ! 417: and C in which every subprogram is a value-returning function allow ! 418: you to construct a value and then blithely go on your way without ! 419: using it.) ! 420: .PP ! 421: To store (a pointer to) the instance returned by \fIcreate\fR in ! 422: the atom Trip, you could do the following: ! 423: .DS ! 424: (setq Trip (create individual PTrans ! 425: (Actor John) ! 426: (Object John) ! 427: (From Office) ! 428: (To Home) ) ) ! 429: .DE ! 430: Since this is a common operation, \fIcreate\fR provides the option of ! 431: having (a pointer to) the newly created instance automatically ! 432: assigned to a Lisp atom. ! 433: This is accomplished by including the ! 434: name of the atom as the third argument to \fIcreate\fR. ! 435: If the third argument to \fIcreate\fR is an atom rather than a ! 436: (<slotname> <value>) pair, \fIcreate\fR stores the new ! 437: object in this atom. ! 438: Thus the effect of the previous example can be achieved by: ! 439: .DS ! 440: (create individual PTrans Trip ! 441: (Actor John) ! 442: (Object John) ! 443: (From Office) ! 444: (To Home) ) ! 445: .DE ! 446: (In addition, when \fIcreate base PTrans\fR is used, an assignment is ! 447: automatically made to the atom PTrans, thus making the defaultinstance ! 448: of a structure easily available. ! 449: To preserve this, calls to create of the form ! 450: \fI(create individual PTrans PTrans ...)\fR are disallowed (that ! 451: is, ignored). ! 452: In case you should actually wish to use the atom PTrans for other ! 453: purposes, evaluating the atom built by prepending \fBi:\fR onto ! 454: the structure name will give you the default instance of a base ! 455: structure and evaluating the atom built by prepending \fBd:\fR ! 456: will give you the actual definition. ! 457: Changing the value of these atoms is \fBvery dangerous\fR. ! 458: Given the name of a structure, the functions \fBinstatom\fR and ! 459: \fBdefatom\fR will construct these atoms for you. ! 460: For more information about the item assigned to \fIPTrans\fR ! 461: and \fIi:PTrans\fR, see the section 7 on defaults.) ! 462: .PP ! 463: PTrans is an example of a structure whose slots are all ! 464: of the type \fIsymbol\fR. ! 465: A more complex example is that of MTrans (Mental Transfer: ! 466: an actor transfering a concept (Mental Object) from one place ! 467: to another (usually from himself to someone else). ! 468: The MObject slot is some other act and so would be of ! 469: type \fIstruct\fR resulting in the following definition: ! 470: .DS ! 471: (create base MTrans ! 472: (Actor symbol) ! 473: (MObject struct) ! 474: (From symbol) ! 475: (To symbol) ) ! 476: .DE ! 477: A sample instance of MTrans is \fIJohn told Carol that he ! 478: was going home from the office\fR and would be created with ! 479: .DS ! 480: (create individual MTrans InformLeaving ! 481: (Actor John) ! 482: (MObject (PTrans Leaving ! 483: (Actor John) ! 484: (Object John) ! 485: (From Office) ! 486: (To Home) ) ) ! 487: (From John) ! 488: (To Carol) ) ! 489: .DE ! 490: .LP ! 491: Note that to fill a slot of type \fIstruct\fR (or \fIsetof struct\fR) ! 492: with a structure value within a ! 493: \fIcreate\fR one just embeds the appropriate arguments for a recursive ! 494: call to \fIcreate\fR, \fIexcept\fR that you \fBmay\fR leave out ! 495: \fIindividual\fR since it would just be repetitive. ! 496: If you should want to create an object of another type within ! 497: an individual or base structure, you must include the alternative ! 498: argument (\fIindividual\fR, \fIbase\fR, \fIpattern\fR, \fIexpanded\fR, ! 499: or \fIfunction\fR) before the type name. ! 500: This is particularly useful when you wish to create a pattern ! 501: with an individual instance in one of its slots. ! 502: .PP ! 503: The optional third argument of an atom name for storing ! 504: in may be included at each level if you wish. ! 505: In the example above, \fIcreate\fR actually will create two ! 506: new instances, an MTrans which will be stored in InformLeaving, ! 507: and a PTrans which is pointed to by the MObject slot of the ! 508: MTrans and is also pointed to by Leaving. ! 509: In this case, neither InformLeaving nor Leaving is required. ! 510: If Leaving were left out, then one would still have a way ! 511: to get at the PTrans via the MObject slot of the MTrans that ! 512: InformLeaving points to. ! 513: However, if InformLeaving were left out and the ! 514: result of the call to \fIcreate\fR were not stored any other way, ! 515: there is one more way that the MTrans would be accessible. ! 516: The value of the most recently created object is always ! 517: stored in the special variable \fB*lastcreated*\fR by ! 518: \fIcreate\fR so the value of the MTrans would remain ! 519: accessible until the next call to \fIcreate\fR. ! 520: Note that if there are recursive calls to \fIcreate\fR during this ! 521: time in order to process structure values in slots, the value of ! 522: \fI*lastcreated*\fR is continually changing to the most recent ! 523: one and the setting of \fI*lastcreated*\fR is the last thing ! 524: \fIcreate\fR does. ! 525: There is also a special variable called \fB*currenttopcreated*\fR ! 526: which is set by \fIcreate\fR at the top level call as soon as ! 527: the space for an individual or default instance is allocated. ! 528: Since it is sometimes handy for a piece of user code which ! 529: runs during \fIcreate\fR (see the sections on !, $, predicates and ! 530: demons) to be able to access the topmost object, ! 531: \fI*currenttopcreated*\fR is sometimes quite useful. ! 532: .PP ! 533: As in C and Pascal, one can embed to any level. ! 534: \fICreate\fR does not have facilities ! 535: for more complex networks of structures, as there are other ! 536: functions in PEARL which allow their construction. ! 537: \fICreate\fR is mainly used to create objects for other ! 538: functions to manipulate. ! 539: .NH ! 540: Accessing Slots of Structures ! 541: .PP ! 542: In C and Pascal one can access the slots of a record or structure by ! 543: using dot notation. ! 544: For example, in Pascal the To slot of the MObject slot of ! 545: the MTrans pointed to by InformLeaving would be accessed ! 546: with the expression InformLeaving.MObject.To (or perhaps ! 547: more accurately InformLeaving\fB^\fR.MObject\fB^\fR.To ! 548: since slots really contain pointers to objects). ! 549: In Pascal and C, there are essentially only two things that ! 550: one can do to a slot of a record or structure: access it ! 551: (get its value) and assign to it (give it a new value). ! 552: In PEARL the macro \fBpath\fR provides ! 553: a large number of ways to access and/or change the values ! 554: in slots of individual structures. ! 555: (In the UCI Lisp version this is called \fIppath\fR ! 556: to distinguish it from the system function \fIpath\fR.) ! 557: A call to \fIpath\fR is of the following general form: ! 558: .DS ! 559: (path <Selector> <Structure> <Slot-Name-or-List> <Value>) ! 560: .DE ! 561: <Selector> determines the action to be performed ! 562: and is not evaluated. ! 563: <Structure> should evaluate to the object in which the slot ! 564: occurs (or in whose depths the object occurs). ! 565: <Slot-Name-or-List> should evaluate either to the atom name of the ! 566: slot desired in <Structure> or a list of the slot names ! 567: which one must follow to get down to the slot. ! 568: <Value> (which is only needed when it makes sense) ! 569: should evaluate to the value to be put into the slot ! 570: (or otherwise used in performing the function). ! 571: At this point, we will only describe the two <Selector>s ! 572: corresponding to accessing and assigning. ! 573: These are \fBget\fR and \fBput\fR respectively. ! 574: Thus to access the value of a slot, you would use ! 575: .DS ! 576: (path get <Structure> <Slot-Name-or-List>) ! 577: .DE ! 578: (No value is needed; ! 579: the purpose of this call is to get the value.) ! 580: To assign a value to a slot, you would use ! 581: .DS ! 582: (path put <Structure> <Slot-Name-or-List> <Value>) ! 583: .DE ! 584: For example, to access the Actor slot of the PTrans in Trip, either of ! 585: the following is appropriate: ! 586: .DS ! 587: (path get Trip 'Actor) ! 588: (path get Trip '(Actor) ) ! 589: .DE ! 590: This is essentially equivalent to a reference to ! 591: \fITrip\fB^\fI.Actor\fR in Pascal. ! 592: .PP ! 593: To access a slot within a structure in a slot of type \fIstruct\fR, ! 594: add the slot names to the <Slot-Name-or-List>, just as we access ! 595: embedded fields within fields in Pascal by adding more slots ! 596: to the accessing expression. ! 597: For example, to access the place ! 598: John told Carol he was going in our MTrans example above, we ! 599: want the To slot of the MObject slot of the MTrans stored in ! 600: InformLeaving: ! 601: .DS ! 602: (path get InformLeaving '(MObject To) ) ! 603: .DE ! 604: This is essentially equivalent to a reference to ! 605: \fIInformLeaving\fB^\fI.MObject\fB^\fI.To\fR in Pascal. ! 606: PEARL will check each slot reference, and will indicate if ! 607: a slot name is not found (perhaps due to a misspelling or an ! 608: unbound slot). ! 609: .PP ! 610: Similarly, to change the Actor of our PTrans in Trip to be Bob: ! 611: .DS ! 612: (path put Trip '(Actor) (getsymbol 'Bob) ) ! 613: .DE ! 614: and to change the To slot within the MObject of the MTrans: ! 615: .DS ! 616: (path put InformLeaving '(MObject To) (getsymbol 'School) ) ! 617: .DE ! 618: which is essentially equivalent to assigning a value to ! 619: \fIInformLeaving\fB^\fI.MObject\fB^\fI.To\fR in Pascal. ! 620: Note that the order of the arguments to these functions is in ! 621: \fBnot like\fR the argument ordering of \fIputprop\fR. ! 622: .PP ! 623: \fBCAUTION\fR: ! 624: \fIPath\fR does not check values to ensure that they are of the ! 625: correct type before putting them in a slot. ! 626: Also, a change in a structure with \fIpath\fR ! 627: does not cause it to be reinserted in the data base ! 628: (see the next section). ! 629: Thus, before changing a structure, one should remove it from ! 630: the data base and then reinsert it after the change. ! 631: .PP ! 632: These functions were gathered under the macro \fIpath\fR because of ! 633: their similarity. ! 634: However, if you prefer to have the action being performed lead off the ! 635: function name in keeping with \fIputprop\fR, \fIget\fR, \fIputd\fR, ! 636: \fIgetd\fR, etc., these two functions are also available as ! 637: \fBputpath\fR and \fBgetpath\fR with similar names also provided for ! 638: all the other forms of path described below. ! 639: Thus the name "path" may be tacked onto the end of one of the action ! 640: selectors to \fIpath\fR but the rest of the arguments to these ! 641: functions remain the same. ! 642: .PP ! 643: There are quite a few other operations which are allowed through ! 644: \fIpath\fR which you will not need or understand until you have read ! 645: the rest of this documentation. ! 646: We describe them here for completeness but suggest you skip ! 647: to the next section during your first reading. ! 648: If you feel there is one missing, feel free to suggest it since ! 649: they are easy to add. ! 650: .IP ! 651: \fIpath \fBclear\fR or \fBclearpath\fR -- sets the selected path to ! 652: the standard default value for its type (\fInilsym\fR, ! 653: \fInilstruct\fR, zero or \fInil\fR). ! 654: Note that this is only the standard default and does ! 655: not inherit a default from above. ! 656: See section 7 for more on default values. ! 657: .IP ! 658: \fIpath \fBaddset\fR or \fBaddsetpath\fR -- add the specified value to ! 659: a slot of type \fIsetof\fR. ! 660: .IP ! 661: \fIpath \fBdelset\fR or \fBdelsetpath\fR -- delete the specified value ! 662: from a slot of type \fIsetof\fR. ! 663: .IP ! 664: \fIpath \fBgetpred\fR or \fBgetpredpath\fR -- get the list of ! 665: predicates on the slot. ! 666: .IP ! 667: \fIpath \fBaddpred\fR or \fBaddpredpath\fR -- add the specified ! 668: predicate to the predicates on the slot. ! 669: .IP ! 670: \fIpath \fBdelpred\fR or \fBdelpredpath\fR -- delete the specified ! 671: predicate from the predicates on the slot. ! 672: .IP ! 673: \fIpath \fBgethook\fR or \fBgethookpath\fR -- get the assoc-list of ! 674: hooks (demons) on the slot. ! 675: .IP ! 676: \fIpath \fBapply\fR or \fBapplypath\fR -- arguments to this function ! 677: are a <Function-or-Lambda-Body>, followed by the <Structure>, and ! 678: <Slot-Name-or-List>. ! 679: The <Function-or-Lambda-Body> is applied to the value of the slot. ! 680: (In the UCI Lisp version, \fIapply#\fR is used so that macros will work. ! 681: In the Franz Lisp version, a PEARL-supplied version of \fIapply\fR ! 682: called \fBapply*\fR is used which also handles macros "right".) ! 683: .PP ! 684: (Skip this next paragraph until you have read about hashing and ! 685: the data bases.) ! 686: The method of processing the path in \fBpath\fR functions allows a ! 687: form of indirection through the data base that is sometimes ! 688: helpful when you use symbols in slots as unique pointers to ! 689: other structures. ! 690: Suppose you had the following definitions: ! 691: .DS ! 692: (create base Person ! 693: (* Identity symbol) ! 694: ( Name lisp) ) ! 695: .DE ! 696: .DS ! 697: (dbcreate individual Person ! 698: (Identity John) ! 699: (Name (John Zappa) ) ! 700: .DE ! 701: and you want to ask \fI"what is the Name of the Person in the ! 702: Actor slot of Trip (above)"\fR which you might normally write as: ! 703: .DS ! 704: (getpath (fetch (create pattern Person ! 705: (Identity ! (getpath Trip 'Actor) ) ) ) ! 706: 'Name) ! 707: .DE ! 708: This is very hard to understand. ! 709: A shorthand for this is the following: ! 710: .DS ! 711: (getpath Trip '(Actor Person Name) ) ! 712: .DE ! 713: which behaves like this: when \fIpath\fR gets to the symbol in ! 714: the Actor slot of Trip, it notices that there is still more path ! 715: to follow. ! 716: It then interprets the next symbol in the path as the ! 717: name of a type and does a quick equivalent of fetch of a Person ! 718: with its first slot set to John. ! 719: It then continues to follow the path specified in this new ! 720: structure, finishing up with the value of the Name slot ! 721: of the structure. ! 722: (Note that this depends on Person structures being hashed by the ! 723: relevant slot and will fail otherwise. ! 724: Also note that the tendency of most users of PEARL has been away ! 725: from the use of symbols as indirections to larger structures and ! 726: toward actually putting the larger structure in the slot. ! 727: In this case this would imply putting the Person structure in the ! 728: Actor slot of PTrans and eliminate the need for "Person" in the ! 729: path list.) ! 730: .NH ! 731: Storing In and Retrieving From the Data Base -- The Simplest Way ! 732: .PP ! 733: So far we have shown how to create structures and have treated ! 734: them pretty much like C structures or Pascal records. ! 735: However, PEARL's most important departures from these languages ! 736: involve its data base facilities. ! 737: PEARL's data base can be thought of as one large ! 738: bag into which any structure can be placed. ! 739: The data base can hold hundreds, even thousands of separate objects. ! 740: There are two basic operations that can be performed upon ! 741: the data base, inserting with the function \fIinsertdb\fR ! 742: and retrieving with a combination of the functions ! 743: \fIfetch\fR and \fInextitem\fR. ! 744: .NH 2 ! 745: Storing In the Data Base: \fIInsertdb\fR and \fIRemovedb\fR ! 746: .PP ! 747: While the simplest forms of these actions are ! 748: relatively straightforward, the power and efficiency of PEARL ! 749: derives from the nuances and controls available with these ! 750: functions which take up much of the rest of this document. ! 751: Much of the power develops from knowledge provided by the user about ! 752: how each kind of structure is likely to be retrieved (and therefore ! 753: how it should be stored). ! 754: Thus, the data base benefits from knowing as much as possible ! 755: in advance about the objects that will be placed within it. ! 756: This information is provided by using a large variety ! 757: of extra flags during definition calls to \fIcreate\fR. ! 758: It is used by \fIinsertdb\fR to hash objects into a specific ! 759: \fIhash bucket\fR in the data base, by \fIfetch\fR to retrieve the ! 760: correct hash bucket from the data base, and by \fInextitem\fR ! 761: to filter the desired objects from this bucket. ! 762: .PP ! 763: PEARL allows the construction and use of multiple data bases which are ! 764: described in detail later. ! 765: Without exerting any effort, a data base is automatically created ! 766: called \fB*maindb*\fR and pointed to by the special variable \fB*db*\fR. ! 767: In general, all PEARL functions which deal with a data base have an ! 768: optional last argument which specifies which data base to use. ! 769: If it is missing, then the default data base pointed to by ! 770: \fI*db*\fR is assumed. ! 771: Thus you can change the default data base ! 772: simply by assigning the desired data base to \fI*db*\fR. ! 773: For simplicity, this optional data base argument is not ! 774: mentioned in the following discussion. ! 775: .PP ! 776: The function \fBinsertdb\fR takes a single structure argument and ! 777: inserts it into the data base. ! 778: In its simplest form \fIinsertdb\fR requires no user flags on the ! 779: definitions of structures. ! 780: In this case, \fIinsertdb\fR simply hashes on the type of the ! 781: structure regardless of its specific contents so that each ! 782: entry ends up in a bucket with all other entries of that type. ! 783: For example, to insert into the data base the PTrans which was ! 784: saved in the Lisp variable Trip above, you simply provide it as an ! 785: argument to \fIinsertdb\fR: ! 786: .DS ! 787: (insertdb Trip) ! 788: .DE ! 789: We could also put the PTrans (saved in Leaving whose To slot ! 790: was changed to School) which was the MObject of the MTrans above ! 791: in the data base with: ! 792: .DS ! 793: (insertdb Leaving) ! 794: .DE ! 795: Since no information has been provided by the user about how to ! 796: efficiently distinguish PTranses in general, these two will be stored ! 797: in the same bucket (as will all PTranses). ! 798: When inserting an item into a bucket, \fIinsertdb\fR will check ! 799: to ensure that this specific item is not already in that bucket ! 800: (using \fIeq\fR) and will only insert it if ! 801: it is not already there, thus avoiding duplicates. ! 802: .PP ! 803: The function \fBremovedb\fR takes a single structure argument ! 804: and removes it from any place in the data base where it has been ! 805: put using \fIeq\fR to determine equality. ! 806: .PP ! 807: Since one often wants to create an individual and then insert it into ! 808: the data base, there is a macro \fBdbcreate\fR provided whose ! 809: arguments are precisely like \fIcreate\fR. ! 810: Thus, \fI(dbcreate individual PTrans ....)\fR expands into ! 811: \fI(insertdb (create individual PTrans ....) )\fR. ! 812: .NH 2 ! 813: Retrieving Hash Buckets From the Data Base: Fetch ! 814: .PP ! 815: .hy next-item ! 816: The simplest case of fetching from the data base is ! 817: equivalent to asking if a particular, completely defined ! 818: object is in the data base. ! 819: This is performed by a combination of the functions ! 820: fIfetch\fR and \fInextitem\fR. ! 821: The first step is to retrieve the hash bucket(s) for the object. ! 822: For example, to determine whether the object stored in Trip is in the ! 823: data base, the first step is to call the function \fBfetch\fR and ! 824: store what it returns (the form of what is returned is described ! 825: below): ! 826: .DS ! 827: (setq PotentialTrips (fetch Trip) ) ! 828: .DE ! 829: .PP ! 830: The function \fIfetch\fR takes a single structure argument which is ! 831: called the \fBpattern\fR. ! 832: What \fIfetch\fR returns includes this pattern and the hash bucket(s) ! 833: from the data base which contain those structures which are ! 834: most likely to "match". ! 835: The rules of "matching" are fairly complex and are described in ! 836: detail in section 20, but for the moment it is enough to know that ! 837: two structures match if their respective slots contain equal values. ! 838: Thus matching is closer to Lisp's \fIequal\fR than to \fIeq\fR. ! 839: .NH 2 ! 840: Accessing the Results of a Fetch: Nextitem. ! 841: .PP ! 842: Conceptually, what \fIfetch\fR returns is a restricted type of \fBstream\fR. ! 843: A stream is a "virtual" list, whose items are computed only as needed. ! 844: When a fetch from the data base is performed, the pattern provided ! 845: is only used to construct a stream containing that pattern and the ! 846: appropriate hash bucket from the data base; ! 847: no matching (comparing) ! 848: between the pattern and objects in the data base occurs. ! 849: Thus the stream contains pointers to all data base items in the ! 850: same hash bucket, regardless of their likelihood of matching the pattern. ! 851: Therefore, the \fIstream\fR or "virtual list" returned by \fIfetch\fR is ! 852: in fact bigger than the list of actual items which match. ! 853: (For this reason, the default PEARL print function only prints how ! 854: many potential items are in the stream.) ! 855: .PP ! 856: For our purposes, you should regard the object that \fIfetch\fR ! 857: returns to be a funny sort of black box, whose only use is as ! 858: an argument to the function \fBnextitem\fR. ! 859: \fINextitem\fR will compute the next element to be removed from the stream. ! 860: When elements are extracted from the stream with the function \fInextitem\fR, ! 861: the pattern is "matched" against successive items from the hash bucket ! 862: until one matches (and is returned) or until the potential items run out ! 863: (and \fInil\fR is returned). ! 864: .PP ! 865: \fINextitem\fR is very much like the function \fIpop\fR in Lisp because it ! 866: updates the status of the stream to reflect the ! 867: extraction of the "topmost element" similar to the way \fIpop\fR replaces ! 868: its list argument with its \fIcdr\fR. ! 869: \fINextitem\fR does this by destructively modifying the stream ! 870: (but not the hash bucket); ! 871: once the top item ! 872: has come off it is no longer a part of the stream. ! 873: Like \fIpop\fR, \fInextitem\fR returns \fInil\fR if the stream is empty. ! 874: .PP ! 875: A stream, as returned by \fIfetch\fR in PotentialTrips, ! 876: will \fBnever\fR be \fInil\fR but instead will be a list. ! 877: In all cases, the first element will be the atom \fB*stream*\fR. ! 878: In most cases, the second element (\fIcadr\fR) is the pattern (object ! 879: being fetched) and the rest (\fIcddr\fR) is ! 880: the hash bucket that the object hashes to. ! 881: However, it is entirely possible for the hash bucket to either ! 882: fail to contain any instances of the object, or to contain ! 883: multiple instances of the object. ! 884: The form that is printed by PEARL's default print function is: ! 885: the atom \fB*stream:*\fR, the object being fetched, ! 886: and the number of potential items in the stream, ! 887: avoiding the prining of a lengthy result. ! 888: (If the pattern is actually a function structure, then the atom ! 889: used is \fB*function-stream:*\fR.) ! 890: .PP ! 891: Thus, to actually determine whether the object in Trip is in the data ! 892: base, it is necessary to ask for the \fInextitem\fR in the bucket of ! 893: the stream PotentialTrips (that is, in the \fIcddr\fR) ! 894: which matches the object being fetched (that is, the \fIcadr\fR ! 895: of PotentialTrips): ! 896: .DS ! 897: (setq FirstResult (nextitem PotentialTrips) ) ! 898: (setq SecondResult (nextitem PotentialTrips) ) ! 899: .DE ! 900: If nothing matching Trip occurred in the data base, FirstResult would ! 901: contain \fInil\fR; ! 902: otherwise, it would contain an object in the data base ! 903: which matches Trip. ! 904: If you have typed in all the examples we have shown you above, ! 905: then FirstResult will contain the same value as Trip. ! 906: SecondResult will be \fInil\fR. (The only other object in the same ! 907: bucket is the value of Leaving, but that does not match because ! 908: its To slot contains School after the \fIpath put\fR above.) ! 909: If the two structures in Trip and Leaving both contained ! 910: the same slot fillers, they would both match Trip and each ! 911: would be returned by \fInextitem\fR on successive calls. ! 912: .PP ! 913: This is essentially the only type of fetching that is ! 914: useful with the information presented so far, ! 915: but more powerful types will be described shortly. ! 916: .PP ! 917: Since the functions \fIcreate\fR, \fIfetch\fR, and \fInextitem\fR ! 918: are often used in combination, several macros combining them are ! 919: provided by PEARL: ! 920: .IP ! 921: When you wish to create a pattern only long enough to use it as an ! 922: argument to \fIfetch\fR, you can use the macro \fBfetchcreate\fR ! 923: which is defined in such a way that \fI(fetchcreate blah)\fR is ! 924: equivalent to \fI(fetch (create blah) )\fR ). ! 925: .IP ! 926: If you want to do a \fIfetchcreate\fR in a function definition and ! 927: you wish the pattern to be created only once but used each time ! 928: this function is called (a potential savings in space and time), ! 929: the macro \fBinlinefetchcreate\fR will call \fIcreate\fR when it ! 930: expands and then expand to a call to fetch with this pattern. ! 931: .IP ! 932: If you want to do a \fIcreate\fR in a function definition and ! 933: you wish the object to be created only once, ! 934: the macro \fBinlinecreate\fR will call \fIcreate\fR when it ! 935: expands and effectively replace itself with the result. ! 936: .IP ! 937: When you wish to fetch but only need the resulting stream long ! 938: enough to use it as an argument to \fInextitem\fR, you can use ! 939: the macro \fBfirstfetch\fR which is defined in such a way that ! 940: \fI(firstfetch blah)\fR is equivalent to \fI(nextitem (fetch blah) )\fR ). ! 941: .IP ! 942: If your only goal in fetching some fully-specified object is to ! 943: test for its existence in the data base, the function \fBindb\fR ! 944: which expects a single structure argument will return \fInil\fR ! 945: if it is not there, and non-\fInil\fR if it is. ! 946: (Note that \fIindb\fR uses \fIstrequal\fR rather than \fImatch\fR.) ! 947: .IP ! 948: It is sometimes convenient to have a list of all the items which would be ! 949: returned by successive calls to \fInextitem\fR on a stream. ! 950: The function \fBstreamtolist\fR expects a stream argument and ! 951: returns a list of the items which the stream would produce. ! 952: .NH ! 953: The Default Values for Unspecified Slots ! 954: .PP ! 955: When creating an instance of a given type, one may not always ! 956: wish to fill in all the slots of the structure, either because ! 957: the slot value is unknown or immaterial. ! 958: PEARL has a mechanism for filling unfilled slots with default values. ! 959: The simplest form of defaulting involves two ! 960: predefined objects, \fBnilsym\fR and \fBnilstruct\fR. ! 961: \fINilsym\fR is a \fIsymbol\fR, and roughly corresponds to Lisp's ! 962: \fInil\fR when \fInil\fR is viewed as an atom. ! 963: \fINilstruct\fR is a structure without any slots, ! 964: and corresponds to a null structure. ! 965: In the absence of a specified value, PEARL will fill in slots ! 966: of an individual instance of a structure being created ! 967: with \fInilsym\fR if the slot type is \fIsymbol\fR, ! 968: \fInilstruct\fR if the slot type is \fIstruct\fR, zero if the slot ! 969: is of type \fIint\fR, and Lisp \fInil\fR ! 970: if the slot is of type \fIlisp\fR or \fIsetof <any type>\fR. ! 971: Note that it is up to the user to decide upon the meaning of ! 972: \fInilsym\fR and \fInilstruct\fR during further processing. ! 973: For example, you must decide for your own application whether ! 974: a \fInilstruct\fR filling the MObject slot of a MTrans indicates ! 975: that nothing was said or that what was said is unknown. ! 976: .PP ! 977: Often you may desire closer control over the default values of ! 978: a particular slot within individual instances. ! 979: For example, suppose you had a definition of Person that ! 980: includes several pieces of information about a person: ! 981: .DS ! 982: (create base Person ! 983: (Identity symbol) ! 984: (Age int) ! 985: (Salary int) ! 986: (Health symbol) ) ! 987: .DE ! 988: The Identity slot would be filled in with a unique symbol for ! 989: that person (such as the symbol John), the Age slot would contain ! 990: the age in years, the Salary slot would get the person's monthy salary ! 991: in dollars, and the Health slot would contain a \fIsymbol\fR indicating ! 992: their state of health. ! 993: Now in creating an individual instance of a Person ! 994: the Identity slot should be always filled in, but we may desire the ! 995: other slots to be defaulted to 30 (years), 20000 (dollars) and Healthy. ! 996: However, under the default system described so far, these would be ! 997: defaulted to zero, zero and \fInilsym\fR. ! 998: PEARL provides the ability to specify individual defaults for ! 999: each slot of a particular structure type. ! 1000: This is done at \fIbase\fR creation time by following the type ! 1001: within a slot with the new default value. ! 1002: Thus our definition of Person would be: ! 1003: .DS ! 1004: (create base Person ! 1005: (Identity symbol) ! 1006: (Age int 30) ! 1007: (Salary int 20000) ! 1008: (Health symbol Healthy) ) ! 1009: .DE ! 1010: Although the main purpose of a call to \fIcreate base\fR is to define ! 1011: a structure, it also creates a special individual of the type ! 1012: being defined which has its slots filled with the default values. ! 1013: For this reason this individual is called the \fBdefault instance\fR ! 1014: of that type. ! 1015: It is a structure instance like any other, only a ! 1016: pointer to it is kept with the type definition, and it is consulted ! 1017: whenever an instance of that type is constructed. ! 1018: Thus the default values (either the user-defined defaults or ! 1019: the standard defaults) will always be used whenever the user ! 1020: declines to fill in a slot of a structure instance. ! 1021: For more on defaults, see the discussion of inheriting in ! 1022: section 19 on creating expanded structures. ! 1023: .NH ! 1024: Using Patterns For More Flexible and Powerful Retrieval ! 1025: .PP ! 1026: If the fetching mechanisms described so far were the ! 1027: only sort of fetching that we could do, \fIfetch\fR ! 1028: (and PEARL) would not be very useful. ! 1029: What is needed is a way to only partially specify the ! 1030: values in the structure to be fetched. ! 1031: Note that the default mechanism does not accomplish this, ! 1032: since all slots are specified at creation time, even if they ! 1033: get \fInilsym\fR, \fInilstruct\fR, or \fInil\fR for a value. ! 1034: What is needed is the ability to specify a \fIdon't care\fR ! 1035: value for slots whose values should not affect the matching ! 1036: process during retrieval. ! 1037: The easiest way to accomplish this in PEARL is to create ! 1038: a type of object called a \fBpattern\fR. ! 1039: A \fIpattern\fR is similar to an \fIindividual\fR instance of ! 1040: a structure except that a special pattern-matching variable ! 1041: called \fB?*any*\fR which means \fIdon't care\fR or \fImatch anything\fR ! 1042: is used as the default value for unspecified slots. ! 1043: (The reason for its name will be clear after the description ! 1044: of pattern-matching variables later in this section. ! 1045: Even more detail on pattern-matching variables and more powerful ! 1046: patterns is provided in sections 21-23 on the matching process, ! 1047: blocks, lexically scoped variables, and the ! 1048: unbinding of variables.) ! 1049: .PP ! 1050: Patterns are created with \fIcreate\fR using \fIpattern\fR ! 1051: as the first argument. ! 1052: Other than this, their syntax is exactly the same as individuals. ! 1053: An example of a \fIpattern\fR creation is: ! 1054: .DS ! 1055: (create pattern PTrans JohnWentSomewhere ! 1056: (Actor John) ! 1057: (Object John) ) ! 1058: .DE ! 1059: This pattern would match any instance of PTrans in which John ! 1060: was both the actor and the object being moved. ! 1061: (Note that this pattern is stored in the Lisp variable ! 1062: JohnWentSomewhere in the same way as other individuals.) ! 1063: The main use of patterns is as arguments to \fIfetch\fR, as in: ! 1064: .DS ! 1065: (setq PotentialGoings (fetch JohnWentSomewhere) ) ! 1066: .DE ! 1067: \fIFetch\fR will return a stream containing all PTranses in the ! 1068: data base in which John was the actor and object, regardless ! 1069: what the From and To slots contain. ! 1070: More complex examples can be created. ! 1071: Patterns can be embedded as in: ! 1072: .DS ! 1073: (create pattern MTrans InformJohnGoingSomewhere ! 1074: (MObject (PTrans (Actor John) ! 1075: (Object John) ) ) ) ! 1076: .DE ! 1077: Since all unspecified slots are filled with ?*any*, this pattern ! 1078: will return any MTranses concerning any of John's PTranses ! 1079: when passed to \fIfetch\fR. ! 1080: Thus, if we insert InformLeaving from above in the data base: ! 1081: .DS ! 1082: (insertdb InformLeaving) ! 1083: .DE ! 1084: then the following will fetch that object: ! 1085: .DS ! 1086: (nextitem (fetch InformJohnGoingSomewhere) ) ! 1087: .DE ! 1088: .PP ! 1089: Usually one is interested in a more specific piece of information. ! 1090: For example, if you knew that John told Carol something and wanted ! 1091: to find out what it was, then you could do this two ways. ! 1092: One is to create a pattern, fetch it and look at the MObject slot of ! 1093: the result: ! 1094: .DS ! 1095: (create pattern MTrans WhatDidJohnTellCarol ! 1096: (Actor John) ! 1097: (From John) ! 1098: (To Carol) ) ! 1099: (setq Result (firstfetch WhatDidJohnTellCarol) ) ! 1100: (path get Result 'MObject) ! 1101: .DE ! 1102: However, you might prefer to use a pattern which explicitly ! 1103: shows that you want that value and gives you a slightly easier ! 1104: way to get at it. ! 1105: In this case, you can specify a pattern-matching variable ! 1106: in the MObject slot of the pattern. ! 1107: A pattern-matching variable is created by preceding an atom with a ! 1108: question mark \fB?\fR as in \fI?What\fR. ! 1109: The question mark is a read macro character which reads the next ! 1110: atom and builds the list \fI(*var* What)\fR out of it (or ! 1111: \fI(*global* What)\fR if \fIWhat\fR has previously been declared ! 1112: global to PEARL; ! 1113: see below for more on global variables.). ! 1114: During matching, this variable will get bound to the value ! 1115: of the slot it gets matched against: ! 1116: .DS ! 1117: (create individual MTrans WhatDidJohnTellCarol ! 1118: (Actor John) ! 1119: (MObject ?What) ! 1120: (From John) ! 1121: (To Carol) ) ! 1122: (firstfetch WhatDidJohnTellCarol) ! 1123: .DE ! 1124: To access the value of a pattern-matching variable in ! 1125: a structure, one uses either the function \fBvalueof\fR ! 1126: (which is an expr) or the fexpr \fBvarvalue\fR. ! 1127: Both functions have two arguments: the name of the ! 1128: pattern-matching variable whose value you want and ! 1129: the structure it occurs in (which is evaluated internally ! 1130: by \fIvarvalue\fR). ! 1131: Thus both of the following are equivalent: ! 1132: .DS ! 1133: (valueof \fB'\fRWhat WhatDidJohnTellCarol) ! 1134: (varvalue What WhatDidJohnTellCarol) ! 1135: .DE ! 1136: .NH ! 1137: Marking Structures During Creation For More Efficient Retrieval ! 1138: .PP ! 1139: Besides specifying what type each structure is, the simplest ! 1140: piece of information that \fIinsertdb\fR would like the user ! 1141: to give it through \fIcreate\fR concerns which slot(s) of ! 1142: a type would be most likely to contain unique information ! 1143: about a particular instance of that type. ! 1144: This information is used to differentiate instances of the ! 1145: type from each other, so that they will be hashed into ! 1146: different hash buckets. ! 1147: This is similar to the "keys" that many data base systems ask for. ! 1148: For PTrans, the Actor slot is often the best choice for this role. ! 1149: For Person, the Identity slot would be the best choice for this role. ! 1150: Such unique slots are indicated to \fIcreate\fR when defining a ! 1151: type by placing an asterisk '*' before the slotname in a ! 1152: (<slotname> <type>) pair. ! 1153: For example, our new definitions of PTrans and Person ! 1154: to take advantage of this would look like: ! 1155: .DS ! 1156: (create base PTrans ! 1157: (* Actor symbol) ! 1158: ( Object symbol) ! 1159: ( From symbol) ! 1160: ( To symbol) ) ! 1161: (create base Person ! 1162: (* Identity symbol) ! 1163: ( Age int 30) ! 1164: ( Salary int 20000) ! 1165: ( Health symbol Healthy) ) ! 1166: .DE ! 1167: If you execute this when you have already executed the other examples ! 1168: in this document, PEARL will warn you that you are redefining the ! 1169: base structures PTrans and Person. ! 1170: This is all right, since that is precisely what we want to happen. ! 1171: However, the previous instances of PTrans will remain hashed in the ! 1172: more inefficient way and will not match any later PTrans structures ! 1173: that are defined. ! 1174: If you find these warnings annoying when redefining structures, ! 1175: they may be turned off by setting the special variable ! 1176: \fB*warn*\fR to \fInil\fR instead of the initial \fIt\fR. ! 1177: (Note that the Lisp scanner requires a space (or other ! 1178: white space) to separate the asterisk from the slotname. ! 1179: Otherwise one would have the slotname \fI*Actor\fR). ! 1180: .PP ! 1181: Any number of starred slots may be provided within a structure ! 1182: definition, but usually only one or two are necessary. ! 1183: How one decides which slots should be starred is an ! 1184: art, and depends significantly on your application and the nature ! 1185: of your data. ! 1186: The basic rule of thumb is to choose those slots ! 1187: whose values vary the most widely from instance to instance. ! 1188: A bad choice will not usually cause the system to bomb or ! 1189: operate incorrectly in any way, but when it comes time to ! 1190: fetch an object back out of the data base the system may have ! 1191: to take the time to scan a large amount of the data base ! 1192: rather than finding the desired object very rapidly. ! 1193: Thus execution time is usually the only penalty one pays ! 1194: for an improper choice of slots to star. ! 1195: .PP ! 1196: However, there is one type of use of a slot which can cause ! 1197: problems in combination with hashing information. ! 1198: It involves the use of pattern-matching variables and will ! 1199: serve as a useful example of how to use variables and of how ! 1200: \fIinsertdb\fR and \fIfetch\fR use the hashing ! 1201: information to insert and find objects. ! 1202: The key difference between them is that while \fIinsertdb\fR ! 1203: inserts an object in as many places as it can, \fIfetch\fR only ! 1204: looks for it in the \fBbest\fR place. ! 1205: (What we mean by best will be more obvious after section 13.) ! 1206: .PP ! 1207: The problem situation occurs when you wish to insert items ! 1208: into the data base which contain a variable in the starred ! 1209: slot (representing general knowledge) and then use, ! 1210: as a pattern, a structure with that slot filled. ! 1211: Thus, the following sequence will fail to find Thing ! 1212: in the data base and instead will return \fInil\fR: ! 1213: .DS ! 1214: (create base Thing ! 1215: (* One int) ) ! 1216: .DE ! 1217: .DS ! 1218: (dbcreate individual Thing DBThing ! 1219: (One ?O) ! 1220: (Two 2) ) ! 1221: .DE ! 1222: .DS ! 1223: (nextitem (fetchcreate individual Thing PatThing ! 1224: (One 1) ! 1225: (Two 2) ) ! 1226: .DE ! 1227: This fails \fIsimply because of the hashing\fR. ! 1228: Let us see why. ! 1229: When \fIinsertdb\fR is asked to put something into the data base, ! 1230: it seeks to put it as many places as the hashing information ! 1231: indicates are good places to want to look for it. ! 1232: With no hashing information at all, the only thing \fIinsertdb\fR ! 1233: can do is to put the object with all other objects of its type. ! 1234: Thus, with no hashing information, all Things are put together in ! 1235: the same hash bucket. ! 1236: With the hashing information, \fIinsertdb\fR would like to put ! 1237: DBThing in a second (and better) place based on the fact that it ! 1238: is a Thing \fIand\fR on the value of its One slot. ! 1239: Unfortunately, its One slot has an unbound variable in it and does ! 1240: not provide any information which is useful. ! 1241: Thus the hashing process puts DBThing into the data base in ! 1242: only one place. ! 1243: However, when \fIfetch\fR indexes PatThing, it uses the hashing ! 1244: information to determine that it should look in the data base ! 1245: under the best combination which is \fIThing + 1\fR. ! 1246: Since DBThing is not there, it is not found. ! 1247: If we remove the asterisk, this sequence will return ! 1248: DBThing with ?O bound to 1 because both DBThing and PatThing will ! 1249: get indexed into the same spot (along with all other Things). ! 1250: Thus you should be very careful when determining how to hash ! 1251: types of structures when you intend to insert them into ! 1252: the data base with variables in them. ! 1253: (An alternative solution which could be more efficient if used ! 1254: carefully is to use the function \fIfetcheverywhere\fR which is ! 1255: described in section 13. ! 1256: This problem can also sometimes be solved with the use of adjunct ! 1257: variables, described in section 14.) ! 1258: .PP ! 1259: After more of the system has been described and examples of fetching ! 1260: and inserting have been given the user will have a better ! 1261: understanding of this process. ! 1262: .PP ! 1263: As another example, let us now create and insert an instance ! 1264: of our new PTrans which has the Actor slot starred: ! 1265: .DS ! 1266: (dbcreate individual PTrans Trip ! 1267: (Actor John) ! 1268: (Object John) ! 1269: (From Office) ! 1270: (To Home) ) ! 1271: .DE ! 1272: This would insert Trip with all other PTranses and, because of the ! 1273: starred slot Actor, also with any other PTranses with a value of ! 1274: John in the Actor slot. ! 1275: Next we redefine and recreate the MTrans: ! 1276: .DS ! 1277: (create base MTrans ! 1278: (* Actor symbol) ! 1279: ( MObject struct) ! 1280: ( From symbol) ! 1281: ( To symbol) ) ! 1282: .DE ! 1283: .DS ! 1284: (create individual MTrans InformLeaving ! 1285: (Actor John) ! 1286: (MObject (PTrans Leaving ! 1287: (Actor John) ! 1288: (Object John) ! 1289: (From Office) ! 1290: (To Home) ) ) ! 1291: (From John) ! 1292: (To Carol) ) ! 1293: .DE ! 1294: reinsert the PTrans from the MTrans: ! 1295: .DS ! 1296: (insertdb Leaving) ! 1297: .DE ! 1298: and finally create and insert two other instances of a PTrans, ! 1299: one with different values in the From and To slots ! 1300: and one with different values in the Actor and Object slot: ! 1301: .DS ! 1302: (create individual PTrans Trip ! 1303: (Actor John) ! 1304: (Object John) ! 1305: (From Home) ! 1306: (To School) ) ! 1307: .DE ! 1308: .DS ! 1309: (create individual PTrans ! 1310: (Actor Ted) ! 1311: (Object Ted) ! 1312: (From Office) ! 1313: (To Home) ) ! 1314: .DE ! 1315: Note that this last PTrans will be indexed under the combination ! 1316: of PTrans and Ted and thus will not be in the same hash bucket we ! 1317: look in when fetching Trip (which is indexed by PTrans and John): ! 1318: .DS ! 1319: (setq PotentialTrips (fetch Trip) ) ! 1320: (setq Result (nextitem PotentialTrips) ! 1321: PotentialTrips ! 1322: .DE ! 1323: Notice the form of the stream PotentialTrips at this point. ! 1324: .NH ! 1325: Printing Structures, Symbols and Other PEARL Objects ! 1326: .PP ! 1327: As mentioned in the beginning, PEARL stores symbols and ! 1328: structures (and their definitions) in hunks of memory ! 1329: that are circularly linked. ! 1330: Lisp cannot print out the contents of these blocks in a useful way. ! 1331: Franz Lisp sometimes goes into an infinite loop trying to print them ! 1332: and the best UCI Lisp can do is tell you its address, ! 1333: like #2934, which is not very informative. ! 1334: As mentioned above, the PEARL prompt-read-eval-print loop knows how ! 1335: to print these in symbolic form. ! 1336: However, when you want your own programs to print ! 1337: them, PEARL provides you with two pairs of functions ! 1338: to convert these blocks into more readable form. ! 1339: The first we will discuss is the function \fBvalform\fR. ! 1340: \fIValform\fR takes a \fIstruct\fR, a \fIsymbol\fR or any other type ! 1341: of PEARL or Lisp object as an argument and returns a ! 1342: Lisp S-expression describing the object. ! 1343: Thus if one calls \fIvalform\fR on our PTrans in Trip: ! 1344: .DS ! 1345: (setq TripAsList (valform Trip) ) ! 1346: .DE ! 1347: the Lisp variable TripAsList will contain the S-expression: ! 1348: .DS ! 1349: (PTrans (Actor John) (Object John) (From Home) (To School) ) ! 1350: .DE ! 1351: Note that \fIvalform\fR does not cause the PTrans to be printed out ! 1352: at the user's terminal, it is merely a function that returns an ! 1353: S-expression (just as the Lisp function \fIlist\fR does.) ! 1354: PEARL functions will operate upon structures and symbols only ! 1355: when they are in their internal form, so the primary reason ! 1356: for converting structures to S-expressions is to print them ! 1357: (or to modify them for use as new input to \fIcreate\fR). ! 1358: So PEARL provides a more useful function \fBvalprint\fR ! 1359: that is effectively \fI(sprint (valform <argument>) )\fR. ! 1360: (\fBSprint\fR is a function provided by UCI Lisp or Franz PEARL ! 1361: which prints a Lisp expression in a nicely indented form. ! 1362: There are more details on \fIsprint\fR in the appendix on UCI Lisp ! 1363: functions added to PEARL.) ! 1364: \fIValprint\fR is normally used within a Lisp program to ! 1365: print out any PEARL construct onto the user's terminal ! 1366: and it is also used by the default print function in the ! 1367: PEARL prompt-read-eval-print loop. ! 1368: Try typing the following and notice that they are the ! 1369: same except that the second value is slightly indented. ! 1370: .DS ! 1371: (valprint Trip) ! 1372: Trip ! 1373: .DE ! 1374: Like \fIsprint\fR, \fIvalprint\fR will accept a second integer ! 1375: argument telling it which column to start printing in. ! 1376: The default \fIpearlprintfn\fR uses a value of 4 for this argument ! 1377: to make the items typed by the user more distinguisable from the ! 1378: results typed by PEARL. ! 1379: .PP ! 1380: There is one other form of each of these two functions. ! 1381: The functions \fBfullform\fR and \fBfullprint\fR are ! 1382: like \fIvalform\fR and \fIvalprint\fR but they print ! 1383: more complete information. ! 1384: If you type ! 1385: .DS ! 1386: (fullprint Trip) ! 1387: .DE ! 1388: you will notice that the result has two mysterious ! 1389: \fInil\fRs in each slot. ! 1390: These represent other forms of information (predicates ! 1391: and hooks or demons) which can be added to structures ! 1392: and which will be described later. ! 1393: At the moment therefore, \fIvalform\fR and \fIvalprint\fR ! 1394: are all that the user need remember. ! 1395: .PP ! 1396: Note also from above that when a pattern with \fI?*any*\fR is printed, ! 1397: only the name of that variable is printed, and not its value. ! 1398: (Try typing JohnWentSomewhere and InformJohnGoingSomewhere ! 1399: if you do not remember what this looked like.) ! 1400: If a PEARL pattern-matching variable has not been bound, ! 1401: PEARL indicates this by printing no value. ! 1402: If a variable is bound, both the variable name and ! 1403: its value are printed. ! 1404: Later when you learn how to put your own variables ! 1405: in slots, this will become more useful. ! 1406: .PP ! 1407: When given a data base, these functions assume that the user does ! 1408: not really want the complete contents of the data base printed out ! 1409: and so simply print \fI(database: <databasename>)\fR. ! 1410: To actually have the complete contents of a data base printed out, ! 1411: use the function \fBprintdb\fR. ! 1412: With no argument, it prints the default data base. ! 1413: Otherwise, it expects its argument to evaluate to a data base. ! 1414: A print function which prints all the internal information contained ! 1415: in a structure or its definition is \fBdebugprint\fR. ! 1416: .NH ! 1417: Error Messages, Bugs, and Error Handling Abilities ! 1418: .PP ! 1419: Due to the complex implemention of PEARL and the lack ! 1420: of facilities in Lisp for easily distinguishing between ! 1421: types of input, a user's error in using PEARL will not ! 1422: show up as soon as it occurs, but may instead cause some ! 1423: unfathomable part of PEARL to bomb out sometime later. ! 1424: If this should happen, the user might try using the Lisp ! 1425: trace facilities, but will often find little useful information. ! 1426: This sad state of affairs is currently unavoidable due to the ! 1427: difficulty of catching user errors where they first occur. ! 1428: This is partly due to our inability to predict what kinds of ! 1429: errors users are most likely to make. ! 1430: .PP ! 1431: PEARL checks as much as it can, but many features are impossible ! 1432: or prohibitively expensive to check. ! 1433: The best strategy for the ! 1434: user to follow is to examine his last interaction with PEARL. ! 1435: If the error occurred in the bowels of \fIcreate\fR, then there is a ! 1436: good chance that the user did something wrong in the details of ! 1437: a slot description in the call to \fIcreate\fR, since gross structural ! 1438: errors in such calls are checked for. ! 1439: Inspect your call closely. ! 1440: .PP ! 1441: Other errors can be even more difficult, since a function call ! 1442: may blow up or fail to produce the desired result due to bad ! 1443: data passed to \fIcreate\fR several calls ago. ! 1444: A general rule of thumb to use in tracking down mystifying ! 1445: errors is to check out the definitions of the structures ! 1446: involved in the function that failed. ! 1447: Thus if \fIpath\fR blows up, one should determine the type of ! 1448: the structure passed to \fIpath\fR, and then check the ! 1449: \fIcreate\fR call that defined that type. ! 1450: .PP ! 1451: Sometimes PEARL may appear to the user to be doing the wrong thing, ! 1452: but due to PEARL's complex semantics, the user is really at fault. ! 1453: To make matters worse, there is of course always the chance that ! 1454: the error really \fBis\fR in PEARL. ! 1455: Every effort has been made to minimize this chance, and at the ! 1456: moment there are no known major errors (except those indicated ! 1457: in this documentation), but as with any complex evolving ! 1458: software system there is always the chance of obscure errors. ! 1459: It has been our experience that most errors ! 1460: are due to the user (including the implementors) not completely ! 1461: understanding the semantics of some PEARL feature. ! 1462: This documentation is an effort to minimize this type of error. ! 1463: For any error which you commit in which PEARL gives what ! 1464: you consider an unreasonable response, feel free to report ! 1465: it and we will consider trying to catch it. ! 1466: These or any other complaints, bugs or suggestions should be ! 1467: mailed to Joe Faletti via Arpanet or Unix mail ! 1468: (Kim.Faletti@Berkeley or ucbvax!kim.faletti). ! 1469: .NH ! 1470: Short-Circuiting and Redirecting Create Using !, $ and Atoms ! 1471: .PP ! 1472: Sometimes, when creating an individual structure, ! 1473: one may want to fill a slot with an already created structure ! 1474: that is pointed to by some atom or returned by some function ! 1475: (or with whatever type of value the slot requires). ! 1476: In this case, one does not wish to (or cannot) describe the ! 1477: value for a slot as a list of atoms. ! 1478: To handle this situation, PEARL allows you to list a Lisp expression ! 1479: which evaluates to the desired internal form (that is, a form ! 1480: which needs no processing by \fIcreate\fR), preceding it with ! 1481: an exclamation point \fB"!"\fR. ! 1482: The structure (or other object) resulting from evaluating ! 1483: the Lisp expression will be tested to ensure it is the right type ! 1484: of value and, if it is, inserted in the newly created structure ! 1485: as the value of that slot. ! 1486: (The mnemonic idea of this symbol is as a sort ! 1487: of "barrier" meaning \fIStop processing here!!! and take this ! 1488: (almost) literally!!!\fR) For example, after using ! 1489: .DS ! 1490: (create individual PTrans Ptrans23 ! 1491: (Actor John) ! 1492: (Object John) ! 1493: (To Home) ) ! 1494: .DE ! 1495: to create an individual PTrans, leaving it in internal form in the ! 1496: atom Ptrans23, you can then insert this PTrans into a new MTrans ! 1497: with: ! 1498: .DS ! 1499: (create individual MTrans ! 1500: (Actor Bob) ! 1501: (MObject ! Ptrans23) ! 1502: (To Carol) ) ! 1503: .DE ! 1504: .PP ! 1505: At other times the user may want to take the result of evaluating ! 1506: some Lisp code and splice it into the Lisp expression describing the ! 1507: structure being created at the point where the description of the ! 1508: value of a slot would occur. ! 1509: In this case, you wish some Lisp code to be evaluated and then ! 1510: you wish \fIcreate\fR to build a value for this slot ! 1511: by further processing (scanning) the result of this evaluation. ! 1512: To this end, PEARL will evaluate any slot value preceded by a ! 1513: \fB"$"\fR and insert its result into the \fIcreate\fR call, ! 1514: proceeding to process it just as if ! 1515: the user had typed it in directly. ! 1516: So if one stores the atom Alice in Name with ! 1517: .DS ! 1518: (setq Name 'Alice) ; the atom Alice, not the symbol Alice ! 1519: ; (or the value of s:Alice). ! 1520: .DE ! 1521: or possibly ! 1522: .DS ! 1523: (setq Name (read) ) ! 1524: .DE ! 1525: with the user having typed \fIAlice\fR, then \fI$ Name\fR in ! 1526: .DS ! 1527: (create individual PTrans ! 1528: (Actor $ Name) ! 1529: (Object $ Name) ! 1530: (From Home) ! 1531: (To NewYork) ) ! 1532: .DE ! 1533: is equivalent to having Alice typed as the Actor and Object ! 1534: values: \fIcreate\fR evaluates Name and then processes its ! 1535: value \fIAlice\fR as input. ! 1536: Thus, the PTrans will be equivalent to ! 1537: .DS ! 1538: (create individual PTrans ! 1539: (Actor Alice) ! 1540: (Object Alice) ! 1541: (From Home) ! 1542: (To NewYork) ) ! 1543: .DE ! 1544: The power of this construct occurs when Name is a atom whose ! 1545: value changes at run time (as when it is read above) or the ! 1546: \fIcreate\fR call is within a loop in which Name takes on many ! 1547: different values. ! 1548: .PP ! 1549: In summary, both ! and $ cause the evaluation of the Lisp ! 1550: expression following them. ! 1551: However, ! stops the usual processing and expects an ! 1552: internal value, whereas $ continues the usual ! 1553: processing and expects a Lisp description of the value. ! 1554: When you need either ! or $, you will know it! ! 1555: Until then, do not worry if you do not understand them very well! ! 1556: .PP ! 1557: If the expression you want evaluated is simply an atom ! 1558: bound to a value of the appropriate type, you need not use the !. ! 1559: Whenever \fIcreate\fR is looking for a value of a particular ! 1560: type, and finds a bound atom instead, it evaluates the atom and ! 1561: if it is bound to the correct type of value, that value is used. ! 1562: This is only done in \fIsymbol\fR slots when the atom is not a ! 1563: symbolname and in \fIinteger\fR slots if the atom is not from ! 1564: the ordinal type (if any) associated with the slot. ! 1565: .NH ! 1566: More Flexible Hash Selection ! 1567: .PP ! 1568: The use of stars (asterisks *) to indicate useful slots for hashing ! 1569: described earlier is only one of many hashing schemes that PEARL allows. ! 1570: This section describes the others, and how the user can control them. ! 1571: The first point to note is that even with the star hashing a single ! 1572: structure can be hashed in several different ways. ! 1573: Thus if one thinks that in a particular program PTrans will be ! 1574: frequently fetched from the data base given only the ! 1575: Actor \fBor\fR only the Object (that is, the program might only ! 1576: know the Actor and desire the whole PTrans, or know only ! 1577: the Object and desire the whole PTrans) the user should ! 1578: star \fBboth\fR the Actor and Object slots within ! 1579: the definition of PTrans. ! 1580: When PEARL stores a PTrans into the data base, it will index ! 1581: it under both (PTrans + Actor) and (PTrans + Object) in addition ! 1582: to the usual indexing with all other PTranses. ! 1583: In general, any number of slots can be starred. ! 1584: .PP ! 1585: Another type of hashing does not use the type of the structure in ! 1586: creating a hash index. ! 1587: If the symbol colon (:) is used before the ! 1588: name of a slot, objects of that type will be hashed under that slot ! 1589: value only. ! 1590: Thus if the Actor slot of the PTrans definition was ! 1591: preceded by a colon instead of a star, then instances of PTrans ! 1592: would be hashed under the value of the Actor slot alone rather the ! 1593: value of the (PTrans + Actor). ! 1594: This would be useful in the case in which one were interested in ! 1595: fetching any structure in which a particular value, say the ! 1596: symbol John, appered in a coloned slot. ! 1597: For example all structures in which John appeared in the Actor slot ! 1598: could be fetched at once (and very efficiently). ! 1599: .PP ! 1600: A third type of hashing is \fBstar-star\fR or \fBdouble-star (**) ! 1601: hashing\fR. ! 1602: If a double star is used instead of a single star, ! 1603: PEARL will use \fBtriple hashing\fR. ! 1604: Only one triple hashing is allowed per structure. ! 1605: Triple hashing requires that two, and only two slots be double starred. ! 1606: If PTrans were to be defined in the following way: ! 1607: .DS ! 1608: (create base PTrans ! 1609: (** Actor symbol) ! 1610: (** Object symbol) ! 1611: ( From symbol) ! 1612: ( To symbol) ) ! 1613: .DE ! 1614: then when an instance of a PTrans is created, it will be hashed ! 1615: into the data base under a combination of the three values ! 1616: (PTrans + Actor + Object). ! 1617: As with all hashing, if a slot is necessary to a particular type ! 1618: of hashing but is unfilled (or filled with \fInilsym\fR or ! 1619: \fInilstruct\fR) the hashing will not occur. ! 1620: Triple hashing is used when one wants fast access to all ! 1621: individuals of a particular type with two slots likely to have ! 1622: fairly unique values. ! 1623: In the case of PTrans, this would allow one fast access to all ! 1624: PTranses in which John PTranses Mary somewhere. ! 1625: Distinctions this fine are not usually necessary, and as it ! 1626: is slightly more expensive at creation and fetching time, ! 1627: it should only be used when the user is sure of the need for it. ! 1628: .PP ! 1629: A fourth type of hashing is \fBcolon-colon\fR or \fBdouble colon (::) ! 1630: hashing\fR. ! 1631: It has the same relation to colon hashing as double star ! 1632: hashing has to star hashing. ! 1633: If the **'s in the above are replaced with ::, the hashing will be ! 1634: on (Actor + Object) ignoring the fact that the structure is a PTrans. ! 1635: This might be useful in fetching all structures involving John and Mary. ! 1636: As with double star hashing, double colon hashing should be used ! 1637: sparingly and only one such hashing pair may be used in a type. ! 1638: .PP ! 1639: However, it is possible to combine the use of any of these ! 1640: hashing methods in a single structure. ! 1641: Thus one could have both double colon hashing and double star ! 1642: hashing, as well as several * and : hashings as well. ! 1643: Given several ways, PEARL uses the one ! 1644: which the most complex one is used during ! 1645: fetching, since that should provide the greatest degree of ! 1646: discrimination between items (that is, most likely to narrow ! 1647: down the choices). ! 1648: If the value in a slot intended to take part in hashing is unbound ! 1649: or otherwise not useful, then the next most specific method it used. ! 1650: Given the values which are considered useful and the hashing ! 1651: information for the type of structure, the hierarchy of buckets ! 1652: to be chosen is as follows: ! 1653: .DS ! 1654: ** hashing ! 1655: :: hashing ! 1656: * hashing ! 1657: : hashing ! 1658: .DE ! 1659: .PP ! 1660: In section 9 we discussed a problem that arises when the pattern ! 1661: you are using is more specific than the structures in the data base. ! 1662: In this case, \fIfetch\fR looks in the data base in the most ! 1663: specific place and does not find what it is looking. ! 1664: One alternative is to eliminate the hashing that causes this problem ! 1665: but this will force \fIfetch\fR to look through a large number of items. ! 1666: If you do not intend to look all the way through the stream ! 1667: returned by \fIfetch\fR, there is a version of fetch which will ! 1668: build the stream out of all the ways the pattern could be fetched. ! 1669: This function is called \fBfetcheverywhere\fR and will return a ! 1670: stream made up of the (up to five) hash buckets that its pattern ! 1671: could be -- potentially expensive if you intend to process the ! 1672: whole thing. ! 1673: .PP ! 1674: In addition to these four methods of hashing, and the simplest one ! 1675: based on the type of structure only, there are several ! 1676: hashing labels which are modifiers on these methods and ! 1677: affect what values are used to compute the index. ! 1678: .PP ! 1679: The remaining hashing flags do not introduce any new types ! 1680: of hashing, but rather modify the way the existing types work. ! 1681: To motivate these, consider the implementation of Goal withing CD. ! 1682: In early versions of CD, there were several different types of ! 1683: goals, including Delta-Prox (goal of being near something), ! 1684: Delta-Poss (goal of possessing something), and so on. ! 1685: In general these delta goals were of the form ! 1686: (Delta-<some CD primitive> (Actor ...) (Objective ...) ). ! 1687: This lead to an explosion of Delta-goals ! 1688: (e.g. Delta-Move-Fingers-Within-Telephone-Dial), ! 1689: and a new way of handling goals was established. ! 1690: This was simply that all Goals were to have the form: ! 1691: .DS ! 1692: (create base Goal ! 1693: (Planner symbol) ! 1694: (Objective struct) ) ! 1695: .DE ! 1696: where the Objective would be filled with the appropriate structure, ! 1697: whether it was a simple Poss or the $DialPhone script. ! 1698: This change makes CD much cleaner, but poses somewhat of ! 1699: a problem for hashing. ! 1700: One of the major uses of hashing within some AI programs ! 1701: written in PEARL is to associate plans with goals. ! 1702: So it is best if this process is efficient. ! 1703: .PP ! 1704: As an example of this problem (using the early form of Delta-goals): ! 1705: .DS ! 1706: ; Declaration of PlanFor rules. ! 1707: (create base PlanFor ! 1708: (* Objective struct) ! 1709: (* Plan struct) ) ! 1710: .DE ! 1711: .DS ! 1712: (create base Delta-Prox ! 1713: (Planner symbol) ! 1714: (Location symbol) ) ! 1715: .DE ! 1716: .DS ! 1717: (create base Walk-Plan ! 1718: (Planner symbol) ! 1719: (From symbol) ! 1720: (To symbol) ) ! 1721: .DE ! 1722: .DS ! 1723: ; Store in the data base the fact that walking is a way of accomplishing ! 1724: ; a Delta-Prox goal. ! 1725: (dbcreate individual PlanFor ! 1726: (Goal (Delta-Prox (Planner ?X) ! 1727: (Location ?Y) ) ) ! 1728: (Plan (Walk-Plan (Planner ?X) ! 1729: (From nilsym) ! 1730: (To ?Y) ) ) ) ! 1731: .DE ! 1732: This structure simply says the fact that if one has a goal of being ! 1733: somewhere, then one plan for doing this is to walk. ! 1734: Or, using the rule in reverse, if you note that someone is ! 1735: walking to some location, then you might infer that they had ! 1736: a goal of being at that location. ! 1737: Note that after being put into the data base, the rule can be easily ! 1738: fetched by presenting either half of it as a pattern. ! 1739: .PP ! 1740: Thus if a planning program has a goal of doing the action in ! 1741: the atom GoalAct, then it can query the data base for ! 1742: any direct plans for doing Act by: ! 1743: .DS ! 1744: (fetchcreate individual PlanFor ! 1745: (Goal ! GoalAct) ! 1746: (Plan ?*any*) ) ! 1747: .DE ! 1748: So if GoalAct happened to be a Delta-Prox goal, then the ! 1749: rule above would be fetched. ! 1750: However the revised form of goals hides the unique nature of ! 1751: the Delta-goal, and the best one could do is fetch all PlanFor rules ! 1752: that have a structure of type Goal in their Goal slot. ! 1753: This is a serious loss since \fIall PlanFors\fR have a Goal ! 1754: in their Goal slot; ! 1755: thus the system would have to look through all ! 1756: PlanFors whenever it was trying to fetch one. ! 1757: What is needed is a way of telling PEARL that when hashing on Goals, ! 1758: never hash the structure type Goal, but rather use the ! 1759: item that fills the Objective slot of the Goal. ! 1760: This would solve our problem nicely, as now all ! 1761: PlanFors would be hashed on the name of the Objective (Prox, ! 1762: Dial-Phone, etc.), and a list of all PlanFors would not have to be ! 1763: searched to find a particular one, rather the system could just hash ! 1764: directly to it. ! 1765: .PP ! 1766: To indicate to PEARL that this \fBhash aliasing\fR is desired, ! 1767: place an ampersand '&' before the slot name to be substituted ! 1768: for the structure name when defining the structure. ! 1769: Thus Goal would be declared: ! 1770: .DS ! 1771: (create base Goal ! 1772: ( Planner symbol) ! 1773: (& Objective struct) ) ! 1774: .DE ! 1775: Naturally only one slot can be selected for hash aliasing. ! 1776: .PP ! 1777: In this way, Goals change the way in which other structures ! 1778: use them to index but the way in which Goals themselves ! 1779: are indexed will not be affected. ! 1780: Since many other types of structures are likely to contain Goals, ! 1781: we must be careful about how this affects the hashing of all of them. ! 1782: It might be the case that PlanFor was the only structure ! 1783: indexed based on Goals which would benefit from hash aliasing ! 1784: and that some structures would actually be hurt by this ! 1785: because they expected Goals to be only one of many types ! 1786: of values. ! 1787: In this case, putting the control of how Goals get used by ! 1788: other structures into the definition of Goal is a bad idea. ! 1789: Instead, the control can be moved up into only the ! 1790: problematic structures. ! 1791: These structures can simply add the \fB">"\fR hash label to ! 1792: a starred slot, causing PEARL to use the first starred ! 1793: slot of the slot-filling structure instead of its type. ! 1794: For example, when we put a both \fB"*"\fR and \fB">"\fR on the Goal ! 1795: slot of PlanFor then it will always use the first starred ! 1796: slot of the Goal in its Goal slot: ! 1797: .DS ! 1798: (create base Goal ! 1799: ( Planner symbol) ! 1800: (* Objective struct)) ! 1801: .DE ! 1802: .DS ! 1803: (create base PlanFor ! 1804: (* > Goal struct) ! 1805: ( Plan struct)) ! 1806: .DE ! 1807: Thus, the use of \fB">"\fR hashing is called \fBforced aliasing\fR since ! 1808: the structure filling a slot has very little control over it. ! 1809: .PP ! 1810: However, there is one way for a structure to affect ! 1811: how forced aliasing happens. ! 1812: If the user wanted to also star the Planner slot of Goal, ! 1813: but wanted the Objective slot to be used in cases of forced ! 1814: aliasing, then the use of an \fB"^"\fR on the Objective slot will ! 1815: allow that: ! 1816: .DS ! 1817: (create base Goal ! 1818: (* Planner symbol) ! 1819: (* ^ Objective struct)) ! 1820: .DE ! 1821: thus allowing Goals inserted directly into the data base to be ! 1822: indexed by the combinations \fIGoal + Planner\fR and ! 1823: \fIGoal + Objective\fR while other objects containing Goals would ! 1824: use the Objective slot rather than Goal \fIOtherObject + Objective\fR. ! 1825: .PP ! 1826: On the other hand, if most structures containing Goals would ! 1827: benefit from the use of the hash aliasing label \fB"&"\fR in Goal, ! 1828: but only one or two are hurt by it, the use of \fB"&"\fR in Goal ! 1829: can be overridden by the structures which will contain Goals ! 1830: by adding the \fB"<"\fR hash label to the starred slot to produce ! 1831: \fBanti-aliasing\fR. ! 1832: This gives the controlling structure the last word ! 1833: over how it is hashed. ! 1834: .DS ! 1835: (create base Goal ! 1836: ( Planner symbol) ! 1837: (& Objective struct)) ! 1838: .DE ! 1839: .DS ! 1840: (create base OffendedStructure ! 1841: (* < Slot struct)) ! 1842: .DE ! 1843: Thus, the anti-aliasing \fB"<"\fR means \fIjust for this hashing, turn ! 1844: off hash aliasing (if any) of any structure filling this slot\fR. ! 1845: .PP ! 1846: The proper use of hash aliasing and anti-aliasing, ! 1847: like all the hashing specifiers is an art that must be learned by ! 1848: applying them to real systems, and the correct hash directives ! 1849: for a particular system rely critically upon the statistics of ! 1850: that particular system operating upon a particular set of data. ! 1851: The hashing mechanism was designed to give the user benefit in ! 1852: proportion to the effort expended in determining hash labels. ! 1853: With no effort, the structure type provides some help. ! 1854: With the addition of each label or pair of labels, ! 1855: an item to be inserted into the data base is indexed into ! 1856: another location in the hash table. ! 1857: Thus the cost of \fIextra\fR labels is simply the time to ! 1858: find another hash bucket (a few adds and multiplies), and add ! 1859: the item to the front of the list implying the time and ! 1860: space incurred by one cons-cell. ! 1861: .NH ! 1862: Using Predicates to Constrain Fetching ! 1863: .PP ! 1864: Sometimes when you are creating a pattern to fetch a structure, ! 1865: giving the overall form of the structure is not specific enough. ! 1866: In particular, it is often desirable to restrict the value of a ! 1867: slot to a subrange. ! 1868: For example, using the structure Health: ! 1869: .DS ! 1870: (create base Health ! 1871: (Actor symbol) ! 1872: (Level int) ) ! 1873: .DE ! 1874: one might want to find out who is sick by creating a pattern ! 1875: that only matches those Health structures in which the Level ! 1876: is less than -1 (on a scale from -10 to 10 perhaps). ! 1877: This can be done by simply writing a predicate (say Sick) ! 1878: which expects to be given the value of the slot being matched ! 1879: against as its one argument: ! 1880: .DS ! 1881: (de Sick (Num) ! 1882: (lessp Num -1) ) ! 1883: .DE ! 1884: Then you simply add its name after the value ! 1885: within the <slotname filler> pair of the pattern: ! 1886: .DS ! 1887: (create pattern Health HealthPattern ! 1888: (Actor ?Person) ! 1889: (Level ?Level Sick) ) ! 1890: .DE ! 1891: Given these definitions, a (fetch HealthPattern) would pass ! 1892: the Level slotfiller of each Health structure it ! 1893: found in the data base to the predicate Sick. ! 1894: If Sick returned true (non-\fInil\fR) then it would ! 1895: consider the slot to have matched whereas a ! 1896: \fInil\fR from Sick would be considered a mismatch. ! 1897: There are no standard predicates for users to use for these ! 1898: purposes, but they are relatively easy to create as needed. ! 1899: .PP ! 1900: However, one often has a predicate which has more than one ! 1901: argument only one (or none) of which are the slot value. ! 1902: For example, one might want to include a special variable ! 1903: or the value of some other slot of the structure or the ! 1904: structure itself. ! 1905: To make this easy PEARL allows predicates to be arbitrary ! 1906: s-expressions which may contain any of several special forms ! 1907: for which PEARL substitutes the current slot or structure. ! 1908: .PP ! 1909: If a predicate includes an asterisk \fB*\fR, this is replaced by ! 1910: the value of the current slot (in the structure being matched ! 1911: against). ! 1912: If it includes a double asterisk \fB**\fR, this is replaced ! 1913: by the whole structure being matched against. ! 1914: If you want the value of another slot in the current structure, ! 1915: precede its name with an equal sign (as in \fB=SlotName\fR to ! 1916: have the value of the slot named SlotName inserted). ! 1917: There is a readmacro \fB"="\fR which converts \fI=S\fR into ! 1918: \fI(*slot* S)\fR, just as the readmacro \fB"?"\fR converts ?X into ! 1919: \fI(*var* X)\fR (or \fI(*global* X)\fR) for pattern-matching variables. ! 1920: While processing predicates before executing them, PEARL will ! 1921: look for these three constructs and replace any of them with the ! 1922: appropriate value, so pattern-matching variables can also be ! 1923: used in predicates. ! 1924: .PP ! 1925: If there are several predicates on a slot, they are run in ! 1926: succession until one returns nil or they have all been run. ! 1927: Thus, a list of predicates provides the effect of a conditional ! 1928: \fIand\fR. ! 1929: Thus, although PEARL knows nothing special about logical ! 1930: connectives like \fIor\fR and \fIand\fR, the effect of a ! 1931: the usual Lisp \fIand\fR is automatically implied and ! 1932: the conditional \fIor\fR of Lisp can be had by using the ! 1933: s-expression type of predicate. ! 1934: If you wish things to run regardless of their results, ! 1935: providing the effect of unconditional \fIand\fR, use hooks (demons). ! 1936: .PP ! 1937: The above was one of two types of predicates available. ! 1938: To motivate the other type, consider the case of wanting ! 1939: to fetch all MTranses about the occurence of a PTrans. ! 1940: This could be accomplished in one of two ways. ! 1941: The first is: ! 1942: .DS ! 1943: ; In this pattern example, all slots are automatically filled ! 1944: ; with ?*any* except the MObject which must be a PTrans. ! 1945: (create pattern MTrans ! 1946: (MObject (PTrans) ) ) ! 1947: .DE ! 1948: Since this method actually results in \fI?*any*\fR being ! 1949: matched against the fillers in each of the PTrans's ! 1950: slots, it is a bit inefficient. ! 1951: .PP ! 1952: The second way uses \fBstructure predicates\fR ! 1953: to avoid this matching by specifying merely that the filler ! 1954: of the MObject slot must be a PTrans structure. ! 1955: This is done by listing the name of a previously ! 1956: defined structure after a pattern-matching variable: ! 1957: .DS ! 1958: (create pattern MTrans ! 1959: (MObject ?Obj PTrans) ) ! 1960: .DE ! 1961: PEARL will then bind Obj to any structure that is a PTrans ! 1962: (or expanded PTrans) and match successfully without ! 1963: examining any of the slots of that PTrans. ! 1964: PEARL can tell the difference between these two types of ! 1965: predicates since one will have some sort of function declaration ! 1966: and the other will be the name of a defined structure. ! 1967: In the case of a function with the ! 1968: same name as a structure (which the user should never do as it ! 1969: invites errors) the name's structure role takes precedence. ! 1970: .PP ! 1971: Since a similar effect is sometimes desired on slots of type ! 1972: \fIsymbol\fR, a similar but more complex mechanism is provided ! 1973: with symbols and with structures which failed the above test. ! 1974: If the name of a predicate on a slot of type symbol or structure ! 1975: is the name of a type of structure, PEARL will assume that what ! 1976: you want to know about the value in this slot is whether there ! 1977: is anything in the data base of the type specified by the structure ! 1978: predicate with the slot value in its first slot. ! 1979: Thus, if the data base contains an item saying that the symbol ! 1980: John represents a person: ! 1981: .DS ! 1982: (symbol John) ! 1983: (dbcreate individual Person ! 1984: (Identity John)) ! 1985: .DE ! 1986: then fetching a pattern with a symbol slot which has a Person ! 1987: predicate on it: ! 1988: .DS ! 1989: (fetchcreate pattern Thing ! 1990: (Slot ?X Person)) ! 1991: .DE ! 1992: will cause the equivalent of a fetch from the (default) data base ! 1993: of the pattern (Person (Identity John)). ! 1994: Note that this implies that the first slot of a structure enjoys ! 1995: somewhat of a pre-eminence and that this means that one should ! 1996: carefully choose which slot to put first. ! 1997: For efficiency however, \fIfetch\fR is not actually used. ! 1998: The function actually used is \fBdisguisedas\fR which expects ! 1999: the slot filler, the structure definition (not default instance) ! 2000: and an optional data base to look in. ! 2001: Slot filler may be either a symbol or structure. ! 2002: .PP ! 2003: This second type of predicate can also result in a kind of ! 2004: inefficiency which you might like to avoid. ! 2005: By putting a variable in the MObject slot of the MTrans along with ! 2006: a PTrans structure predicate, we preclude PEARL from hashing the ! 2007: object in any useful way, forcing it to look through all MTranses ! 2008: instead of only MTranses with PTranses in their MObject slot. ! 2009: Since patterns are most often less specific than the objects in ! 2010: the data base, this can make a big difference. ! 2011: Another problem with a variable plus a structure predicate is that the ! 2012: structure predicate is either based on fetches and the first slot or it ! 2013: is limitted to matching the type only. ! 2014: We might sometimes want a more complicated structure to be used ! 2015: as a predicate. ! 2016: However, if we opt instead for the more efficient fetching and ! 2017: matching by putting a structure in the slot, we have lost the ! 2018: ability to have a variable bound during the match. ! 2019: .PP ! 2020: To allow you both to help improve the hashing and matching of a ! 2021: structure and also to bind a variable as a side effect, PEARL ! 2022: provides a mechanism to attach an \fBadjunct variable\fR to the slot. ! 2023: This adjunct variable in a slot is bound as a side effect whenever the ! 2024: values in the slot of the two structures were already bound, have ! 2025: already been matched successfully and all predicates and slot hooks ! 2026: have been run. ! 2027: Adjunct variables may be local, lexically scoped or global, just ! 2028: as any other variable. ! 2029: To use an adjunct variable, include the variable \fIafter\fR the ! 2030: value preceded by a colon and preceding any predicates or slot hooks. ! 2031: For example, ! 2032: .DS ! 2033: (create pattern MTrans ! 2034: (MObject (PTrans (Actor John) ) : ?Obj) ) ! 2035: .DE ! 2036: would match any MTrans about John PTransing something, and also ! 2037: bind the adjunct variable ?Obj to the actual PTrans structure ! 2038: that applied. ! 2039: .PP ! 2040: Since PEARL uses hunks to create so many types of values of its ! 2041: own, it also provides a set of predicates to test an item to see ! 2042: what type it is. ! 2043: Many of them are quite definitely kludges since they depend upon ! 2044: certain bizarre structures existing only in PEARL-created items ! 2045: and not in user-created items and thus should not be depended ! 2046: upon totally. ! 2047: These functions are \fBstreamp\fR, \fBdatabasep\fR, \fBblockp\fR, ! 2048: \fBdefinitionp\fR, \fBpsymbolp\fR (to distinguish from Franz Lisp ! 2049: \fIsymbolp\fR), \fBstructurep\fR, ! 2050: \fBsymbolnamep\fR, and \fBstructurenamep\fR. ! 2051: .NH ! 2052: More Useful Slot Types ! 2053: .PP ! 2054: These last few examples begin to show the restricted nature of basic ! 2055: integer values and of labelling slots as being of type \fIstruct\fR. ! 2056: If the values in an integer slot will range between -10 and 10, ! 2057: then you would like to say that. ! 2058: If the values which will fill a slot of type structure will ! 2059: be Events or Acts or States, you would like to specify that. ! 2060: PEARL provides mechanisms to fill both of these needs. ! 2061: .PP ! 2062: In the case of an integer slot to be filled with values from a range ! 2063: of -10 to 10, these integer values do not represent "levels of health" ! 2064: very well either. ! 2065: Rather than saying that a person's "health level" ! 2066: is -2, you might like to say it was "Sick". ! 2067: In fact, you would ! 2068: probably like to say that the values of the slot will be one from ! 2069: among the set of values "Dead, Critical, Sick, OK, Healthy and InThePink". ! 2070: Moreover, you might like to specify that these values are to be ! 2071: associated with integer values in such a way that the ordering ! 2072: you specified holds and you may or may not want to specify precisely ! 2073: what integer values should be associated with these atoms. ! 2074: In other words, you would like a type which consists of a set of ! 2075: values with a linear ordering on them, similar to the Pascal scalar or ! 2076: enumeration type. ! 2077: .PP ! 2078: Such a type exists in PEARL and is created by a call to ! 2079: the function \fBordinal\fR. ! 2080: For example, to create an ordered set of values to represent ! 2081: levels of various states when you want the actual ! 2082: integer values to be created by PEARL, you would say: ! 2083: .DS ! 2084: (ordinal Levels (Low Middle High)) ! 2085: .DE ! 2086: which would associate the numbers 1, 2, and 3 with Low, Middle and ! 2087: High respectively. ! 2088: If you want to specify the values to be associated with each name, ! 2089: you simply list the value after each name. ! 2090: Thus, to create a set of values for use in the integer Level ! 2091: slot of Health above, you might say the following (the values need ! 2092: not be listed in order): ! 2093: .DS ! 2094: (ordinal HealthLevels (Dead -10 Critical -6 Sick -2 OK 2 ! 2095: Healthy 6 InThePink 10)) ! 2096: .DE ! 2097: Among the actions that \fIordinal\fR performs are the following: ! 2098: .IP 1. ! 2099: The assoc-list of names and values for the ordinal type can be ! 2100: accessed by evaluating the atom built by prepending \fBo:\fR to ! 2101: the name of the ordinal type. ! 2102: Given the name of an ordinal type, the function \fBordatom\fR builds ! 2103: this atom. ! 2104: Thus \fIo:Levels\fR contains (and \fI(eval (ordatom 'Levels))\fR returns) ! 2105: the value \fI((Low . 1) (Middle . 2) (High . 3))\fR. ! 2106: .IP 2. ! 2107: Atoms consisting of the name of the ordinal type concatenated ! 2108: with a colon and the value name are created and set to the value ! 2109: they represent. ! 2110: Thus \fILevels:Low\fR is set to 1, \fILevels:Middle\fR is set to 2, etc. ! 2111: .IP 3. ! 2112: Two atoms with \fB:min\fR and \fB:max\fR concatenated to the ! 2113: name of the ordinal type are created and set to the lowest ! 2114: and highest integer values in the type. ! 2115: Thus \fIHealthLevels:min\fR is -10, and \fIHealthLevels:max\fR is 10. ! 2116: .IP 4. ! 2117: The name of the ordinal type is added the list of all ordinal type ! 2118: names kept in the special variable \fB*ordinalnames\fR*. ! 2119: .IP 5. ! 2120: The name of the ordinal type is stored with the slot ! 2121: so that the print functions can convert from the ! 2122: integer value back into the name. ! 2123: Since the default value for integers is zero but most ! 2124: ordinals will not have a zero value, the print functions will ! 2125: print \fB*zero-ordinal-value*\fR instead of zero. ! 2126: .PP ! 2127: Having created an ordinal type, it is then possible to declare in ! 2128: a structure definition that a slot will contain values of that type. ! 2129: The use of values from this type is \fBnot enforced\fR ! 2130: by PEARL but allows the definitions of integer slots to be ! 2131: more readable, allows the use of the names of values instead ! 2132: of their associated integers when creating individuals and ! 2133: allows PEARL to print the more readable information when ! 2134: printing an integer slot. ! 2135: The special atoms created allow predicates, hooks (demons) and ! 2136: other functions to refer to these values without knowing ! 2137: their associated integers. ! 2138: We can now redefine Health to use HealthLevels: ! 2139: .DS ! 2140: (create base Health ! 2141: (Actor symbol) ! 2142: (Level HealthLevels) ) ! 2143: .DE ! 2144: and create an individual which says that John is in ! 2145: the pink of health: ! 2146: .DS ! 2147: (create individual Health ! 2148: (Actor John) ! 2149: (Level InThePink) ) ! 2150: .DE ! 2151: .PP ! 2152: Declaring a slot to be of type \fIstruct\fR is similarly ! 2153: unenlightening, so PEARL will accept the name of a ! 2154: structure type in its place. ! 2155: For example, we can make the following definitions: ! 2156: .DS ! 2157: (create base Person ! 2158: (* Identity symbol) ) ! 2159: (create base Health ! 2160: (Actor Person) ! 2161: (Level HealthLevels) ) ! 2162: .DE ! 2163: and the Actor slot of Health will be of type \fIstruct\fR. ! 2164: However, there is currently no extra type checking implied ! 2165: by this declaration (although it is being considered), but ! 2166: again it improves the readability of declarations tremendously. ! 2167: .NH ! 2168: Attaching Hooks to Structures (If-Added Demons) ! 2169: .PP ! 2170: A fairly old construct within AI is that of demons. ! 2171: In their pure form they could be thought of as asynchronous ! 2172: parallel processes that watch everything going on within a ! 2173: system, lying in wait for a particular set of conditions to occur. ! 2174: These conditions might be a block-manipulating program stacking ! 2175: some blocks too high to be stable, or a data base program violating ! 2176: a consistency constraint. ! 2177: The main problem with classical demons was that in their most flexible ! 2178: form they gobble up far too much system time, as well as being very ! 2179: hard to program as it was hard to see just when they might pop up ! 2180: during the execution of a program. ! 2181: .PP ! 2182: In an attempt to control the implementation of demons and at the same ! 2183: time provide the user with increased control over the built-in PEARL ! 2184: functions, PEARL allows the user to attach pieces of code to ! 2185: structures that will be run when specific PEARL (or user) functions ! 2186: access particular types of data or pieces of data at particular ! 2187: places in the code. ! 2188: Thus, PEARL provides a general but restricted and fairly efficient ! 2189: ability to control the operation of specific functions on specific ! 2190: pieces of data by providing \fBhooks\fR in the PEARL functions ! 2191: which check for requests within structures that certain functions ! 2192: be run when they are accessed in certain ways. ! 2193: Thus PEARL has two useful sub-breeds of \fBhooks\fR which ! 2194: watch over either ! 2195: .IP a. ! 2196: the value of a particular slot of a particular individual structure, ! 2197: referred to as \fIslot hooks\fR. ! 2198: .IP b. ! 2199: operations upon all individuals of a particular base structure type ! 2200: referred to as \fIbase hooks\fR. ! 2201: .PP ! 2202: Like predicates, hooks can either be the name of a function to ! 2203: run or a Lisp s-expression to be evaluated. ! 2204: If an s-expression, they can include the special forms ! 2205: \fB**\fR representing the current structure or \fB*\fR representing ! 2206: the value of the current slot on slot hooks and of the current ! 2207: structure on base hooks. ! 2208: Variables or slot names preceded by \fB=\fR are also allowed ! 2209: (just as in predicates), referring to variables or slots in ! 2210: the current structure. ! 2211: If hooks are run by functions which take two items as arguments, ! 2212: like \fImatch\fR, then the special form \fB>**\fR may ! 2213: be used to represent the \fBother\fR structure (which \fB>\fR is ! 2214: meant to suggest) and \fB>*\fR may be used for the value in this ! 2215: slot of the other structure. ! 2216: (In the case of functions of only one argument, \fI>*\fR and ! 2217: \fI>**\fR are the same as \fI**\fR and \fI*\fR.) ! 2218: In functions which take two arguments, the special form \fB?\fR ! 2219: may be used to represent the result that the function intends to ! 2220: return. ! 2221: (This will be \fI*pearlunbound*\fR in hooks which run before the ! 2222: function has done its job.) ! 2223: .PP ! 2224: When hooks run in the context of a call to \fIpath\fR, ! 2225: two special variables are available: \fB*pathtop*\fR which ! 2226: is the topmost structure passed to path and \fB*pathlocal*\fR ! 2227: which is the current innermost structure whose slot is ! 2228: being accessed. ! 2229: When hooks are run in the context of a call to a function which ! 2230: deals with a data base, then the special variable \fBdb\fR ! 2231: will contain the data base currently being used. ! 2232: .PP ! 2233: The functions used to fill in the special forms like *, **, =slot, ! 2234: and variables before evaluation come in two flavors and are ! 2235: called \fBfillin1\fR and \fBfillin2\fR. ! 2236: \fIFillin1\fR is designed for hooks which run on single structures ! 2237: and expects as arguments: ! 2238: .IP a. ! 2239: the function (s-expression) to fill in, ! 2240: .IP b. ! 2241: the slot value (or item if a base hook) to use for \fI*\fR, ! 2242: .IP c. ! 2243: the structure to use for \fI**\fR, and ! 2244: .IP d. ! 2245: the definition for the item provided as the third argument ! 2246: (for interpretation of \fI=slot\fR forms). ! 2247: .PP ! 2248: \fIFillin2\fR is designed for hooks which run on two structures and ! 2249: produce a result and expects as arguments: ! 2250: .IP a. ! 2251: the function (s-expression) to fill in, ! 2252: .IP b-c. ! 2253: the slot values (or structures if a base hook) to use for \fI*\fR and \fI>*\fR, ! 2254: .IP d-e. ! 2255: the structures to use for \fI**\fR and \fI>**\fR, ! 2256: .IP f. ! 2257: the definition for the structure provided as the fourth argument, and ! 2258: .IP g. ! 2259: the result the function intends to return to use for \fI?\fR. ! 2260: .PP ! 2261: Four functions for running hooks are provided for the user, two ! 2262: for running slot hooks and base hooks for single items and two for ! 2263: running slot hooks and base hooks for pairs of items. ! 2264: \fBRunslothooks1\fR expects to be given the invoking function's ! 2265: name, the structure and name of the slot on which to run the slot ! 2266: hooks, and the value to be used for \fI*\fR. ! 2267: \fBRunslothooks2\fR expects to be given the invoking function's ! 2268: name, the two structures and name of the slot in them on which to ! 2269: run the slot hooks, and the values to be used for \fI*\fR and \fI>*\fR. ! 2270: \fBRunbasehooks1\fR expects to be given the invoking function's name ! 2271: and the structure whose base hooks are to be run. ! 2272: \fBRunbasehooks2\fR expects the invoking function's name, the two ! 2273: structures whose base hooks are to be run and the result the ! 2274: calling function plans to return. ! 2275: .PP ! 2276: If present, base hooks are run by most major PEARL functions. ! 2277: If a base hook is labelled with \fI<foo\fR then the function ! 2278: \fIfoo\fR will execute the hook just after entry and whatever ! 2279: initialization is necessary. ! 2280: If a base hook is labelled with \fI>foo\fR then the function \fIfoo\fR ! 2281: will execute the hook just before exitting. ! 2282: Slot hooks are run by most major PEARL functions which look through ! 2283: the slots of a structure. ! 2284: If a slot hook is labelled with \fI<foo\fR then the function \fIfoo\fR ! 2285: will execute the hook just before processing the slot. ! 2286: If a slot hook is labelled with \fI>foo\fR then the function \fIfoo\fR ! 2287: will execute the hook just after processing the slot. ! 2288: .PP ! 2289: However, hooks can be turned off selectively or completely. ! 2290: By setting the atoms \fB*runallslothooks*\fR and ! 2291: \fB*runallbasehooks*\fR to nil, you can completely disable ! 2292: the running of all hooks. ! 2293: This is useful for debugging and also helps improve efficiency ! 2294: a bit if you do not use hooks at all. ! 2295: There is also an atom to go with each PEARL function (of the form ! 2296: \fB*run...hooks*\fR) which can be used to disable hooks for selected ! 2297: functions. ! 2298: The following is a complete table of what PEARL functions run hooks ! 2299: and the names of the labels that invoke them and the atoms that ! 2300: control their running: ! 2301: .LD ! 2302: Base hooks are run by: \kminvoked by hooks labelled: ! 2303: create expanded \h'|\nmu'<expanded or >expanded ! 2304: create individual \h'|\nmu'<individual or >individual ! 2305: create pattern \h'|\nmu'<pattern or >pattern ! 2306: smerge \h'|\nmu'<smerge or >smerge ! 2307: nextitem \h'|\nmu'<nextitem or >nextitem ! 2308: standardfetch * \h'|\nmu'<fetch or >fetch ! 2309: expandedfetch * \h'|\nmu'<fetch or >fetch ! 2310: fetcheverywhere * \h'|\nmu'<fetch or >fetch ! 2311: insertdb \h'|\nmu'<insertdb or >insertdb ! 2312: removedb \h'|\nmu'<removedb or >removedb ! 2313: nextequal \h'|\nmu'<nextequal or >nextequal ! 2314: indb \h'|\nmu'<indb or >indb ! 2315: standardmatch \h'|\nmu'<match or >match ! 2316: basicmatch \h'|\nmu'<match or >match ! 2317: strequal \h'|\nmu'<strequal or >strequal ! 2318: _________ ! 2319: * \fIfetch\fR does not run hooks on function structures. ! 2320: .sp 2 ! 2321: Slot hooks are run by: \h'|\nmu'invoked by hooks labelled: ! 2322: standardmatch \h'|\nmu'<match or >match ! 2323: basicmatch \h'|\nmu'<match or >match ! 2324: strequal \h'|\nmu'<strequal or >strequal ! 2325: path put \h'|\nmu'<put or >put ! 2326: path clear \h'|\nmu'<clear or >clear ! 2327: path addset \h'|\nmu'<addset or >addset ! 2328: path delset \h'|\nmu'<delset or >delset ! 2329: path addpred \h'|\nmu'<addpred or >addpred ! 2330: path delpred \h'|\nmu'<delpred or >delpred ! 2331: path get \h'|\nmu'<get or >get ! 2332: path getpred \h'|\nmu'<getpred or >getpred ! 2333: path gethook \h'|\nmu'<gethook or >gethook ! 2334: path apply \h'|\nmu'<apply or >apply ! 2335: .sp 2 ! 2336: Hooks of both kinds are controlled by these atoms, initially t: ! 2337: *runallslothooks* -- controls all slot hooks. ! 2338: *runallbasehooks* -- controls all base hooks. ! 2339: *runputpathhooks* \h'|\nmu'*runclearpathhooks* ! 2340: *runaddsetpathhooks* \h'|\nmu'*rundelsetpathhooks* ! 2341: *runaddpredpathhooks* \h'|\nmu'*rundelpredpathhooks* ! 2342: *rungetpathhooks* \h'|\nmu'*rungetpredpathhooks* ! 2343: *rungethookpathhooks* \h'|\nmu'*runapplypathhooks* ! 2344: *runmatchhooks* \h'|\nmu'*runsmergehooks* ! 2345: *runindividualhooks* \h'|\nmu'*runexpandedhooks* ! 2346: *runpatternhooks* \h'|\nmu'*runnextitemhooks* ! 2347: *runfetchhooks* \h'|\nmu'*runinsertdbhooks* ! 2348: *runremovedbhooks* \h'|\nmu'*runindbhooks* ! 2349: *runnextequalhooks* \h'|\nmu'*runstrequalhooks* ! 2350: .DE ! 2351: .PP ! 2352: It is likely that hooks attached to a particular function would like to run ! 2353: the same function in such a way that hooks will not be invoked. ! 2354: Or in general, it is possible that you will want to run some PEARL function ! 2355: in such a way that it is "hidden" from hooks. ! 2356: To make this easy, a macro is provided called \fBhidden\fR which temporarily ! 2357: sets the atom \fI*run...hooks*\fR to nil, runs a command and then restores ! 2358: the former value of that atom. ! 2359: For this to work correctly, you \fBmust\fR invoke the function you wish hidden ! 2360: with the name corresponding to the "..." in its \fI*run...hooks*\fR atom. ! 2361: Thus, you can hide the creation of an individual from hooks by executing: ! 2362: .DS ! 2363: (hidden (individual PTrans ....) ) ! 2364: .DE ! 2365: (see Section 27 for the macro \fIindividual\fR) but \fBnot\fR by executing: ! 2366: .DS ! 2367: (hidden (create individual PTrans ....) ) ! 2368: .DE ! 2369: A parallel function \fBvisible\fR temporarily sets the associated ! 2370: atom to \fIt\fR before evaluating the function. ! 2371: .PP ! 2372: One of the reasons that hooks are checked for both before and after ! 2373: a PEARL function does its job is to provide the user with the ! 2374: opportunity to affect the result of the particular task. ! 2375: In the simplest case, a hook simply executes a piece of code ! 2376: and does not directly affect the function it is labelled with. ! 2377: However, if the value returned by a hook is a list whose \fIcar\fR ! 2378: is either \fB*done*\fR, \fB*fail*\fR, and \fB*use*\fR, then the action ! 2379: of that function will be modified. ! 2380: If the result of a hook which runs before the task starts with ! 2381: \fI*done*\fR, then the hook is presumed to have accomplished what the ! 2382: PEARL function was supposed to have done and the function will return ! 2383: immediately with the \fIcadr\fR of the hook's result if there is ! 2384: one, or else with the structure being operated on (for base hooks) ! 2385: or the value in the slot (for slot hooks). ! 2386: If the result of a hook which runs after the task starts with ! 2387: \fI*done*\fR, then the function will return immediately with the ! 2388: \fIcadr\fR of the hook's result if there is one, or else with ! 2389: the result that was going to be return anyway. ! 2390: .PP ! 2391: If the result of a hook which runs before the task starts with ! 2392: \fI*fail*\fR, then the hook is presumed to have determined that the ! 2393: PEARL function should quit and the function will return ! 2394: immediately with the \fIcadr\fR of the hook's result if there is one, ! 2395: or else with the atom \fI*fail*\fR. ! 2396: If the result of a hook which runs after the task starts with ! 2397: \fI*fail*\fR, then the function will return immediately with the ! 2398: \fIcadr\fR of the hook's result (which may be nil). ! 2399: .PP ! 2400: If the result of a hook which runs before the task starts with ! 2401: \fI*use*\fR, then the hook is presumed to have determined that the ! 2402: PEARL function should use a different value instead of the originally ! 2403: provided one and the function will use the \fIcadr\fR of the hook's ! 2404: result for the rest of the task. ! 2405: If the result of a hook which runs after the task starts with ! 2406: \fI*use*\fR, then the function will replace its intended result with ! 2407: the \fIcadr\fR of the hook's result (which may be nil). ! 2408: Thus, for example, a slot hook labelled with \fI<match\fR can ! 2409: short-circuit the matching of a slot and one labelled with ! 2410: \fI<match\fR can reverse the decision made by matching of a slot. ! 2411: Similarly, a base hook labelled with \fI<match\fR can use its own matching ! 2412: algorithm and one labelled with \fI>match\fR can modify the result of the ! 2413: whole match. ! 2414: .PP ! 2415: Obviously, these all should be used with great care. ! 2416: Note that \fIreturn immediately\fR means without even running ! 2417: any other slot hooks on that slot for slot hooks or without ! 2418: running any other base hooks on that structure for base hooks. ! 2419: .PP ! 2420: For example consider the case of a structure representing someone's ! 2421: order in a Chinese restaurant. ! 2422: As items are added to the order, it would be nice if there was a ! 2423: magical slot TotalBill that contained the current ! 2424: running total of the cost of the items ordered. ! 2425: Demons, being such magical creatures, fill the bill nicely. ! 2426: However, we only wish to have our demon-like hooks ! 2427: activated when particular slots are filled (added to or accessed). ! 2428: First consider the simple case in which an order consists of ! 2429: three items only, the name of the soup and one or two entrees: ! 2430: .DS ! 2431: (create base Chinese-Food-Entree ! 2432: (Name lisp) ! 2433: (Price int) ) ! 2434: .DE ! 2435: .DS ! 2436: (create base Chinese-Dinner-Order ! 2437: (Soup Chinese-Food-Entree) ! 2438: (Entree1 Chinese-Food-Entree) ! 2439: (Entree2 Chinese-Food-Entree) ! 2440: (TotalBill int) ) ! 2441: .DE ! 2442: .DS ! 2443: (create individual Chinese-Food-Entree ! 2444: (Name (Hot And Sour Soup) ) ! 2445: (Price 323) ) ! 2446: .DE ! 2447: .DS ! 2448: (create individual Chinese-Food-Entree ! 2449: (Name (Sizzling Rice Soup) ) ! 2450: (Price 349) ) ! 2451: .DE ! 2452: .DS ! 2453: (create individual Chinese-Food-Entree ! 2454: (Name (Lingnan Beef) ) ! 2455: (Price 399) ) ! 2456: .DE ! 2457: .DS ! 2458: (create individual Chinese-Food-Entree ! 2459: (Name (Mandarin Chicken) ) ! 2460: (Price 367) ) ! 2461: .DE ! 2462: .DS ! 2463: (create individual Chinese-Food-Entree ! 2464: (Name (Shrimp Cantonese) ) ! 2465: (Price 479) ) ! 2466: .DE ! 2467: .DS ! 2468: ; an undetermined meal is created. ! 2469: (create individual Chinese-Dinner-Order Meal ! 2470: (Soup ^ if >put (Maintain-Total * ** =TotalBill) ) ! 2471: (Entree1 ^ if >put (Maintain-Total * ** =TotalBill) ) ! 2472: (Entree2 ^ if >put (Maintain-Total * ** =TotalBill) ) ! 2473: (TotalBill 0) ) ! 2474: .DE ! 2475: Note that a slot hook is put after the value in a slot by using ! 2476: the word \fBif\fR (or \fBhook\fR) followed by the appropriate label ! 2477: for the invoking function followed by the function name or ! 2478: s-expression to be evaluated. ! 2479: Note also that when you want to put hooks on slots of an individual but ! 2480: do not want to specify a value, the use of \fB"^"\fR will instruct ! 2481: \fIcreate\fR to copy the default value instead. ! 2482: If the Maintain-Total function is properly specified, whenever ! 2483: one replaces one of the food slots with a real dish using ! 2484: the \fIputpath\fR function, the Maintain-Total function would be ! 2485: activated and would add the price of that meal to the running total ! 2486: in the TotalBill slot. ! 2487: If one changed one's mind a lot, it would be necessary to include ! 2488: another hook Remove-Price which would be activated by a \fIclearpath\fR. ! 2489: This would require adding the \fIif-cleared\fR hook ! 2490: \fI"if >clear Remove-Price"\fR after the \fIif-put\fR hook: ! 2491: .DS ! 2492: (create individual Chinese-Dinner-Order ChangingMeal ! 2493: (Soup ^ if >put (Maintain-Total * ** =TotalBill) ! 2494: if >clear (Remove-Price * ** =TotalBill) ) ! 2495: (Entree1 ^ if >put (Maintain-Total * ** =TotalBill) ! 2496: if >clear (Remove-Price * ** =TotalBill) ) ! 2497: (Entree2 ^ if >put (Maintain-Total * ** =TotalBill) ! 2498: if >clear (Remove-Price * ** =TotalBill) ) ! 2499: (TotalBill 0) ) ! 2500: .DE ! 2501: The code for the two hooks follows: ! 2502: .DS ! 2503: (de Maintain-Total (Food Meal CurrentMealTotal) ! 2504: (putpath Meal '(TotalBill) ! 2505: (*plus CurrentTotal ! 2506: (getpath Food '(Price) ) ) ) ) ! 2507: .DE ! 2508: .DS ! 2509: (de Remove-Price (Food Meal CurrentMealTotal) ! 2510: (putpath Meal '(TotalBill) ! 2511: (*plus CurrentTotal ! 2512: (getpath Food '(Price) ) ) ) ) ! 2513: .DE ! 2514: .PP ! 2515: A more flexible meal order structure would not have three slots ! 2516: for food, but rather a single slot of type \fIsetof struct\fR. ! 2517: Then entries would be added by the \fIaddsetpath\fR functions, ! 2518: and the \fIif-put\fR hook would be an \fIif-addset\fR hook but the ! 2519: code would essentially be the same. ! 2520: .PP ! 2521: To attach a base hook to a structure, the first "slot" in its definition ! 2522: must start with one of the atoms \fBif\fR or \fBhook\fR. ! 2523: The rest of the slot must then contain a sequence of labels for invoking ! 2524: functions and function names or s-expressions to be evaluated. ! 2525: For example, to invoke \fIvalprint\fR before and a user function called ! 2526: \fIverify\fR afterwards whenever a PTrans is inserted into the data base, ! 2527: you would define PTrans as follows: ! 2528: .DS ! 2529: (create base PTrans ! 2530: (if <insertdb (valprint * 5) ! 2531: >insertdb (verify *)) ! 2532: (* Actor symbol) ! 2533: ( Object symbol) ! 2534: ( From symbol) ! 2535: ( To symbol) ) ! 2536: .DE ! 2537: .PP ! 2538: Recall that PEARL provides a print function called \fBfullprint\fR ! 2539: which for most structures seen so far printed two extra \fInil\fRs ! 2540: in each slot. ! 2541: If a slot has predicates, the first \fInil\fR will be replaced by ! 2542: a list of them. ! 2543: If the slot has hooks, the second \fInil\fR will be ! 2544: replaced by a list of cons-cells with the invoking function in the ! 2545: \fIcar\fR and the hook in the \fIcdr\fR. ! 2546: .PP ! 2547: The invocation of hooks labelled with other forms of \fIpath\fR are similar ! 2548: except for \fIapply\fR. ! 2549: If \fI(path <apply Fcn ...)\fR or \fI(path >apply Fcn ...)\fR is executed, ! 2550: then any hooks which are labelled with Fcn will be run. ! 2551: .PP ! 2552: At this point the syntax of a slot in a definition or individual has become ! 2553: quite complicated, so we summarize with the following BNF grammar: ! 2554: .DS ! 2555: { a b c } means select one of a, b, or c. ! 2556: [ XXX ] means optionally XXX. ! 2557: XXX * means zero or more XXX's ! 2558: x | y means x or y ! 2559: .DE ! 2560: .ID ! 2561: <BaseSlot> ::= ( ! 2562: <HashLabels> ! 2563: <SlotName> ! 2564: <SlotType> ! 2565: <InheritOrValue> ! 2566: <AdjunctVariable> ! 2567: <PredicatesAndHooks> ! 2568: ) ! 2569: <IndividualSlot> ::= ( ! 2570: <SlotName> ! 2571: <InheritOrValue> ! 2572: <AdjunctVariable> ! 2573: <PredicatesAndHooks> ! 2574: ) ! 2575: <ExpandedSlot> ::= <BaseSlot> | <IndividualSlot> ! 2576: .sp 1 ! 2577: <HashLabels> ::= { "&" "^" "*" "**" ":" "::" ">" "<" } * ! 2578: <SlotType> ::= { "struct" "symbol" "int" "lisp" } | ! 2579: "setof" <SlotType> | <OrdinalName> | ! 2580: <StructureName> ! 2581: <InheritOrValue> ::= <Value> | "^" | "nil" | ! 2582: "==" <Value> | ":=" <Value> ! 2583: <Value> ::= <integer> | <atom> | <list> | <Variable> ! 2584: <AdjunctVariable> ::= [ ":" <Variable> ] ! 2585: <Variable> ::= ?<atom> ! 2586: <PredicatesAndHooks> ::= { <Predicate> | <Hook> } * ! 2587: <Predicate> ::= <StructureName> | <S-Expression> ! 2588: <Hook> ::= "if" <atom> <HookFunction> ! 2589: <HookFunction> ::= <atom> | <S-Expression> ! 2590: .DE ! 2591: .NH ! 2592: Creating and Manipulating Multiple Data Bases ! 2593: .PP ! 2594: Without any effort on the user's part, a single data base of a ! 2595: default size exists in PEARL when it starts up. ! 2596: It is called \fB*maindb*\fR and is pointed to by the special ! 2597: variable \fB*db*\fR which is assumed by all functions which use a ! 2598: data base to point to the default data base (that is, the data ! 2599: base to be used when an expected data base argument is missing). ! 2600: .PP ! 2601: To build another data base, choose a name for it and call the ! 2602: function \fBbuilddb\fR which is an nlambda (fexpr) expecting ! 2603: the name of the new data base. ! 2604: You may build as many as you wish and store whichever one you want ! 2605: in \fI*db*\fR. ! 2606: .PP ! 2607: Sometimes one may wish to clear out the data base and start out with a ! 2608: clean slate. ! 2609: To make this easy, there is a special function \fBcleardb\fR ! 2610: which expects either zero or one data bases as arguments ! 2611: and does the job. ! 2612: If it receives no arguments, then the default data base is cleared. ! 2613: \fICleardb\fR removes everything from the data base, ! 2614: but does not actually delete (or reclaim the storage space of) the ! 2615: objects within the data base. ! 2616: But if the objects inside are not pointed to by any program ! 2617: variables, they are gone for good. ! 2618: (\fICleardb\fR clears out \fIonly\fR the named data base and not ! 2619: data bases that it may be built upon as described in the next section.) ! 2620: .PP ! 2621: Data bases contain two parts, referred to as \fIdb1\fR and \fIdb2\fR. ! 2622: \fIDb1\fR contains items which are indexed under only their type ! 2623: or using single-colon hashing. ! 2624: Its default size is 29. ! 2625: \fIDb2\fR contains items which are indexed under two or three ! 2626: values. ! 2627: Its default size is 127. ! 2628: These sizes are chosen to be prime numbers which are just barely ! 2629: smaller than a power of two. ! 2630: (This choice was made to take full advantage of hunks in Franz Lisp ! 2631: which are always allocated to be a power of two.) ! 2632: The ratio between the two sizes is approximately 1 to 4. ! 2633: The size for data bases may be chosen by specifying the ! 2634: power of two that you wish \fIdb2\fR to close to. ! 2635: .PP ! 2636: The function \fBsetdbsize\fR expects an integer between 2 and 13 ! 2637: representing the power to which two should be raised. ! 2638: The default data base size is thus the result of calling ! 2639: \fIsetdbsize\fR with an argument of 7. ! 2640: To change the default size, you should call \fIsetdbsize\fR ! 2641: in your \fI.init.prl\fR file, before creating any data bases of your ! 2642: own. ! 2643: \fISetdbsize\fR rebuilds \fI*maindb*\fR (without putting ! 2644: anything into the new one) and releases all other data bases. ! 2645: Thus, it should not \fInormally\fR be used at any time after the ! 2646: processing of the \fI.init.prl\fR file. ! 2647: (In the Franz Lisp version, although this full range of values is ! 2648: accepted, the largest a data base in the 1 to 4 ratio can be ! 2649: is 29 + 127 since hunks are limitted to 128 words. ! 2650: However, an argument of 9 to \fIsetdbsize\fR will set the sizes ! 2651: of both data bases to 127.) ! 2652: Related special variables are \fB*db1size*\fR and ! 2653: \fB*db2size*\fR which are set by \fIsetdbsize\fR and ! 2654: \fB*availablesizes*\fR which contains the assoc-list used ! 2655: to associate the power of two to a size. ! 2656: .NH ! 2657: Creating a Forest of Data Bases ! 2658: .PP ! 2659: Although having multiple data bases which are unconnected is often ! 2660: enough, it is sometimes convenient to build onto an already ! 2661: existing data base in a tree-like fashion. ! 2662: For example, in a story understanding program, one might want ! 2663: to have the default data base containing long-term knowledge ! 2664: and then add a data base to contain the knowledge specific to a ! 2665: particular story being processed. ! 2666: In large applications, it can also help to split up special kinds ! 2667: of knowledge to improve efficiency even more than PEARL's hashing ! 2668: already does. ! 2669: With only the ability to build separate data bases, searching for ! 2670: a fact which might be either general knowledge or specific ! 2671: knowledge learned from the story would require two fetches, one ! 2672: from each data base. ! 2673: However, if the story data base is built on top of the main data ! 2674: base then simply fetching an item from the story data base will ! 2675: also include fetching from the main data base. ! 2676: To build another data base upon an existing one, use the function ! 2677: \fBbuilddb\fR with two arguments, the name of the new data base ! 2678: and the name of the old one to build onto: ! 2679: .DS ! 2680: (builddb *story* *maindb*) ! 2681: (builddb *future* *maindb*) ! 2682: .DE ! 2683: These two statements will build two data bases on top of the main ! 2684: one such that fetching from *story* will look both in it and in ! 2685: *maindb* but not in *future*. ! 2686: You can then build further upon any of these if you wish. ! 2687: Note however, that the second argument must be \fIthe name of the ! 2688: data base to build upon\fR and cannot be \fI*db*\fR to build upon ! 2689: the default data base. ! 2690: Also, if the second argument is missing, then the new data base is ! 2691: isolated, not built on top of the default data base. ! 2692: .PP ! 2693: If your program builds many data bases, it is likely that some of ! 2694: them will be temporary ones. ! 2695: If this is so, it is possible to release a data base so that the ! 2696: space can be garbage collected or reused for a later data base. ! 2697: To release a data base, pass the actual data base (not its name) ! 2698: to the function \fBreleasedb\fR. ! 2699: If the data base is not a leaf of the data base tree, then the ! 2700: space will not actually be released until all its children ! 2701: are released also but PEARL will no longer accept it as a data ! 2702: base argument. ! 2703: .PP ! 2704: A list of the names of the currently active data bases is ! 2705: maintained by PEARL in the special variable \fB*activedbnames*\fR. ! 2706: .NH ! 2707: Creating Expanded Subtypes of Previously Defined Objects ! 2708: .PP ! 2709: Within CD, as in many applications, you may have many different structures ! 2710: with some slots with the same name. ! 2711: PEARL allows this, as it can always tell which type of structure ! 2712: you are using, and thus it behaves just as if you had used ! 2713: unique names for all slots. ! 2714: But sometimes the fact that two different structure types have ! 2715: slots with the same names is more than a coincidence: ! 2716: there may be various semantic similarities ! 2717: between the similar parts of the two structures. ! 2718: PEARL has a mechanism for creating such structures using the ! 2719: \fBexpanded\fR selector to \fIcreate\fR. ! 2720: Basically, you must first define a base structure that contains ! 2721: all the identical parts of two or more structures, and then you ! 2722: must define the structures themselves as \fIthe base plus the differences\fR. ! 2723: A good example of this from CD involves Acts. ! 2724: All Acts within CD have an Actor slot, and all of ! 2725: these slots have the same meaning. ! 2726: That is, whatever is going on, the person in the actor slot is the ! 2727: motivating force. ! 2728: So we may first define this common part as a normal ! 2729: base structure: ! 2730: .DS ! 2731: (create base Act ! 2732: (* Actor symbol) ) ! 2733: .DE ! 2734: and then we can define the various acts as expansions upon this base: ! 2735: .DS ! 2736: (create expanded Act PTrans ! 2737: (Object symbol) ! 2738: (From symbol) ! 2739: (To symbol) ) ! 2740: .DE ! 2741: .DS ! 2742: (create expanded Act MTrans ! 2743: (MObject struct) ! 2744: (From symbol) ! 2745: (To symbol) ) ! 2746: .DE ! 2747: .DS ! 2748: (create expanded Act ATrans ! 2749: (Object symbol) ! 2750: (From symbol) ! 2751: (To symbol) ) ! 2752: .DE ! 2753: .DS ! 2754: (create expanded Act Injest ! 2755: (Object symbol) ! 2756: (Through symbol) ) ! 2757: .DE ! 2758: Note that we did \fBnot\fR have to list the Actor slot, ! 2759: it was \fBinherited\fR from the base structure Act. ! 2760: The structure to be expanded need not be a base structure, ! 2761: but could itself be an \fIexpanded\fR structure. ! 2762: Thus we can capture the similarities of the various Transfers with: ! 2763: .DS ! 2764: (create expanded Act Trans ! 2765: (From symbol) ! 2766: (To symbol) ) ! 2767: .DE ! 2768: followed by ! 2769: .DS ! 2770: (create expanded Trans PTrans ! 2771: (Object symbol) ) ! 2772: .DE ! 2773: .DS ! 2774: (create expanded Trans MTrans ! 2775: (MObject symbol) ) ! 2776: .DE ! 2777: .DS ! 2778: (create expanded Trans ATrans ! 2779: (Object symbol) ) ! 2780: .DE ! 2781: In expanded definitions as in base definitions one can ! 2782: specify hashing and default information in the usual way. ! 2783: However one can selectively inherit some of this ! 2784: information from the structure being expanded. ! 2785: Thus in our first Act example, since we specified star hashing on the ! 2786: Actor slot, all the structures that we defined in terms of Act ! 2787: have star hashing on their Actor slot by default. ! 2788: If we had not wanted this for ATrans, we could have specified this ! 2789: simply by listing the Actor slot over again without the asterisk. ! 2790: However, since PEARL requires old slots in expanded structures ! 2791: to also provide a new value, we need some way to say \fIinherit the ! 2792: same old value\fR. ! 2793: This is done by putting an up-arrow \fB"^"\fR where PEARL expects ! 2794: to find a value, just as when you want to inherit the default ! 2795: value but add hooks or predicates when creating individuals. ! 2796: .DS ! 2797: (create expanded Act ATrans ! 2798: (Actor ^) ! 2799: (From symbol) ) ! 2800: .DE ! 2801: We also could have added colon hashing to the Actor slot by ! 2802: listing it above as normal. ! 2803: However, we cannot change the type of a slot and including a type ! 2804: name after \fIActor\fR will cause PEARL to try to interpret that ! 2805: type name as a value, (resulting in any of several errors, ! 2806: depending on the type). ! 2807: Thus, the hashing information for any slot is inherited from ! 2808: above, \fIunless\fR it the slot appears in the expanded structure. ! 2809: .PP ! 2810: Default values are inherited in almost the same way. ! 2811: The exception is that if in the original structure ! 2812: the default is preceded by the symbol \fB":="\fR (rather than being ! 2813: preceded by either nothing or the symbol \fB"=="\fR), expansions of that ! 2814: structure will not inherit this value, but instead will get the ! 2815: standard default for that type. ! 2816: So if one defines: ! 2817: .DS ! 2818: (symbol Pandora) ! 2819: .DE ! 2820: .DS ! 2821: (create base Act ! 2822: (Actor symbol Pandora) ) ! 2823: ! 2824: or ! 2825: .DE ! 2826: .DS ! 2827: (create base Act ! 2828: (Actor symbol == Pandora) ) ! 2829: .DE ! 2830: .DS ! 2831: (create expanded Act PTrans ! 2832: (From symbol) ) ! 2833: .DE ! 2834: then all PTranses will have Pandora as their default Actor, whereas with: ! 2835: .DS ! 2836: (create base Act ! 2837: (Actor symbol := Pandora) ) ! 2838: .DE ! 2839: .DS ! 2840: (create expanded Act PTrans ! 2841: (From symbol) ) ! 2842: .DE ! 2843: only the default instance of Act will have Pandora in its Actor ! 2844: slot and the default Actor of PTrans will just be the usual ! 2845: default for \fIsymbol\fR-valued slots which is \fInilsym\fR. ! 2846: Which type of default inheritance to use depends upon the ! 2847: application, and must be decided on a case by case basis. ! 2848: .PP ! 2849: Given this hierarchy, it is often useful to check whether an ! 2850: object is of a certain type or an expanded version of it. ! 2851: Two functions provide this ability with slightly different ! 2852: arguments. ! 2853: \fBIsa\fR expects an item and the name of the type you want to ! 2854: check for. ! 2855: \fBIsanexpanded\fR expects two instances. ! 2856: Thus the following are always true for any structure X: ! 2857: .DS ! 2858: (isa X (pname X)) ! 2859: (isanexpanded X X) ! 2860: .DE ! 2861: Two related functions are \fBnullstruct\fR and \fBnullsym\fR which ! 2862: are functions for testing for \fInilstruct\fR and \fInilsym\fR ! 2863: (similar to \fInull\fR for \fInil\fR). ! 2864: .NH ! 2865: Fetching Expanded Structures ! 2866: .PP ! 2867: To make the extra information that \fIexpanded\fR structures provide ! 2868: more useful, a special version of \fIfetch\fR called \fBexpandedfetch\fR ! 2869: is provided which takes the hierarchy of structures defined into ! 2870: account when fetching. ! 2871: For example, using the above hierarchical ! 2872: definitions of Act, Trans, PTrans, MTrans, and ATrans, you can insert ! 2873: three different Transes into the data base: ! 2874: .DS ! 2875: (dbcreate individual PTrans ! 2876: (Actor Pandora) ! 2877: (Object Pandora) ) ! 2878: .DE ! 2879: .DS ! 2880: (dbcreate individual MTrans ! 2881: (Actor Pandora) ! 2882: (To Pandora) ) ! 2883: .DE ! 2884: .DS ! 2885: (dbcreate individual ATrans ! 2886: (Actor Pandora) ! 2887: (From Pandora) ) ! 2888: .DE ! 2889: and then to fetch all Transes performed by Pandora, you could use: ! 2890: .DS ! 2891: (create pattern Trans TransPattern ! 2892: (Actor Pandora) ) ! 2893: .DE ! 2894: .DS ! 2895: (expandedfetch TransPattern) ! 2896: .DE ! 2897: Once you start using expanded structures, you usually want to be ! 2898: able to use the function name \fIfetch\fR and mean \fIexpandedfetch\fR. ! 2899: To this end, the standard fetch function is actually called ! 2900: \fBstandardfetch\fR. ! 2901: This leaves the function \fBfetch\fR to be bound to whichever ! 2902: fetch function you wish. ! 2903: It is initially given the same function definition as ! 2904: \fIstandardfetch\fR. ! 2905: .NH ! 2906: How Two Objects Match ! 2907: .PP ! 2908: When a fetch from the data base is performed, the pattern provided ! 2909: is only used to construct a stream containing that pattern and the ! 2910: appropriate hash bucket from the data base; ! 2911: no matching (comparing) ! 2912: between the pattern and objects in the data base occurs. ! 2913: Thus the stream contains pointers to all data base items in the ! 2914: same hash bucket, regardless of their likelihood of ! 2915: matching the pattern. ! 2916: When elements are extracted from the stream with the function ! 2917: \fInextitem\fR, the pattern is "matched" against successive ! 2918: items from the hash bucket until one matches (and is returned) ! 2919: or until the potential items run out (and \fInil\fR is returned). ! 2920: .NH 2 ! 2921: When Is a Pattern Not a Pattern? ! 2922: .PP ! 2923: To understand the process with which two objects are ! 2924: matched, it is necessary to understand what is meant by ! 2925: a \fIpattern\fR in the context of matching. ! 2926: The term \fIpattern\fR has been used in two ways in PEARL. ! 2927: It has been used previously in this documentation in ! 2928: a specialized sense which is only relevant in the context ! 2929: of creating a \fIpattern\fR. ! 2930: The use of the \fIpattern\fR selector to \fIcreate\fR is simply a ! 2931: variation on \fIcreate individual\fR which uses the match-anything ! 2932: variable ?*any* as the default for unspecified slots instead ! 2933: of the usual default values (either the one inherited from the ! 2934: base definition or the default for the type of slot). ! 2935: It is called creating a \fIpattern\fR because the ! 2936: change of default is usually only useful for constructing a pattern. ! 2937: .PP ! 2938: However, the use of the function \fIcreate\fR with object ! 2939: selector \fIpattern\fR is \fBnot\fR the only way to create a ! 2940: pattern which can be matched; ! 2941: in fact, it is only useful for ! 2942: forming simple patterns. ! 2943: \fBAny\fR individual structure in PEARL can be used as a pattern. ! 2944: If a fully specified structure (that is, one with an actual value ! 2945: in all of its slots) is used as a pattern for fetching, it will ! 2946: only match objects which are equal to it in a manner similar to ! 2947: \fIequal\fR (versus \fIeq\fR) in Lisp. ! 2948: (An exception to this occurs when patterns with pattern-matching ! 2949: variables are stored in the data base.) ! 2950: Thus a fully specified pattern is only useful for ! 2951: determining whether a particular fact (object) is in the data base. ! 2952: Any object is a pattern but the interesting patterns will not ! 2953: be fully specified; ! 2954: rather, they will have unspecified slots ! 2955: which contain pattern-matching variables instead of values. ! 2956: The details of the matching process will now be described. ! 2957: .NH 2 ! 2958: The Matching Process ! 2959: .PP ! 2960: In general, the matching procedure takes two structures and either, ! 2961: neither or both may contain pattern-matching variables. ! 2962: So conceptually, both are patterns. ! 2963: If the structures are not definitionally the same type ! 2964: then the match fails automatically. ! 2965: Otherwise, each structure is viewed as a sequence of slots ! 2966: which are successively "matched" between the two structures. ! 2967: Two structures of the same type match if and only if each of ! 2968: their slots "matches" the corresponding slot of the other structure. ! 2969: Each slot is of one of four types (\fIstruct\fR, \fIsymbol\fR, \fIint\fR, ! 2970: or \fIlisp\fR), or is a \fIsetof\fR one of these types. ! 2971: Regardless of its type, each slot is filled in one of four ways: ! 2972: .IP (1) ! 2973: The slot may contain an actual value of its type (for example, ! 2974: a slot of type \fIstruct\fR may contain a PTrans). ! 2975: .IP (2) ! 2976: The slot may contain a variable which is local to the structure ! 2977: (pattern-matching variables are local unless otherwise specified). ! 2978: .IP (3) ! 2979: The slot may contain a global variable, declared previously by a ! 2980: call to the function \fIglobal\fR with the variable's name as argument. ! 2981: .IP (4) ! 2982: The slot may contain the special match-anything variable ?*any*. ! 2983: .LP ! 2984: If the slot contains a variable (other than ?*any*) which has not ! 2985: been bound then it may become bound as a side effect of the ! 2986: matching process. ! 2987: All local pattern-matching variables are unbound at the start ! 2988: of the matching process. ! 2989: When a local variable is bound to a real ! 2990: value during the matching process (it will never be bound to a ! 2991: variable), it will not be unbound again but for the purposes of ! 2992: matching will be treated as if the slot were filled with that value. ! 2993: .PP ! 2994: Let us now examine each of the pairings of slot values ! 2995: which may occur and how they are matched. ! 2996: If either of the two slots being matched contains the ! 2997: special variable ?*any*, then the slots match by definition, ! 2998: regardless of the contents of the other slot. ! 2999: If both slots contain variables that are unbound, the slots ! 3000: do not normally match, (even if the two variables are textually ! 3001: the same name). ! 3002: (Since some users want two unbound variables to match, ! 3003: the value to be returned in this case is stored in the ! 3004: special variable \fB*matchunboundsresult*\fR whose ! 3005: initial value is \fInil\fR. ! 3006: Setting this variable to non-\fInil\fR will cause two unbound ! 3007: variables to match immediately but will not cause their ! 3008: predicates to be run.) ! 3009: If one slot contains an unbound variable (and the other ! 3010: a bound variable or a value), then the predicates and ! 3011: restrictions of the slot with the unbound variable are ! 3012: tested, and hooks on that slot labelled ! 3013: with \fImatch\fR are run to see if the unbound variable ! 3014: should be bound to the bound value. ! 3015: If so, then the unbound variable is bound to the value ! 3016: of the other slot, and the two slots match. ! 3017: Note that only the predicates and hooks on the ! 3018: structure containing the unbound variable are run while ! 3019: the symbols *, **, and =<slotname> refer to the other ! 3020: structure (with the bound value in it). ! 3021: If the predicates or restrictions return \fInil\fR, ! 3022: the two slots do not match, the variable ! 3023: is not bound, and the entire match fails. ! 3024: .PP ! 3025: If both slots contain either bound variables or values, then the values ! 3026: of the two slots are compared. If the slot is of type \fIstruct\fR, ! 3027: then the entire matching algorithm is recursively applied. ! 3028: If the slot is of types \fIint\fR or \fIlisp\fR, ! 3029: then \fIequal\fR is used. ! 3030: If the type is \fIsymbol\fR, then the two values must ! 3031: be the same symbol. ! 3032: Regardless of the type, restrictions associated with the slot ! 3033: are executed until one fails or there are no more to run. ! 3034: All must succeed for the match to succeed. ! 3035: If the match succeeds, then any hooks ! 3036: with the label \fImatch\fR are run. ! 3037: .PP ! 3038: The difference between the two types of variables is one of scope. ! 3039: Normal variables (for PEARL) do not need to be declared, and ! 3040: may be used in any structure by typing in \fI?<var>\fR during a ! 3041: \fIcreate\fR (note that \fIputpath\fR is incapable of ! 3042: installing variables). ! 3043: The scope of these variables is only over the structure ! 3044: in which they are typed. ! 3045: Thus the variable \fI?V\fR typed into two different creations of ! 3046: structures are in no way connected (in the same manner as two ! 3047: local variables V in different Pascal subroutines are unrelated.) ! 3048: If one becomes bound, the other is unaffected. ! 3049: On the other hand, if a variable name is previously declared ! 3050: as \fBglobal\fR: ! 3051: .DS ! 3052: (global G) ! 3053: .DE ! 3054: then all instances of the variable name ?G are the same ! 3055: (similar to global variables in Pascal). ! 3056: The list of global variables is kept in the special variable \fB*globallist*\fR. ! 3057: .PP ! 3058: As mentioned before, when two structures are matched, all ! 3059: normal (local) variables in both structures are unbound ! 3060: (bound to the value \fI*pearlunbound*\fR) before any ! 3061: slots are compared. ! 3062: This is to ensure that any bindings induced by a previous ! 3063: unsuccessful (or successful for that matter) match are removed. ! 3064: This rule is useful because the type of matching that ! 3065: early PEARL users have needed is in matching most ! 3066: patterns against fully-specified values (that is, cases ! 3067: in which one slot is always bound and the other either ! 3068: bound or unbound). ! 3069: Global variables are \fBnot\fR unbound before each match, ! 3070: so they can be used to reflect global contexts. ! 3071: They are given the value *\fIpearlunbound*\fR at the ! 3072: time they are declared and remain bound thereafter unless ! 3073: explicitly unbound by the user. ! 3074: To unbind a global variable, you may use use the function ! 3075: \fBunbind\fR, a fexpr which requires ! 3076: the name of a (previously declared) global variable: ! 3077: .DS ! 3078: (unbind G) ! 3079: .DE ! 3080: or use \fIsetq\fR and the function \fBpunbound\fR which ! 3081: simply returns the atom \fI*pearlunbound*\fR: ! 3082: .DS ! 3083: (setq G (punbound) ) ! 3084: .DE ! 3085: The function \fBpboundp\fR will test the value of a Lisp ! 3086: (not PEARL) variable to see if it is \fI*pearlunbound*\fR. ! 3087: The function \fBglobalp\fR will determine whether the variable ! 3088: passed to it has been declared global. ! 3089: .PP ! 3090: Global variables should be used with care so that ! 3091: they are not set by unsuccessful matches. ! 3092: Generally this is achieved by first collecting the value ! 3093: desired into a local variable via a series of matches ! 3094: (only the last of which succeed), and then using the result of ! 3095: this success to cause a further action which is guaranteed to ! 3096: correctly bind the value of the global variable. ! 3097: (These actions may be hooks which rebind the global ! 3098: variable every time the local one is bound. ! 3099: Effectively, this is a way to say \fIalways unbind this particular ! 3100: global variable before matches\fR. ! 3101: The action also could be performed by the user's program ! 3102: when the right value is found.) ! 3103: .PP ! 3104: Each structure or tree of structures built by a call to \fIcreate\fR ! 3105: constructs an individual assoc(association)-list of all the local ! 3106: variables in that structure. ! 3107: This assoc-list is stored with the root of the tree, thus ! 3108: achieving local uniqueness of variables within a structure. ! 3109: Global variables are bound values of the Lisp atom of ! 3110: the same name and are accessed in the usual way. ! 3111: To access the value of a local variable in a structure, ! 3112: one uses either the function \fBvalueof\fR (which is an expr) ! 3113: or the fexpr \fBvarvalue\fR both of which have two ! 3114: arguments: the name of the variable whose value ! 3115: you want and the structure it occurs in (evaluated internally by ! 3116: \fIvarvalue\fR). ! 3117: For example, to get the value of ?G in X, use either of: ! 3118: .DS ! 3119: (valueof 'G X) ! 3120: (varvalue G X) ! 3121: .DE ! 3122: Thus PEARL uses both deep and shallow binding. ! 3123: .PP ! 3124: The match algorithm is available to the user as a ! 3125: separate function by the name \fBstandardmatch\fR. ! 3126: This function unbinds all local variables before ! 3127: proceeding with the match (using the macro \fBunbindvars\fR) ! 3128: and again afterwards if the match failed. ! 3129: A function which assumes that all local variables have been ! 3130: unbound already and proceeds just as \fIstandardmatch\fR ! 3131: would is \fBbasicmatch\fR. ! 3132: The function name used to access the matching function by ! 3133: \fInextitem\fR and all other built-in PEARL functions is ! 3134: \fBmatch\fR which is normally given the same function definition ! 3135: as \fIstandardmatch\fR but can be bound to whichever match function ! 3136: you wish. ! 3137: A function which compares two structures for equality without ! 3138: affecting the values of their variables is available as ! 3139: \fBstrequal\fR. ! 3140: Since it does not bind variables, it also does not execute ! 3141: predicates although it does run base hooks and slot hooks labelled ! 3142: with \fIstrequal\fR. ! 3143: A function parallel to \fInextitem\fR which uses \fIstrequal\fR ! 3144: instead of \fImatch\fR is available as \fBnextequal\fR. ! 3145: .PP ! 3146: This rest of this section covers other ways to access and affect ! 3147: the values of variables. ! 3148: It will make more sense after reading the next section on blocks ! 3149: but fits in better here so you should probably leave it for your ! 3150: second reading. ! 3151: .PP ! 3152: Recall that the question mark read macro expands into either ! 3153: \fI(*var* <varname>)\fR or \fI(*global* <varname>)\fR. ! 3154: These two forms are not normally meant to be evaluated. ! 3155: However, for convenience, there are two functions \fB*var*\fR and ! 3156: \fB*global*\fR which return the value of the variable whose name ! 3157: is their argument. ! 3158: That is, if \fI?X\fR expands into \fI(*global* X)\fR, executing it ! 3159: will returned the value of the atom X. ! 3160: Thus \fIX\fR and \fI?X\fR are equivalent for a global variable. ! 3161: For a local or lexically scoped variable, in which \fI?X\fR ! 3162: expands into \fI(*var* X), the function \fI*var*\fR looks in ! 3163: three places for a variable with the name \fIX\fR. ! 3164: .IP 1. ! 3165: First it looks to see if the special variable ! 3166: \fB*currentstructure*\fR has been bound to a structure by ! 3167: the user, and if so, looks in its variable list. ! 3168: .IP 2. ! 3169: If this fails, it looks in the special variable ! 3170: \fB*currentpearlstructure*\fR for a structure. ! 3171: This variable is set by various PEARL functions like ! 3172: \fIcreate\fR, \fIfetch\fR, \fIpath\fR, and \fInextitem\fR ! 3173: to the top level structure they last operated on. ! 3174: .IP 3. ! 3175: If this fails, it looks in the currently open block on ! 3176: top of \fI*blockstack*\fR if there is one. ! 3177: .IP 4. ! 3178: If this fails, it returns \fInil\fR. ! 3179: .LP ! 3180: Note that the atom \fI*currentstructure*\fR is there simply for ! 3181: the use of the user and is never set by PEARL. ! 3182: .PP ! 3183: A related function is \fBsetv\fR which takes a question-mark ! 3184: variable, a value and an optional environment and sets that ! 3185: variable in that environment or else in the default environment ! 3186: described above to that value. ! 3187: The environment can be either a structure or a block. ! 3188: This stops with an error message if it fails to find a variable ! 3189: by that name in the specified or default environment. ! 3190: .NH ! 3191: Binding Blocks of Structures Together Via Common Variables ! 3192: .PP ! 3193: It is sometimes the case that you wish to create a group of ! 3194: structures which are closely related in some way and which you ! 3195: wish to tie together via pattern-matching variables. ! 3196: For example, a \fIframe\fR might be considered such a loosely ! 3197: connected group of structures. ! 3198: In this case what is desired is for the pattern-matching variables ! 3199: to \fIactually be the same\fR. ! 3200: Normally however, if you create several structures in PEARL with ! 3201: variables having the same name, each has its own local variable ! 3202: with that name and they are totally unrelated. ! 3203: If on the other hand, you declared them to be global, then all ! 3204: structures having variables with that name would refer to the same ! 3205: variable and it would no be unbound before matching. ! 3206: For this purpose, PEARL provides variables of an intermediate ! 3207: nature which are local to only a small group of structures and ! 3208: which are all unbound before any one of the structures takes ! 3209: parting in matching. ! 3210: .PP ! 3211: These variables are called \fBlexically scoped\fR (although if ! 3212: the related functions \fIblock\fR and \fIendblock\fR are called ! 3213: dynamically, they also provide a breed of dynamic scoping). ! 3214: To declare a set of lexically-scoped variables, thus opening a ! 3215: (nested) scope for them, use the function \fBblock\fR, ! 3216: so named because of the similarity to the concept of a block ! 3217: in Algol-like languages. ! 3218: The function \fIblock\fR is a fexpr which in its simplest form ! 3219: expects one argument which should be a list of new variables: ! 3220: .DS ! 3221: (block (A B C)) ! 3222: .DE ! 3223: Such a call to \fIblock\fR creates an unnamed block containing ! 3224: these variables and any occurrences of variables with these ! 3225: names in any structures \fIcreated\fR after this call will ! 3226: refer to these lexically-scoped variables. ! 3227: Thus, no structure created after the above call to \fIblock\fR ! 3228: can contain a local variable called A, B, or C. ! 3229: (However, if a variable has been previously declared to be global ! 3230: this overrides \fBall\fR future declarations with \fIblock\fR. ! 3231: Once again, global pattern-matching variables are to be ! 3232: used with \fIextreme caution\fR.) ! 3233: .PP ! 3234: If you use several blocks, especially nested blocks, ! 3235: it is helpful to give them names. ! 3236: For this purpose, \fIblock\fR will accept two arguments, the first ! 3237: an atom to name the block and the second the list of new variables. ! 3238: For example: ! 3239: .DS ! 3240: (block Name (A B C)) ! 3241: .DE ! 3242: .PP ! 3243: To end the most recent block, use the fexpr \fBendblock\fR. ! 3244: This function accepts any of three types of arguments. ! 3245: If last block was unnamed, simply use: ! 3246: .DS ! 3247: (endblock) ! 3248: .DE ! 3249: If the last block was named, you must provide \fIendblock\fR ! 3250: with this name: ! 3251: .DS ! 3252: (endblock Name) ! 3253: .DE ! 3254: This is provided as a protection against unbalanced calls to ! 3255: \fIblock\fR and \fIendblock\fR. ! 3256: If you wish to end the most recent block, regardless of what ! 3257: its name is, use ! 3258: .DS ! 3259: (endblock *) ! 3260: .DE ! 3261: To end several blocks at once, you can use the fexpr ! 3262: \fBendanyblocks\fR which ends all blocks back through ! 3263: the one whose name matches its argument. ! 3264: Again no argument (\fInil\fR) means the last unnamed block. ! 3265: An argument of \fB"*"\fR causes PEARL to end all currently ! 3266: open blocks. ! 3267: A shorthand for \fI(endanyblocks *)\fR is \fB(endallblocks)\fR. ! 3268: .PP ! 3269: The function \fIblock\fR builds an assoc-list of ! 3270: the variables listed. ! 3271: If the block is nested, the assoc-list of the enclosing block is ! 3272: hooked to the end of its assoc-list, thus providing a complete ! 3273: assoc-list of all the variables available in the block. ! 3274: A side effect of \fIblock\fR is that this assoc-list is bound to ! 3275: the name of the block. ! 3276: The block itself (the block's name plus this assoc-list) is available ! 3277: as \fIb:<blockname>\fR so that the above call to block binds ! 3278: \fIName\fR to ! 3279: .DS L ! 3280: ((A . *pearlunbound*) (B . *pearlunbound*) (C . *pearlunbound*)) ! 3281: .DE ! 3282: and \fIb:Name\fR to ! 3283: .DS ! 3284: (Name (A . *pearlunbound*) (B . *pearlunbound*) ! 3285: (C . *pearlunbound*)) ! 3286: .DE ! 3287: If a block is unnamed, PEARL calls it \fIunnamedblock\fR and the ! 3288: corresponding variables are set. ! 3289: The special variable \fB*blockstack*\fR contains a stack of all the ! 3290: currently active blocks. ! 3291: The effect of ending a block is to pop it off this stack. ! 3292: Once a block is closed, it is still accessible through the Lisp ! 3293: variable \fIb:<blockname>\fR. ! 3294: Given the name of a block, the function \fBblockatom\fR will build ! 3295: this atom for you. ! 3296: .PP ! 3297: It is possible to return to the scope of an earlier block with the ! 3298: fexpr \fBsetblock\fR which expects the name of a named block. ! 3299: This will have the effect of ending all currently open blocks and ! 3300: setting the current block stack to contain this block. ! 3301: Note that this block will contain all the variables of any blocks ! 3302: it is nested in but that it is not possible to close off these ! 3303: block selectively. ! 3304: Thus, the block stack will contain only one block with all the ! 3305: variables in its complete assoc-list. ! 3306: .NH ! 3307: Controlling the Unbinding of Variables by Match ! 3308: .PP ! 3309: It is sometimes desireable to use the filled-in result pattern ! 3310: of a \fIfetch\fR or \fImatch\fR as a pattern for a further ! 3311: \fIfetch\fR (or \fImatch\fR) or to otherwise store and restore ! 3312: the current values of variables (for example, to allow ! 3313: backtracking algorithms and/or hypothetical assertions). ! 3314: Since all bound local variables would normally be unbound during this ! 3315: further fetching or matching, this would not be possible given the ! 3316: mechanism described so far. ! 3317: To accomplish this action, which can be considered as "pushing" ! 3318: the context of the current assoc-list, ! 3319: you should use one of several functions provided for this purpose. ! 3320: The function \fBfreezebindings\fR takes a structure as argument ! 3321: and moves all bound variables from its normal assoc-list to a ! 3322: backup so that \fIfetch\fR will not unbind them. ! 3323: The function \fBthawbindings\fR takes a structure as argument and ! 3324: will undo this action, restoring the assoc-list to its complete state. ! 3325: These two functions affect the structure plus any bound variables ! 3326: in all enclosing blocks. ! 3327: To freeze or thaw only a single structure, use \fBfreezestruct\fR ! 3328: and \fBthawstruct\fR. ! 3329: To freeze or thaw only a single block, use \fBfreezeblock\fR ! 3330: and \fBthawblock\fR which expect the name of a block as an ! 3331: argument. ! 3332: .PP ! 3333: Above it was mentioned that two structures will match if ! 3334: and only if they both are of the same type. ! 3335: Actually the system has been extended to allow the matching ! 3336: of a structure of one type with another of a type derived ! 3337: from the first via a \fIcreate expanded\fR. ! 3338: The extra slots of the larger (expanded) ! 3339: structure are ignored during the match. ! 3340: .PP ! 3341: Lastly it should be mentioned that the matching rules are ! 3342: an evolving system, and may be amended as experience ! 3343: with their use is accumulated. ! 3344: The rules may seem a bit complex at first, but in use they ! 3345: are fairly natural. ! 3346: The rules are biased towards efficiency (like much of PEARL). ! 3347: The designers felt that hiding exponential time-complexity ! 3348: processing within the language would lead users to ! 3349: construct inefficient programs without realizing it. ! 3350: Thus several "features" of other complex AI matchers are not built in. ! 3351: The user must implement these individually at a higher level. ! 3352: It has been our experience that this leads to much cleaner designs. ! 3353: .NH ! 3354: Function Structures ! 3355: .PP ! 3356: In using PEARL, it is sometimes handy to escape into Lisp in ! 3357: a "\fIstructure\fRd" way. ! 3358: Although PEARL allows ad hoc escapes by way of its hooks ! 3359: and the ! and $ evaluation operators defined above, ! 3360: the philosophy in PEARL \fBfunction structures\fR ! 3361: is to allow structured escapes that restrict the generality ! 3362: of the escape to the minimum necessary for the task. ! 3363: At times you may wish to equate Lisp functions with their expected ! 3364: arguments with PEARL structures with their associated slots. ! 3365: For example while you may wish to describe an action in a program ! 3366: as fetching an item from the data base, you may actually be ! 3367: unable to describe the item as a structure and/or be unable or ! 3368: unwilling to actually store it in the data base. ! 3369: Instead, you will sometimes want the value to be provided by ! 3370: a function called at fetching time instead of a structure in the ! 3371: data base. ! 3372: .PP ! 3373: Take as an example the case of keeping track of whether any two ! 3374: objects are near each other. ! 3375: One possible way to do this is to keep structures in the data base ! 3376: which record for each pair of objects that are near each other the ! 3377: fact that they are near each other: ! 3378: .DS ! 3379: (create base Near ! 3380: (Object1 struct) ! 3381: (Object2 struct)) ! 3382: .DE ! 3383: Then determining whether two objects are near each other would ! 3384: require a simple fetch. ! 3385: However, if you are dealing with a large number of objects which ! 3386: are moving around quite a bit but only want to know about nearness ! 3387: once in a while, it might be easier or more efficient to compute ! 3388: whether two objects are near each other only on demand. ! 3389: In this case, you might like to write a function called Near ! 3390: which expects two arguments. ! 3391: However, for consistency, you may not want to design your program ! 3392: so that it knows what things can be fetched and what things need ! 3393: computing. ! 3394: So you would like to define a structure which looks like our ! 3395: definition of Near above but which actually invokes the ! 3396: function Near. ! 3397: .PP ! 3398: To do this, one may create the function Near (which must be an ! 3399: expr) and also a structure of type \fIfunction\fR named Near: ! 3400: .DS ! 3401: (de Near (x y) ! 3402: ... mechanism to actually determine nearness ... ) ! 3403: ! 3404: (create function Near ! 3405: (Object1 struct) ! 3406: (Object2 struct)) ! 3407: .DE ! 3408: and then can create an individual of it for fetching: ! 3409: .DS ! 3410: (create individual Near IsNear ! 3411: (Object1 John) ! 3412: (Object2 Office)) ! 3413: ! 3414: (fetch IsNear) ! 3415: .DE ! 3416: Note that the format of function structures within PEARL ! 3417: is the same as that of structures. ! 3418: However, the name of the actual Lisp function to be called must ! 3419: match the type name of the \fIfunction\fR structure, and the ! 3420: arguments must occur in the same order and be of the same types ! 3421: as the slots which will contain the actual arguments to the function. ! 3422: .PP ! 3423: As another simple example, to define a \fIfunction\fR structure ! 3424: to correspond to the function \fIgetpath\fR, we would use the following: ! 3425: .DS ! 3426: (create function getpath ! 3427: (Item struct) ! 3428: (Path lisp) ) ! 3429: .DE ! 3430: and then an actual instance: ! 3431: .DS ! 3432: (create individual getpath Minst ! 3433: (Item ! Mtrans1) ! 3434: (Path '(MObject) ) ) ! 3435: .DE ! 3436: This example is not too useful. ! 3437: As a more realistic use, consider a program to return all ! 3438: the MObjects of all MTranses that are in the data base: ! 3439: .DS ! 3440: (create function nextitem ! 3441: (Stream lisp) ) ! 3442: .DE ! 3443: .DS ! 3444: (create pattern MTrans MPat1 ! 3445: (MObject ?X) ) ! 3446: .DE ! 3447: .DS ! 3448: (global MStream) ! 3449: (setq MStream (fetch MPat1) ) ! 3450: .DE ! 3451: .DS ! 3452: (create individual getpath Minst2 ! 3453: (Item (nextitem (Stream ?MStream) ) ) ! 3454: (Path '(MObject) ) ! 3455: .DE ! 3456: .DS ! 3457: (setq Stream1 (fetch Minst2) ) ! 3458: .DE ! 3459: Note the recursive use of the data base: the \fIfetch\fR of ! 3460: Minst2 will cause a \fIgetpath\fR to be executed. ! 3461: But PEARL must first get the two arguments to pass on to ! 3462: \fIgetpath\fR which causes the function \fInextitem\fR ! 3463: to be evaluated, getting the next MTrans in MStream to ! 3464: pass to \fIgetpath\fR. ! 3465: .PP ! 3466: Thus, function structures provide a way to describe a function and ! 3467: its arguments through a PEARL structure and then to include, ! 3468: in a pattern to fetch or in a structure slot, ! 3469: a function call which will provide the desired value ! 3470: at fetching time. ! 3471: However, this only works during fetching. ! 3472: .PP ! 3473: The function used by PEARL to execute a function ! 3474: structure is \fBevalfcn\fR. ! 3475: It takes an item as its argument and returns the result of ! 3476: applying the associated expr to its slot values if the item ! 3477: is a function structure. ! 3478: If the item is a single structure it returns the item untouched. ! 3479: If the item is a list of structures, it applies itself ! 3480: recursively with \fImapcar\fR. ! 3481: No other PEARL functions currently know about function structures ! 3482: as being any different than other individual structures. ! 3483: .NH ! 3484: More About the PEARL Top Level Loop and History Mechanism ! 3485: .PP ! 3486: The PEARL prompt-read-eval-print loop includes two features which ! 3487: make PEARL easier to work with than the usual top level of Lisp. ! 3488: Both features were designed in imitation of the Berkeley Unix ! 3489: shell program \fIcsh\fR. ! 3490: .PP ! 3491: The first is an aliasing mechanism which provides the ability to ! 3492: use various atoms as aliases for commonly executed s-expressions. ! 3493: If you type an atom to the top level and it has the property ! 3494: \fBalias\fR, the value of its \fIalias\fR property will be ! 3495: evaluated instead. ! 3496: Thus, if you do a ! 3497: .DS ! 3498: (putprop 'dir '(dir) 'alias) ; in UCI Lisp ! 3499: or ! 3500: (putprop 'ls '(exec ls) 'alias) ; in Franz Lisp ! 3501: .DE ! 3502: then if you type the atom \fIdir\fR or \fIls\fR repectively ! 3503: to the top level, you will get the contents of your ! 3504: directory printed out. ! 3505: Two such built-in atoms are \fBhistory\fR which will ! 3506: run the function \fIhistory\fR and print out your last ! 3507: 64 commands (see below) and \fBh\fR which will print the last 22 ! 3508: commands (one crt screenful). ! 3509: The aliasing mechanism can be turned off (saving a \fIget\fR for ! 3510: each atom you use at the top level) by setting the special ! 3511: variable \fB*usealiases*\fR to \fInil\fR. ! 3512: .PP ! 3513: PEARL's top level also includes a simplified command-history mechanism. ! 3514: As you type in expressions to the top level of PEARL, they are ! 3515: stored away for future reference. ! 3516: The results of evaluating each expression are also kept. ! 3517: The commands and their results are kept in two hunks ! 3518: whose default size is 64. ! 3519: The hunk containing the commands is kept in the special ! 3520: variable \fB*history*\fR and the hunk containing the results ! 3521: is kept in the special variable \fB*histval*\fR ! 3522: To change the number of commands remembered, set the special ! 3523: variable \fB*historysize*\fR to something other than 64 ! 3524: in your \fI.init.prl\fR. ! 3525: It cannot be changed later. ! 3526: (If you are a novice user of PEARL, we recommend that you not ! 3527: change it to be smaller, since the history command can sometimes ! 3528: be helpful to someone helping you to debug something after you ! 3529: have fiddled with it a while.) ! 3530: .PP ! 3531: The commands you type are squirrelled away so that you can ask ! 3532: PEARL to re-execute them, thus saving the pain of retyping ! 3533: a complicated expression. ! 3534: To access the previous commands, the readmacro \fB"!"\fR is ! 3535: provided. ! 3536: To access the results of the previous commands, ! 3537: the readmacro \fB"$"\fR is provided. ! 3538: (The exclamation point is in imitation of the cshell; ! 3539: the dollar sign is meant to suggest "value".) ! 3540: These readmacros peek at the next character to determine what to do. ! 3541: We discuss the variations available on these two readmacros in ! 3542: parallel, since many of them coincide. ! 3543: .PP ! 3544: The simplest and most useful forms are \fB"!!"\fR and \fB"$$"\fR ! 3545: which effectively re-execute and reprint the last command or its result. ! 3546: Actually, both forms are executed, but the dollard sign macro ! 3547: always returns its value quoted so that its effect is usually to ! 3548: just reprint the result of the previous command. ! 3549: Note that since these are readmacros which simply return the ! 3550: last s-expression typed or its value, you can use them to build up ! 3551: more complex commands. ! 3552: For example: ! 3553: .DS ! 3554: pearl> (fetch Item) ! 3555: (*stream:* . . .) ! 3556: pearl> (nextitem !!) ! 3557: .DE ! 3558: will cause the fetch to be repeated and then do a \fInextitem\fR on it. ! 3559: However, it is much more efficient to use the \fI$$\fR form in ! 3560: this case, since what you really want is to do a \fInextitem\fR ! 3561: on the result of the \fIfetch\fR in the last command: ! 3562: .DS ! 3563: pearl> (fetch Item) ! 3564: (*stream:* . . .) ! 3565: pearl> (nextitem $$) ! 3566: .DE ! 3567: .PP ! 3568: The commands are numbered as you type them, starting with zero. ! 3569: Although the values wrap around in the hunks, the \fIhistory number\fR ! 3570: continues to climb. ! 3571: The current history number is available in the special ! 3572: variable \fB*historynumber*\fR. ! 3573: To access a particular command or its value, you may type you may ! 3574: follow an exclamation point or dollar sign with the number of the ! 3575: command. ! 3576: Thus \fB!23\fR and \fB$23\fR are the 23rd command and its result. ! 3577: If you don't remember the command's number you can use the ! 3578: function name or a prefix of it. ! 3579: Thus \fB!fetch\fR and \fB$fetch\fR will access the last \fIfetch\fR ! 3580: or its value. ! 3581: Or \fB!fe\fR and \fB$fe\fR will access the last command starting ! 3582: with \fIfe\fR or its value. ! 3583: If there was a reference to an atom (instead of a list) with that ! 3584: name or with that as a prefix somewhere, then the atom will be ! 3585: evaluated again. ! 3586: For exclamation point, this is a waste of typing except for long ! 3587: atom names. ! 3588: For dollar sign, it provides you a way of recovering the value of ! 3589: a variable that has since changed. ! 3590: (As a side effect of implementing this, PEARL contains a function ! 3591: \fBprefix\fR which expects two lists and determines whether the ! 3592: first is a prefix of the second, considered as a list of atoms. ! 3593: Thus, PEARL just calls \fIprefix\fR on the results of \fIexplode\fRing ! 3594: two atoms.) ! 3595: .PP ! 3596: Here the parallel between the two macros ends. ! 3597: .PP ! 3598: There are five forms which work only with exclamation point and ! 3599: refer only to the last s-expression typed. ! 3600: They are essentially ways to pick individual top-level elements ! 3601: out of the last command: ! 3602: .DS ! 3603: \fB!^\fR the first argument ! 3604: \fB!$\fR the last argument ! 3605: \fB!*\fR the complete set of arguments ! 3606: \fB!:0\fR the function name ! 3607: \fB!:n\fR the nth argument ! 3608: .DE ! 3609: Both macros are splicing macros so that their values may be ! 3610: spliced into the current s-expression. ! 3611: \fB!*\fR is designed so that the following will work: ! 3612: .DS ! 3613: pearl> (add 1 2 3 4) ! 3614: 10 ! 3615: pearl> (times !*) ! 3616: (times 1 2 3 4) ! 3617: 24 ! 3618: .DE ! 3619: .PP ! 3620: To see the last 64 commands you gave printed out, use the function ! 3621: \fBhistory\fR (or type the atom \fBhistory\fR). ! 3622: If you don't want all 64 commands, \fIhistory\fR will accept an ! 3623: integer argument telling how many you want. ! 3624: Thus the aliases on \fIhistory\fR and \fIh\fR are: ! 3625: .DS ! 3626: (putprop 'history '(history) 'alias) ! 3627: (putprop 'h '(history 22) 'alias) ! 3628: .DE ! 3629: If you use the command numbers often, you might like to have the ! 3630: history number printed out before each command. ! 3631: To have the history number printed just before the PEARL prompt, ! 3632: set the special variable \fB*printhistorynumber*\fR to a ! 3633: non-\fInil\fR value. ! 3634: The default value is f\Inilf\R. ! 3635: .PP ! 3636: Whenever you use the ! or $ history mechanisms, the line you type in ! 3637: will be reprinted in its expanded form on the next line using ! 3638: the current \fIpearlprintfn\fR. ! 3639: If you wish to modify your own read macros so that they also will ! 3640: cause this reprinting, simply have them set the special ! 3641: variable \fB*readlinechanged*\fR to a non-\fInil\fR value. ! 3642: .PP ! 3643: It is sometimes useful to have a function return no value. ! 3644: That is, you often do not want the value of the function to be ! 3645: printed by the top level loop. ! 3646: In particular, functions which print values often return ugly ! 3647: values afterward. ! 3648: To get around this problem, the PEARL top level disables printing ! 3649: of the value returned by a function if it returns the atom ! 3650: \fB*invisible*\fR. ! 3651: All of the PEARL print functions return this value. ! 3652: .PP ! 3653: It is sometimes useful to be able to save the current state of a ! 3654: PEARL run for later. ! 3655: There are two functions to allow this. ! 3656: If you wish to save a version which will continue exactly where ! 3657: you left off (at the top level), use the function ! 3658: \fBsavecontinue\fR which expects zero, one or two arguments. ! 3659: If you wish to save a version which will read in ! 3660: the \fI.start.prl\fR file when it starts up, use \fBsavefresh\fR. ! 3661: (If you also want \fI.init.prl\fR read in, change the value of the ! 3662: special variable \fB*firststartup*\fR to \fIt\fR beforehand but ! 3663: be careful not to put functions which may only be run once in it.) ! 3664: Note however that you cannot save Franz PEARL on top of the file ! 3665: you are running; ! 3666: trying to will result in the \fIDumplisp failed\fR ! 3667: error message from Franz Lisp. ! 3668: Note also that a saved PEARL uses about 1500 blocks or 750kbytes on ! 3669: the disk so this should be used sparingly. ! 3670: (Exceeding the disk quota will result in the same error message.) ! 3671: In the Franz Lisp version, if the number of arguments to either of ! 3672: these functions is: ! 3673: .IP 0: ! 3674: It will be saved as \fIpearl\fR in the current directory. ! 3675: .IP 1: ! 3676: The argument is assumed to be a (relative) file name to save under. ! 3677: .IP 2: ! 3678: The result of concatenating the two arguments together with a ! 3679: \fB/\fR between them will be the file name used. ! 3680: (This is for UCI Lisp compatibility.) ! 3681: .LP ! 3682: In the UCI Lisp version, if the number of arguments is: ! 3683: .IP 0: ! 3684: It will be saved as \fIpearl\fR in the current directory. ! 3685: .IP 1: ! 3686: The argument is assumed to be a file name for the current directory. ! 3687: .IP 2: ! 3688: They must be a directory and a file name to save in. ! 3689: .NH ! 3690: Looping and Copying Functions ! 3691: .PP ! 3692: PEARL includes several loop macros. ! 3693: The first two were included simply for use by the implementation but ! 3694: might be useful to the user. ! 3695: They are the \fBfor\fR and \fBwhile\fR macros which both expand ! 3696: into a \fIprog\fR wrapped around a \fIprogn\fR. ! 3697: A call to the \fIwhile\fR macro should be of the form: ! 3698: .DS ! 3699: (while <test> ! 3700: EXPR1 ! 3701: EXPR2 ! 3702: ... ! 3703: EXPRn) ! 3704: .DE ! 3705: The <test> is evaluated before each execution of the loop. ! 3706: If it is non-\fInil\fR, the EXPRi are evaluated in sequence. ! 3707: This continues until <test> return nil in which case the last ! 3708: value returned by EXPRn is returned. ! 3709: Since the while expands into a \fIprog\fR, any of the EXPRi may ! 3710: call the function \fIreturn\fR, terminating the loop prematurely ! 3711: and returning the value given to \fIreturn\fR. ! 3712: .PP ! 3713: A call to the \fIfor\fR macro should be of the form: ! 3714: .DS ! 3715: (for <var> <initial> <final> ! 3716: EXPR1 ! 3717: EXPR2 ! 3718: ... ! 3719: EXPRn) ! 3720: .DE ! 3721: <initial> and <final> should evaluate to integers. ! 3722: The EXPRi are repeatedly evaluated in sequence with <var> being ! 3723: set to the values ascending from <initial> to <final>. ! 3724: If <initial> is greater than <final>, nothing is done. ! 3725: <var> is a prog variable which disappears after the \fIfor\fR ! 3726: executes. ! 3727: The value returned is the last value of EXPRn and \fIreturn\fR ! 3728: provides a premature exit with a value as in \fIwhile\fR. ! 3729: .PP ! 3730: The fexpr \fBforeach\fR expects a stream and a function (or macro) ! 3731: and applies the function to each element returned by successive ! 3732: calls to \fInextitem\fR on the stream. ! 3733: Unfortunately it only returns \fInil\fR at this time. ! 3734: Eventually, other useful looping structures may be provided. ! 3735: .PP ! 3736: Since PEARL provides several new types of values, it provides a ! 3737: few functions to copy them. ! 3738: In particular, the standard Lisp function \fBcopy\fR has been ! 3739: redefined to avoid trying to copy anything that is not a cons-cell. ! 3740: There are several ways to copy structures, described below. ! 3741: The rest of PEARL values either are too complicated to copy ! 3742: (data bases), can be copied with \fIcopy\fR (streams) or else ! 3743: make no sense to copy (symbols, blocks). ! 3744: .PP ! 3745: For copying structures, there are currently two functions. ! 3746: The one you are most likely to want is \fBscopy\fR which expects a ! 3747: single structure argument and returns a new structure with the ! 3748: same values in it. ! 3749: However, the new structure will differ from the old in several ! 3750: important ways. ! 3751: First of all, copying a bound variable will result in the actual ! 3752: value being inserted in the new copy. ! 3753: When copying an unbound variable, the new structure will receive ! 3754: a local variable with the same name and this variable will ! 3755: be installed in the slot. ! 3756: All variables so installed will be installed in the top level ! 3757: structure regardless of where they came from in the original. ! 3758: The only exception to this is lexically-scoped variables. ! 3759: When the new structure is built, it will be built within any ! 3760: currently open blocks and any of its unbound variables whose names ! 3761: match variables from the current block(s) will be identified with ! 3762: those block variables. ! 3763: Global variables are similarly reinstalled only if they are unbound. ! 3764: Adjunct variables are also installed \fIonly if\fR they are ! 3765: unbound, since if they are bound their purpose will already have ! 3766: been served and their bound values installed in other slots ! 3767: referring to them. ! 3768: .PP ! 3769: A variation on \fIscopy\fR which replaces all unbound ! 3770: variables from the original with \fI?*any*\fR is called ! 3771: \fBpatternize\fR. ! 3772: After (and during) the running of these copying functions, the ! 3773: resulting top-level structure is kept in the special variable ! 3774: \fB*currenttopcopy*\fR. ! 3775: .PP ! 3776: The situation sometimes arises where you have already built a ! 3777: structure and have a new structure with information that should be ! 3778: merged into the old one. ! 3779: Rather than use \fIpath\fR to copy each relevant slot, you can use ! 3780: \fBsmerge\fR which expects as arguments the old structure to merge ! 3781: into and the new structure from which to take values. ! 3782: All unfrozen variables in the old structure are unbound first and ! 3783: then any unbound variable whose counterpart in the new structure ! 3784: is bound gets replaced (\fBnot set\fR) with this value. ! 3785: The old structure being merged into must be of the same type or ! 3786: an expanded version of the new structure. ! 3787: .NH ! 3788: Miscellaneous Variations and Abbreviations ! 3789: .PP ! 3790: People very quickly get tired of typing the relatively long ! 3791: function names that PEARL uses. ! 3792: As a result, a large number of abbreviations and macros have ! 3793: been included in PEARL. ! 3794: We recommend that the shortest ones be used primarily at ! 3795: the top level, since they are easily subject to typographic ! 3796: errors. ! 3797: Most the abbreviations are in \fIcreate\fR and are summarized by ! 3798: the following table: ! 3799: .DS ! 3800: The function or atom: May \kmbe abbreviated: ! 3801: create \h'|\nmu'cr ! 3802: individual \h'|\nmu'ind ! 3803: pattern \h'|\nmu'pat ! 3804: expanded \h'|\nmu'exp ! 3805: function \h'|\nmu'fn ! 3806: .DE ! 3807: Thus, \fI(cr pat ....)\fR is equivalent to ! 3808: \fI(create pattern ....)\fR. ! 3809: .PP ! 3810: In addition, a large number of macros for popular combinations of ! 3811: functions are included: ! 3812: .ID ! 3813: The s-expression: Is exp\kmanded into by the macro: ! 3814: (create base ...) \h'|\nmu'(cb ...) ! 3815: \h'|\nmu'(base ...) ! 3816: (create individual ...) \h'|\nmu'(ci ...) ! 3817: \h'|\nmu'(individual ...) ! 3818: \h'|\nmu'(ind ...) ! 3819: (create expanded ...) \h'|\nmu'(ce ...) ! 3820: \h'|\nmu'(expanded ...) ! 3821: \h'|\nmu'(pexp ...) ! 3822: (create pattern ...) \h'|\nmu'(cp ...) ! 3823: \h'|\nmu'(pattern ...) ! 3824: \h'|\nmu'(pat ...) ! 3825: (create function ...) \h'|\nmu'(cf ...) ! 3826: \h'|\nmu'(pfunction ...) ! 3827: \h'|\nmu'(fn ...) ! 3828: .sp 1 ! 3829: (insertdb (create ...) nil) \h'|\nmu'(dbcreate ...) ! 3830: \h'|\nmu'(dbcr ...) ! 3831: `(quote ,(create ...)) \h'|\nmu'(inlinecreate ...) ! 3832: (fetch (create ...) nil) \h'|\nmu'(fetchcreate ...) ! 3833: `(fetch (quote ,(create ...)) nil) \h'|\nmu'(inlinefetchcreate ...) ! 3834: (nextitem (fetch ...) ) \h'|\nmu'(firstfetch ...) ! 3835: .sp 1 ! 3836: (valprint ...) \h'|\nmu'(vp ...) ! 3837: (fullprint ...) \h'|\nmu'(fp ...) ! 3838: .DE ! 3839: (\fIpexp\fR and \fIpfunction\fR are so named to avoid conflict ! 3840: with the exponential function \fIexp\fR and the function quoting ! 3841: function \fIfunction\fR.) ! 3842: .PP ! 3843: The automatic setq feature of \fIcreate\fR that causes an atom ! 3844: to be bound to the item created is available throughout ! 3845: \fIcreate\fR. ! 3846: In all cases, the special variable \fB*lastcreated*\fR is ! 3847: set to the item. ! 3848: In addition: ! 3849: .DS ! 3850: This combination: Causes \kmthis atom to be set: ! 3851: (create base X ... \h'|\nmu'X ! 3852: (create base X Y ... \h'|\nmu'Y ! 3853: (create expanded X Y ... \h'|\nmu'Y ! 3854: (create expanded X Y Z ... \h'|\nmu'Z ! 3855: (create individual X ... \h'|\nmu'(none) ! 3856: (create individual X Y ... \h'|\nmu'Y ! 3857: (create individual X X ... \h'|\nmu'(none, the second X is ignored) ! 3858: (create pattern X ... \h'|\nmu'(none) ! 3859: (create pattern X Y ... \h'|\nmu'Y ! 3860: (create pattern X X ... \h'|\nmu'(none, the second X is ignored) ! 3861: .DE ! 3862: .PP ! 3863: When creating an object, wherever a recursive call to \fIcreate\fR ! 3864: is implied by a structure in a slot of type structure, you may start ! 3865: with one of the types \fIindividual\fR, \fIpattern\fR, \fIbase\fR, ! 3866: \fIexpanded\fR, \fIfunction\fR to change the type of object ! 3867: being created. ! 3868: Whenever it isn't given, the type of the toplevel \fIcreate\fR, ! 3869: which is kept in the special variable ! 3870: \fB*currentcreatetype*\fR is used. ! 3871: For example, in ! 3872: .DS ! 3873: (create pattern x ! 3874: (a (individual y)) ! 3875: (b (base z (s1 ...) ...)) ! 3876: (c (w))) ! 3877: .DE ! 3878: where a, b, and c are all slots of type structure, slot a ! 3879: will contain an individual y which the attendant defaults ! 3880: filled in, slot b will contain the default instance of a ! 3881: newly created type z, and slot c will contain a pattern w ! 3882: with \fI?*any*\fR as defaults. ! 3883: .PP ! 3884: Since each Lisp stores its functions in a different place, PEARL ! 3885: includes a macro \fBaliasdef\fR which expects the names of an new ! 3886: and a old function name and copies the function definition of the ! 3887: old one to the new one. ! 3888: In the case of Lisps which store the function definition on the ! 3889: property list, \fIaliasdef\fR requires a third argument which is ! 3890: the name of the property that the definition is kept under. ! 3891: .NH ! 3892: Low Level Access Functions. ! 3893: .PP ! 3894: There are a large number of functions for setting and accessing ! 3895: the various part of structures, symbols, and data bases which are ! 3896: primarily intended for the use of PEARL. ! 3897: In general, the access functions are called \fBget...\fR where ! 3898: "..." is the name of the information about the structure. ! 3899: The functions which change information are called \fBput...\fR. ! 3900: It is not generally safe to use the \fIput...\fR functions but the ! 3901: \fIget...\fR functions can sometimes be useful to the user. ! 3902: For a complete list of the functions, see the index. ! 3903: If you don't recognize the function by name, you don't need it so ! 3904: we don't bother to further document them. ! 3905: Since most of them expect a slot number, it is useful to know ! 3906: about the macro \fBnumberofslot\fR which requires the name of a ! 3907: slot and the definition of a structure (which can be accessed ! 3908: with \fIdefatom\fR or \fId:<structurename>\fR.) and returns the ! 3909: corresponding slot number. ! 3910: .bp ! 3911: .NH ! 3912: Appendix of UCI Lisp functions added to Franz PEARL ! 3913: .PP ! 3914: Since PEARL was originally written in UCI Lisp, there are many functions ! 3915: from UCI Lisp that it needed. ! 3916: We also wrote others to move our other programs. ! 3917: The number is too great to document each one. ! 3918: If the function is described with an equal sign, as in ! 3919: \fI"fn = other"\fR then the function definition of the Franz Lisp ! 3920: function \fIother\fR has been put under \fIfn\fR. ! 3921: Thus it might not behave quite the same as in UCI Lisp. ! 3922: If no equivalence is given, it was written from scratch which is ! 3923: slightly more likely to mimic UCI Lisp. ! 3924: In this case, see the UCI Lisp manual for details. ! 3925: .PP ! 3926: The functions used for the PEARL top level loop in the Franz Lisp ! 3927: version plus changes to the fixit debugger and the trace package ! 3928: are briefly described here also. ! 3929: .PP ! 3930: The Franz Lisp version of PEARL is normally loaded with both the Fixit ! 3931: debugger and the trace package already loaded. ! 3932: This is done to avoid getting the versions which do not know how to print ! 3933: PEARL objects. ! 3934: In addition, the Fixit debugger is attached to all available hooks for ! 3935: going into the break package, since it is much more similar to the UCI Lisp ! 3936: break package than the standard Franz Lisp break package is. ! 3937: Both the debugger and trace package use the function ! 3938: \fBbreakprintfn\fR to print values. ! 3939: The \fImsg\fR function uses the function \fBmsgprintfn\fR ! 3940: to print values. ! 3941: Either can be bound to whatever function you wish. ! 3942: To disengage the Fixit debugger, read the Franz manual chapter on exception ! 3943: handling. ! 3944: See Note 4 below for more on features added to the Fixit debugger. ! 3945: .LP ! 3946: .nf ! 3947: Atoms and Variables: ! 3948: *dskin* -- special variable -- initial value: t. See Note 1 below. ! 3949: *file* -- special variable -- initial value: nil. Used by \fIdskin\fR ! 3950: and function definition functions. ! 3951: *invisible* -- special atom -- not printed by \fIdskin\fR if returned ! 3952: by a value when it is evaluated. ! 3953: ! 3954: Functions: ! 3955: *append = append ! 3956: (breakprintfn value lmar rmar) -- used by \fItrace\fR and \fIdebug\fR. ! 3957: *dif = diff ! 3958: *eval = eval ! 3959: *great = greaterp ! 3960: *less = lessp ! 3961: *max = max ! 3962: (msgprintfn value lmar rmar) -- used by \fImsg\fR. ! 3963: *nconc = nconc ! 3964: *plus = plus ! 3965: *times = times ! 3966: (addprop 'id 'value 'prop) ! 3967: (allsym itemorpair) -- fexpr ! 3968: (apply* 'fcn 'args) -- macro -- This is provided to act like UCI Lisp's ! 3969: \fIapply#\fR. The asterisk is used because of the special meaning ! 3970: of # in Franz Lisp. Unlike Franz Lisp's \fIfuncall\fR and ! 3971: \fIapply\fR, this does what you would expect with macros! ! 3972: atcat = concat ! 3973: (boundp 'item) ! 3974: clrbfi = drain ! 3975: consp = dtpr ! 3976: (de fcnname arglist &rest body) -- macro -- See Note 2 below. ! 3977: (debug-replace-function-name 'cmd 'frame) -- Used by the modified ! 3978: Fixit debugger to handle the "> newfcnname" facility. ! 3979: (defp 'to 'from [prop]) -- macro -- Ignores \fIprop\fR and just ! 3980: copies the function definition. ! 3981: (defv var val) -- fexpr ! 3982: (df fcnname arglist &rest body) -- macro -- See Note 2 below. ! 3983: (dm fcnname arglist &rest body) -- macro -- See Note 2 below. ! 3984: (dremove 'elmt 'l) ! 3985: (drm char lambda) -- macro -- See Note 2 below. ! 3986: (dskin filename1 filename2 ....) -- See Note 1 below. ! 3987: (dskin1 '*file*) ! 3988: (dskin2 'port) ! 3989: (dsm char lambda) -- macro -- See Note 2 below. ! 3990: (enter 'v 'l) ! 3991: (every 'fcn 'args) -- macro -- Potential problem when compiled. ! 3992: expandmacro = macroexpand ! 3993: (funl &rest body) -- macro -- Expands into (function (lambda ...)). ! 3994: (ge 'x) -- macro ! 3995: (gensym1 'ident 'val) ! 3996: gt = > ! 3997: (initsym atomorpair1 ...) -- fexpr ! 3998: (intersection 'set1 'set2) ! 3999: (islambda 'fcn) -- Is \fIfcn\fR a lambda (expr)? ! 4000: (le 'x) -- macro ! 4001: (length '*u*) ! 4002: lineread = readl (below) ! 4003: (litatom 'x) -- macro ! 4004: lt = < ! 4005: mapcl = mapcar ! 4006: memb = member ! 4007: (msg ...) -- macro -- Some features may be missing. The function ! 4008: used to print is \fImsgprintfn\fR, initially bound to ! 4009: (or (eq '*invisible* ...) ! 4010: (patom (valform ...))) ! 4011: (nconc1 'l 'elmt) ! 4012: (nequal 'arg1 'arg2) ! 4013: (newsym atom) -- fexpr ! 4014: noduples = union (below) ! 4015: (nth 'l 'num) ! 4016: (oldsym atomorpair) -- fexpr ! 4017: (pearl-break-err-handler) -- Should be tied to ER%tpl if you want the ! 4018: standard Franz Lisp break (not much of a) package. ! 4019: Same as standard Franz Lisp \fIbreak-err-handler\fR except ! 4020: that it uses the function \fIbreakprintfn\fR. ! 4021: (pearl-top-level) -- The PEARL top level loop. ! 4022: (pearl-top-level-init) -- The initial function called when PEARL starts up. ! 4023: This is the code that reads in the init files and sets any unset ! 4024: PEARL parameters. ! 4025: peekc = tyipeek ! 4026: (pop q) -- macro ! 4027: (push var 'val) -- macro ! 4028: (readl ['flag]) -- fexpr ! 4029: (readl1 'flag) ! 4030: remove = delete ! 4031: (remprops 'item 'proplist) ! 4032: (remsym atomorpairlist) -- fexpr ! 4033: (save fcnname) -- fexpr -- Saves function or macro definition under ! 4034: the property \fIolddef\fR. Saves macro character definitions ! 4035: under \fIoldmacro\fR. ! 4036: (selectq ...) -- macro ! 4037: (some 'fcn 'list) -- macro -- Potential problem when compiled. ! 4038: (sprint 'item ['lmar ['rmar]]) -- See Note 3 below. ! 4039: (subset 'fcn 'list) -- macro ! 4040: (timer (defun timer fexpr (request)$? ! 4041: (unbound) -- macro ! 4042: (union 'list1 ['list2 ...]) ! 4043: (unsave fcnname) -- fexpr -- See \fIsave\fR. ! 4044: .fi ! 4045: .PP ! 4046: \fBNote 1:\fR A simplified but extended imitation of the UCI Lisp function ! 4047: \fBdskin\fR is provided in PEARL. ! 4048: It is an nlambda which requires the file extensions to be provided. ! 4049: There is a special variable \fB*dskin*\fR which controls whether ! 4050: the expression read in is printed and/or whether the result of ! 4051: evaluating it is printed. ! 4052: .DS L ! 4053: *dskin* = nil means neither ! 4054: *dskin* = t means result only ! 4055: *dskin* = 'name means the name of the variable in setq \fIor\fR the name ! 4056: of the function in de, df, dm, dsm, drm, defmacro, ! 4057: defun, or def \fIor\fR the name of the type in create. ! 4058: *dskin* = 'both means both t and 'name. ! 4059: .DE ! 4060: The default value of *dskin* is t. ! 4061: .PP ! 4062: File names are always printed before they are opened. ! 4063: The print function used for values is the current function ! 4064: definition of \fBdskprintfn\fR. ! 4065: The default function definition in PEARL is: ! 4066: .DS ! 4067: (de dskprintfn (*printval*) ! 4068: (cond ((atom *printval*) (patom *printval*)) ! 4069: ( t (print (valform *printval*))))) ! 4070: .DE ! 4071: .PP ! 4072: \fBNote 2:\fR For better compatibility with UCI Lisp, PEARL contains ! 4073: macros for the function and read macro definition functions ! 4074: \fBde, df, dm, dsm,\fR and \fBdrm\fR. ! 4075: They have been defined to save the old definitions automatically ! 4076: and to return \fI(fcnname Redefined)\fR when this is the case. ! 4077: \fIDe, df,\fR and \fIdm\fR save the old definition under the ! 4078: property '\fIolddef\fR. ! 4079: \fIDsm\fR and \fIdrm\fR save the old definition under the ! 4080: property '\fIoldmacro\fR. ! 4081: (The current definition of a readmacro is kept by Franz under the ! 4082: property '\fImacro\fR.) ! 4083: If the function definition is read in by \fIdskin\fR, ! 4084: then the current file name which is in the special variable ! 4085: \fB*file*\fR is put under the property '\fIsourcefile\fR. ! 4086: .PP ! 4087: \fBNote 3:\fR A function similar to the UCI Lisp \fBsprint\fR is included, ! 4088: including the printmacro facility and the optional second argument ! 4089: saying which column to start in. ! 4090: In addition, there is an optional third argument saying which column ! 4091: to try not to go beyond (that is a right margin). ! 4092: A slight addition has been made to the printmacro feature (feature 1 below). ! 4093: During \fIsprinting\fR, if the atom in the function position in a list ! 4094: has the printmacro property one of four things will happen during ! 4095: \fIsprinting\fR: ! 4096: .IP 1. ! 4097: If the printmacro property value is a string and the item to be ! 4098: printed has a nil \fIcdr\fR, then the string will be printed instead ! 4099: of the item. ! 4100: .IP 2. ! 4101: If the printmacro property value is a string and the item to be ! 4102: printed has two items in it, then the string will be printed followed ! 4103: immediately by the \fIcadr\fR of the item. ! 4104: .IP 3. ! 4105: If the printmacro property value is a string but the item to be ! 4106: printed is longer than two elements, then it will be \fIsprinted\fR in ! 4107: the normal fashion (i.e., the printmacro will be ignored). ! 4108: .IP 4. ! 4109: Otherwise, the printmacro property value will be applied ! 4110: to the rest of the arguments. ! 4111: It should be a function which expects three arguments, the item ! 4112: to be printed, a left column to start in and a right column to ! 4113: try not to go beyond. ! 4114: A good default value for the right column argument seems to be zero. ! 4115: If the function under the printmacro property returns nil, ! 4116: then \fIsprint\fR assumes that it decided not to print the item ! 4117: and prints it in the usual way. ! 4118: .PP ! 4119: \fBNote 4:\fR The Fixit debugger now accepts a command of the ! 4120: form \fB> newname\fR whenever either an undefined function or ! 4121: unbound variable error occurs. As in UCI Lisp, newname is not ! 4122: evaluated in the case of an undefined function but is evaluated ! 4123: in the case of an unbound variable. ! 4124: Note that the blank is required (unlike UCI Lisp). ! 4125: This is not guaranteed to work if you move around the stack first. ! 4126: .bp ! 4127: .NH ! 4128: Appendix of Franz Lisp functions added to UCI Lisp PEARL ! 4129: .PP ! 4130: The following is a summary of the functions added to the UCI Lisp ! 4131: version of PEARL to make it compatible with Franz Lisp. ! 4132: Where the details are not obvious, see the Franz Lisp manual. ! 4133: \fBNote:\fR Most \fImacros\fR listed in the index which are ! 4134: labelled with asterisks are not available in UCI Lisp PEARL, since ! 4135: the implementor must specifically request that they stick around. ! 4136: .PP ! 4137: \fIDskin\fR, the break package, and \fImsg\fR have been changed ! 4138: to use the functions \fBdskprintfn\fR, \fBbreakprintfn\fR, ! 4139: \fBmsgprintfn\fRfor printing. ! 4140: .LP ! 4141: .nf ! 4142: (addtoaddress 'n 'address) -- expr -- Used by \fIcxr\fR and ! 4143: \fIrplacx\fR. Written in LAP code. ! 4144: (apply* 'fcn 'args) -- macro -- Equivalent to \fIapply#\fR. ! 4145: (buildalist ...) --- expr --- Used by \fIdefmacro\fR. ! 4146: (combineskels ...) -- expr -- Used by \fIquasiquote\fR. ! 4147: (convert ...) --- expr --- Used by \fIdefmacro\fR. ! 4148: (cxr 'index 'hunk) -- expr -- A hunk is a block of memory. Provides ! 4149: random access to a single cell of a hunk. (Uses ! 4150: \fIaddtoaddress\fR and \fIeven\fR.) ! 4151: (defmacro macroname arglist body) -- macro -- \fIDefmacro\fR provides ! 4152: a slightly more intelligent macro facility. \fIBody\fR is ! 4153: processed to look for occurrences of the arguments in ! 4154: \fIarglist\fR which are replaced with the appropriate form ! 4155: of \fIca..r\fR. If an argument is preceded by \fI&rest\fR, ! 4156: then it gets the list of the rest of the arguments. ! 4157: The Franz Lisp version has many more features not included ! 4158: in the PEARL version. ! 4159: (even 'x) -- expr -- Is \fIx\fR even? Used by \fIcxr\fR and ! 4160: \fIrplacx\fR to determine which half of a cons-cell to use. ! 4161: (isconst ...) -- expr -- Used by \fIquasiquote\fR. ! 4162: (makhunk 'size) -- expr -- Calls the UCI Lisp function \fIgetblk\fR, ! 4163: requesting a block of memory which is half of \fIsize\fR, since ! 4164: each piece of a UCI Lisp block of core is a cons-cell. ! 4165: (msg ...) -- fexpr -- Modified to use \fImsgprintfn\fR to print ! 4166: values of evaluated elements of the print list. ! 4167: (pearl-top-level) -- the PEARL top level loop. ! 4168: (pearl-top-level-init) -- The initial function called when PEARL starts up. ! 4169: (rplacx 'index 'hunk 'val) -- expr -- Provides random access storage into ! 4170: a block of memory. (Uses \fIaddtoaddress\fR and \fIeven\fR.) ! 4171: (quasiquote 'skel) -- expr -- called by the quasi-quote readmacro ! 4172: character backquote \fB`\fR. Equivalent to the quasiquote ! 4173: functions defined in Charniak[2] with different invoking ! 4174: characters to match those of Franz Lisp. ! 4175: Unquote is comma \fB","\fR and splice-unquote is \fB",@"\fR. ! 4176: Uses \fIcombineskels\fR and \fIisconst\fR. ! 4177: .fi ! 4178: .bp ! 4179: .NH ! 4180: Bibliography ! 4181: .SM ! 4182: .IP [1] ! 4183: Bobrow, D., and Winograd, T. "An Overview of KRL, a Knowledge ! 4184: Representation Language." ! 4185: \fICognitive Science\fR 1:1 (1977). ! 4186: .IP [2] ! 4187: Charniak, E., Riesbeck, C., and McDermott, D. ! 4188: \fIArtificial Intelligence Programming\fR. ! 4189: Hillsdale, New Jersey: Lawrence Erlbaum Associates, 1980. ! 4190: .IP [3] ! 4191: Faletti, J., and Wilensky, R. "The Implementation of PEARL: ! 4192: A Package for Efficient Access to Representations In Lisp", ! 4193: forthcoming ERL technical report, UCB. ! 4194: .IP [4] ! 4195: Greiner, R., and Lenat, D. "A Representation Language Language." ! 4196: In \fIProc. First NCAI\fR. Stanford, CA, August, 1980, ! 4197: 165-169. ! 4198: .IP [5] ! 4199: Roberts, I., and Goldstein, R. ! 4200: "NUDGE, A Knowledge-Based Scheduling Program." ! 4201: In \fIProc. IJCAI-77\fR. Cambridge, MA, August, 1977, 257-263. ! 4202: .IP [6] ! 4203: Schank, R. \fIConceptual Information Processing\fR. ! 4204: Amsterdam: North Holland, 1975. ! 4205: .IP [7] ! 4206: Wilensky, R. "Understanding Goal-Based Stories", ! 4207: Technical Report 140, Computer Science Department, ! 4208: Yale University, New Haven, CT, September 1978. ! 4209: .IP [8] ! 4210: Wilensky, R. ! 4211: "Meta-Planning: Representing and Using Knowledge about Planning in Problem ! 4212: Solving and Natural Language Understanding." ! 4213: \fICognitive Science\fR 5:3 (1981). ! 4214: .bp ! 4215: .nr PS 9 ! 4216: .nr VS 11p ! 4217: .ps 9 ! 4218: .vs 11p ! 4219: .NH ! 4220: Index of Global Variables and Functions With Their Arguments ! 4221: .PP ! 4222: All functions are exprs (or lexprs) unless otherwise listed. ! 4223: Functions with one or more asterisks for a page number are not ! 4224: documented other than in this index because they were not ! 4225: actually intended for use by the PEARL user. ! 4226: A single asterisk * means it is primarily intended for use by ! 4227: PEARL but might be useful and will generally work right. ! 4228: A double asterisk ** means it will generally only work ! 4229: within PEARL's code, since it expects certain ! 4230: external prog variables to exist and be set correctly. ! 4231: A triple asterisk *** means it is dangerous to use. ! 4232: Note that it is dangerous to redefine any functions in this list, ! 4233: although it should be all right to redefine any macros. ! 4234: .LP ! 4235: .nr PS 8 ! 4236: .nr VS 10p ! 4237: .ps 8 ! 4238: .vs 10p ! 4239: .nf ! 4240: *activedbnames* -- special variable -- initial value: nil \ki40 ! 4241: *any*conscell* -- special variable -- value: '(*any* . *pearlunbound*) \h'|\niu'* ! 4242: *availablesizes* -- special variable -- value: \h'|\niu'39 ! 4243: ((-1. . 1.) (0. . 1.) (1. . 1.) (2. . 3.) (3. . 7.) ! 4244: (4. . 13.) (5. . 29.) (6. . 61.) (7. . 127.) . . . . ! 4245: Franz Lisp: . . . (8. . 127.) (9. . 127.) (10. . 127.) ! 4246: (11. . 127.) (12. . 127.) (13. . 127.)) ! 4247: UCI Lisp: . . . (8. . 251.) (9. . 509.) (10. . 1021.) ! 4248: (11. . 2039.) (12. . 4093.) (13. . 8191.)) ! 4249: *blockstack* -- special variable -- initial value: nil \h'|\niu'48 ! 4250: *currentcreatetype* -- special variable -- initial value: base \h'|\niu'56 ! 4251: *currentpearlstructure* -- special variable -- initial value: nil \h'|\niu'46 ! 4252: *currentstructure* -- special variable -- initial value: nil \h'|\niu'46 ! 4253: *currenttopcopy* -- special variable -- initial value: <UNBOUND> \h'|\niu'55 ! 4254: *currenttopcreated* -- special variable -- initial value: (nilstruct) \h'|\niu'8 ! 4255: .sp ! 4256: db -- special variable -- default initial value: <UNBOUND> \h'|\niu'33 ! 4257: *db* -- special variable -- default value: the *maindb* data base \h'|\niu'12 ! 4258: *db1size* -- special variable -- default initial value: 29 \h'|\niu'39 ! 4259: *db2size* -- special variable -- default initial value: 127 \h'|\niu'39 ! 4260: *done* -- special atom \h'|\niu'35 ! 4261: .sp ! 4262: *fail* -- special atom \h'|\niu'35 ! 4263: *file* -- special variable -- initial value: nil \h'|\niu'60 ! 4264: *firstartup* -- special variable -- initial value: t \h'|\niu'53 ! 4265: *function-stream:* -- special atom \h'|\niu'13 ! 4266: *globallist* -- special variable -- initial value: nil \h'|\niu'45 ! 4267: .sp ! 4268: *history* -- special variable -- value: command history hunk \h'|\niu'51 ! 4269: *historynumber* -- special variable -- initial value: 0 \h'|\niu'52 ! 4270: *historysize* -- special variable -- default value: 64 \h'|\niu'51 ! 4271: *histval* -- special variable -- value: value history hunk \h'|\niu'51 ! 4272: *invisible* -- special atom \h'|\niu'53 ! 4273: .sp ! 4274: *lastcreated* -- special variable -- initial value: (nilstruct) \h'|\niu'8 ! 4275: *lastsymbolnum* -- special variable -- initial value: -1 \h'|\niu'* ! 4276: *maindb* -- special variable -- default value: the main data base \h'|\niu'11 ! 4277: *matchunboundsresult* -- special variable -- initial value: nil \h'|\niu'44 ! 4278: *ordinalnames* -- special variable -- initial value: nil \h'|\niu'31 ! 4279: .sp ! 4280: *pathlocal* -- special variable -- initial value: <UNBOUND> \h'|\niu'33 ! 4281: *pathtop* -- special variable -- initial value: <UNBOUND> \h'|\niu'33 ! 4282: *pearlprompt* -- special variable -- default value: "pearl> " \h'|\niu'3, 4 ! 4283: *pearlunbound* -- special atom \h'|\niu'45 ! 4284: *printhistorynumber* -- special variable -- initial value: nil \h'|\niu'53 ! 4285: .sp ! 4286: *readlinechanged* -- special variable -- initial value: nil \h'|\niu'53 ! 4287: *runaddpredpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4288: *runaddsetpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4289: *runallbasehooks* -- special variable -- initial value: t \h'|\niu'33 ! 4290: *runallslothooks* -- special variable -- initial value: t \h'|\niu'33 ! 4291: .sp ! 4292: *runapplypathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4293: *runclearpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4294: *rundelpredpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4295: *rundelsetpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4296: *runexpandedhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4297: *runfetchhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4298: *rungethookpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4299: *rungetpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4300: *rungetpredpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4301: *runindbhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4302: *runindividualhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4303: *runinsertdbhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4304: *runmatchhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4305: *runnextequalhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4306: *runnextitemhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4307: *runpatternhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4308: *runputpathhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4309: *runremovedbhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4310: *runsmergehooks* -- special variable -- initial value: t \h'|\niu'34 ! 4311: *runstrequalhooks* -- special variable -- initial value: t \h'|\niu'34 ! 4312: .sp ! 4313: *stream* -- special atom \h'|\niu'13 ! 4314: *stream:* -- special atom \h'|\niu'13 ! 4315: *toplevelp* -- special variable -- initial value: <UNBOUND> \h'|\niu'* ! 4316: *unhashablevalues* -- special variable -- initial value: \h'|\niu'* ! 4317: (0 unbound *pearlunbound* nilsym (nilstruct)) ! 4318: *use* -- special atom \h'|\niu'35 ! 4319: *usealiases* -- special variable -- initial value: t \h'|\niu'51 ! 4320: *warn* -- special variable -- initial value: t \h'|\niu'17 ! 4321: *zero-ordinal-value* -- special variable -- initial value: 0 \h'|\niu'31 ! 4322: .sp ! 4323: ! -- splicing macro \h'|\niu'52 ! 4324: $ -- splicing macro \h'|\niu'52 ! 4325: = -- read macro \h'|\niu'28 ! 4326: ? -- read macro \h'|\niu'16 ! 4327: .sp ! 4328: (addalist 'var 'inst) -- macro \h'|\niu'* ! 4329: (addbasehook 'conscell 'item) -- macro \h'|\niu'* ! 4330: (addhistory 'line) \h'|\niu'* ! 4331: (addpredpath 'item 'path 'pred) \h'|\niu'10 ! 4332: (addsetpath 'item 'path 'value) \h'|\niu'10 ! 4333: .sp ! 4334: (addtoexpansionlists) -- macro \h'|\niu'** ! 4335: (adjvarset 'var 'val) -- macro \h'|\niu'* ! 4336: (allocdef numofslots) -- macro \h'|\niu'* ! 4337: (allocval numofslots) -- macro \h'|\niu'* ! 4338: (applypath 'fcn 'item 'path) \h'|\niu'10 ! 4339: .sp ! 4340: (base name [storage] slot1 ...) -- macro \h'|\niu'56 ! 4341: (basicmatch 'item1 'item2) \h'|\niu'46 ! 4342: (block [blockname] varlist) -- fexpr \h'|\niu'47 ! 4343: (blockatom 'symbol) \h'|\niu'48 ! 4344: (blockp 'potblock) \h'|\niu'30 ! 4345: .sp ! 4346: (breakprintfn '*printval*) \h'|\niu'58, 59 ! 4347: (builddb newdb [olddb]) -- fexpr \h'|\niu'38 ! 4348: (buildintvalue 'intval 'bppset) -- macro \h'|\niu'* ! 4349: (buildslot) -- macro \h'|\niu'** ! 4350: (buildstructvalue 'structdesc) -- macro \h'|\niu'* ! 4351: (buildsymbolvalue 'symname) -- macro \h'|\niu'* ! 4352: (buildvalue 'value 'typenum 'ppset) \h'|\niu'* ! 4353: .sp ! 4354: (cb name [storage] slot1 ...) -- macro \h'|\niu'56 ! 4355: (ce basename newname [storage] slot1 ...) -- macro \h'|\niu'56 ! 4356: (cf name [storage] slot1 ...) -- macro \h'|\niu'56 ! 4357: (checkandrunbasehooks2 'fcn 'item1 'item2) -- macro \h'|\niu'** ! 4358: (checkandrunslothooks2 'fcn 'hooks 'val1 'val2 'item1 'item2) -- macro \h'|\niu'** ! 4359: (checkrunhandlebasehooks1 'fcn 'runhooksatom) -- macro \h'|\niu'** ! 4360: (checkrunhandleslothooks1 'fcn 'runhooksatom) -- macro \h'|\niu'** ! 4361: (ci basename [storage] slot1 ...) -- macro \h'|\niu'56 ! 4362: .sp ! 4363: (cleardb ['db]) \h'|\niu'39 ! 4364: (cleardb1 'db) \h'|\niu'39 ! 4365: (cleardbactive 'db) -- macro \h'|\niu'* ! 4366: (clearhashandformat 'slotnum 'defblock) -- macro \h'|\niu'* ! 4367: (clearpath 'item 'path) \h'|\niu'10 ! 4368: .sp ! 4369: (compatible 'slotnum 'item1 'item2) -- macro \h'|\niu'* ! 4370: (connectdb 'newdb 'olddb) \h'|\niu'* ! 4371: (consistentvalue 'val 'predlist 'typenum 'item) -- macro \h'|\niu'* ! 4372: (constructvalue) -- macro \h'|\niu'** ! 4373: (convertpreds 'pred) \h'|\niu'* ! 4374: (copy 'list) \h'|\niu'54 ! 4375: (copypatternslot) -- macro \h'|\niu'** ! 4376: (copyslice) -- macro \h'|\niu'** ! 4377: (copyslot 'nameblock) -- macro \h'|\niu'** ! 4378: .sp ! 4379: (cp basename [storage] slot1 ...) -- macro \h'|\niu'56 ! 4380: (cr selector ...) -- fexpr \h'|\niu'55 ! 4381: (create selector ...) -- fexpr \h'|\niu'5 ! 4382: (createbase 'newname 'slots) \h'|\niu'* ! 4383: (createexpanded 'oldname 'newname 'slots) \h'|\niu'* ! 4384: (createfunction 'fcnname 'slots) \h'|\niu'* ! 4385: (createindividual 'basename 'slots) \h'|\niu'* ! 4386: (createpattern 'basename 'slots) \h'|\niu'* ! 4387: .sp ! 4388: (databasep 'potdb) \h'|\niu'30 ! 4389: (dbcr selector ...) -- macro \h'|\niu'56 ! 4390: (dbcreate selector ...) -- macro \h'|\niu'12, 56 ! 4391: (debugprint 'item) \h'|\niu'21 ! 4392: (defatom 'symbol) \h'|\niu'7 ! 4393: .sp ! 4394: (defaultfortype 'typenum) -- macro \h'|\niu'* ! 4395: (definitionp 'potdef) \h'|\niu'30 ! 4396: (delpredpath 'item 'path 'pred) \h'|\niu'10 ! 4397: (delsetpath 'item 'path 'value) \h'|\niu'10 ! 4398: (disguisedas 'filler 'struct ['db]) \h'|\niu'29 ! 4399: (disguisedas1 'filler 'struct 'db) \h'|\niu'29 ! 4400: .sp ! 4401: (dobasehooks2< 'fcn 'runhookatom) -- macro \h'|\niu'** ! 4402: (dobasehooks2> 'fcn 'runhookatom) -- macro \h'|\niu'** ! 4403: (doslothooks2< 'fcn 'runhookatom) -- macro \h'|\niu'** ! 4404: (doslothooks2> 'fcn 'runhookatom) -- macro \h'|\niu'** ! 4405: (dskprintfn '*printval*) \h'|\niu'60 ! 4406: .sp ! 4407: (endallblocks) \h'|\niu'48 ! 4408: (endanyblocks blockname) -- fexpr \h'|\niu'48 ! 4409: (endblock [blockname]) -- fexpr \h'|\niu'47 ! 4410: (enforcetype 'value 'typenum) \h'|\niu'* ! 4411: (equalvalue 'xval 'yval 'typenum) -- macro \h'|\niu'* ! 4412: (evalfcn 'item) \h'|\niu'51 ! 4413: .sp ! 4414: (executehook1 fcn value item defblock) -- macro \h'|\niu'** ! 4415: (executehook2 fcn val1 val2 item1 item2 defblock result) -- macro \h'|\niu'** ! 4416: (expanded basename newname [storage] slot1 ...) -- macro \h'|\niu'56 ! 4417: (expandedfetch 'item ['db]) \h'|\niu'42 ! 4418: (expandedfetch1 'item 'db) \h'|\niu'42 ! 4419: .sp ! 4420: (fcnslot) -- macro \h'|\niu'** ! 4421: (fetch 'item ['db]) \h'|\niu'12, 43 ! 4422: (fetch1 'item 'db) \h'|\niu'12, 43 ! 4423: (fetcheverywhere 'item ['db]) \h'|\niu'19, 25 ! 4424: (fetcheverywhere1 'item 'db) \h'|\niu'19, 25 ! 4425: (fetchcreate selector ...) -- macro \h'|\niu'14, 56 ! 4426: (fillbaseslot) -- macro \h'|\niu'** ! 4427: (fillin1 'fcn 'value 'item 'defblock) \h'|\niu'33 ! 4428: (fillin2 'fcn 'val1 'val2 'item1 'item2 'defblock 'result) \h'|\niu'33 ! 4429: (fillindivslot) -- macro \h'|\niu'** ! 4430: .sp ! 4431: (findnextblockstart) -- macro \h'|\niu'** ! 4432: (findslotnum) -- macro \h'|\niu'** ! 4433: (findstructsymbolpair 'defblock 'symbol) -- macro \h'|\niu'** ! 4434: (firstfetch pattern) -- macro \h'|\niu'14, 56 ! 4435: (fn name [storage] slot1 ...) -- macro \h'|\niu'56 ! 4436: .sp ! 4437: (followpath 'item 'path) \h'|\niu'* ! 4438: (for val 'init 'final &rest 'body) -- macro \h'|\niu'54 ! 4439: (foreach 'stream fcn) -- fexpr \h'|\niu'54 ! 4440: (fp 'item ['lmar ['rmar]]) \h'|\niu'56 ! 4441: (freezebindings 'struct) \h'|\niu'48 ! 4442: (freezeblock 'blockname) \h'|\niu'49 ! 4443: (freezestruct 'struct) \h'|\niu'49 ! 4444: .sp ! 4445: (fullform 'item) \h'|\niu'20 ! 4446: (fullprint 'item ['lmar ['rmar]]) \h'|\niu'20, 37 ! 4447: (fullprint1 'item 'lmar 'rmar) \h'|\niu'20, 37 ! 4448: (fullslotform) -- macro \h'|\niu'** ! 4449: .sp ! 4450: (getalist 'inst) -- macro \h'|\niu'57 ! 4451: (getalistcp 'inst) -- macro \h'|\niu'57 ! 4452: (getbasehooks 'defblock) -- macro \h'|\niu'57 ! 4453: (getdb1 'db) -- macro \h'|\niu'57 ! 4454: (getdb2 'db) -- macro \h'|\niu'57 ! 4455: (getdbactive 'db) -- macro \h'|\niu'57 ! 4456: (getdbchildren 'db) -- macro \h'|\niu'57 ! 4457: (getdbname 'db) -- macro \h'|\niu'57 ! 4458: (getdbparent 'db) -- macro \h'|\niu'57 ! 4459: (getdefaultinst 'defblock) \h'|\niu'57 ! 4460: (getdefinition 'valblock) \h'|\niu'57 ! 4461: (getenforce 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4462: (getexpansionlist 'defblock) -- macro \h'|\niu'57 ! 4463: (getformatinfo 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4464: (gethash* 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4465: (gethash** 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4466: (gethash1 'num1 'db1) -- macro \h'|\niu'57 ! 4467: (gethash2 'num1 'num2 'db2) -- macro \h'|\niu'57 ! 4468: (gethash3 'num1 'num2 'num3 'db2) -- macro \h'|\niu'57 ! 4469: (gethash: 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4470: (gethash:: 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4471: (gethash< 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4472: (gethash> 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4473: (gethashalias 'defblock) -- macro \h'|\niu'57 ! 4474: (gethashinfo 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4475: (gethashvalue 'slotnum 'item 'defblock) \h'|\niu'* ! 4476: .sp ! 4477: (gethookpath 'item 'path) \h'|\niu'10 ! 4478: (getisa 'valblock) -- macro \h'|\niu'57 ! 4479: (getpath 'item 'path) \h'|\niu'10 ! 4480: (getpname 'defblock) -- macro \h'|\niu'57 ! 4481: (getppset 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4482: (getpred 'slotnum 'inst) -- macro \h'|\niu'57 ! 4483: (getpredpath 'item 'path) \h'|\niu'10 ! 4484: .sp ! 4485: (getsinglevalue 'slotnum 'item) \h'|\niu'* ! 4486: (getslot 'slotnum 'inst) -- macro \h'|\niu'57 ! 4487: (getslothooks 'slotnum 'inst) -- macro \h'|\niu'57 ! 4488: (getslotname 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4489: (getslottype 'slotnum 'defblock) -- macro \h'|\niu'57 ! 4490: (getstructlength 'defblock) -- macro \h'|\niu'57 ! 4491: (getstructorsymnum 'strsym) -- macro \h'|\niu'57 ! 4492: .sp ! 4493: (getsymbol 'symname) \h'|\niu'4 ! 4494: (getsymbolpname 'symbolitem) -- macro \h'|\niu'57 ! 4495: (getuniquenum 'defblock) -- macro \h'|\niu'57 ! 4496: (getvalue 'slotnum 'inst) \h'|\niu'57 ! 4497: (getvarandvalue 'slotnum 'inst 'var) \h'|\niu'57 ! 4498: (getvarval 'slotnum 'inst) -- macro \h'|\niu'57 ! 4499: .sp ! 4500: (*global* varname) -- fexpr \h'|\niu'46 ! 4501: (global variable) -- fexpr \h'|\niu'45 ! 4502: (globalp 'variable) \h'|\niu'45 ! 4503: (handlehookresult 'oldval 'newval) -- macro \h'|\niu'** ! 4504: (hashablevalue 'slotnum 'item 'defblock) -- macro \h'|\niu'** ! 4505: (hashslot) -- macro \h'|\niu'** ! 4506: .sp ! 4507: (hidden 'command) -- macro \h'|\niu'35 ! 4508: (higheroreq 'item1 'item2) -- macro \h'|\niu'* ! 4509: (history ['num]) \h'|\niu'53 ! 4510: (ind basename [storage] slot1 ...) -- macro \h'|\niu'56 ! 4511: (indb 'item ['db]) \h'|\niu'14 ! 4512: (indb1 'item 'db) \h'|\niu'14 ! 4513: (individual basename [storage] slot1 ...) -- macro \h'|\niu'56 ! 4514: .sp ! 4515: (inheritvalue 'structdef) -- macro \h'|\niu'** ! 4516: (inlinecreate selector ...) -- macro \h'|\niu'14, 56 ! 4517: (inlinefetchcreate selector ...) -- macro \h'|\niu'14, 56 ! 4518: (insertdb 'item ['db]) \h'|\niu'12 ! 4519: (insertdb1 'item 'db) \h'|\niu'12 ! 4520: .sp ! 4521: (insidecreate selector ...) -- fexpr \h'|\niu'** ! 4522: (insidefetch patdef expdefs) -- macro \h'|\niu'** ! 4523: (insidefetcheverywhere patdef expdefs) -- macro \h'|\niu'** ! 4524: (insidepatternize 'item) \h'|\niu'** ! 4525: (insidescopy 'item) \h'|\niu'** ! 4526: (installadjunct 'adjunctvar) -- macro \h'|\niu'** ! 4527: (installglobal 'globalvar) -- macro \h'|\niu'** ! 4528: (installvar 'varname) -- macro \h'|\niu'** ! 4529: .sp ! 4530: (instatom 'symbol) \h'|\niu'7 ! 4531: (isa 'item1 'name) \h'|\niu'42 ! 4532: (isanexpanded 'item1 'item2) \h'|\niu'42 ! 4533: (islambda 'fcnname) \h'|\niu'* ! 4534: .sp ! 4535: (match 'item1 'item2) \h'|\niu'46 ! 4536: (msgprintfn '*printval*) \h'|\niu'58, 62 ! 4537: (newnum) -- macro \h'|\niu'* ! 4538: (nextequal 'stream) \h'|\niu'46 ! 4539: (nextitem 'stream) \h'|\niu'13 ! 4540: (noalias) -- macro \h'|\niu'** ! 4541: .sp ! 4542: (nullstruct 'item) \h'|\niu'42 ! 4543: (nullsym 'item) \h'|\niu'42 ! 4544: (numberofslot 'slotname 'defblock) -- macro \h'|\niu'57 ! 4545: (onesymbol) -- macro \h'|\niu'** ! 4546: (ordatom 'symbol) \h'|\niu'31 ! 4547: (ordinal name vallist) -- fexpr \h'|\niu'30 ! 4548: .sp ! 4549: (pat basename [storage] slot1 ...) -- macro \h'|\niu'56 ! 4550: (path fcn 'item 'pathlist ['val]) -- macro \h'|\niu'9 ! 4551: (pattern basename [storage] slot1 ...) -- macro \h'|\niu'56 ! 4552: (patternize 'item) -- macro \h'|\niu'55 ! 4553: (patternizeslot) -- macro \h'|\niu'** ! 4554: (pboundp 'a) \h'|\niu'45 ! 4555: .sp ! 4556: (pearlprintfn '*printval*) \h'|\niu'3, 4 ! 4557: (pexp basename newname [storage] slot1 ...) -- macro \h'|\niu'56 ! 4558: (pfunction name [storage] slot1 ...) -- macro \h'|\niu'56 ! 4559: (pname 'item) \h'|\niu'4 ! 4560: (ppsetform 'slotval 'ppsetname) \h'|\niu'* ! 4561: .sp ! 4562: (prefix 'item1 'item2) \h'|\niu'52 ! 4563: (prefixcommandhistory) \h'|\niu'* ! 4564: (prefixcommandvalue) \h'|\niu'* ! 4565: (printdb ['db]) \h'|\niu'21 ! 4566: (printdb1 'db) \h'|\niu'21 ! 4567: (psymbolp 'potsymbol) \h'|\niu'30 ! 4568: (punbound) \h'|\niu'45 ! 4569: .sp ! 4570: (punboundatomp 'yyy) \h'|\niu'* ! 4571: (putalist 'alist 'inst) -- macro \h'|\niu'* ! 4572: (putalistcp 'alist 'inst) -- macro \h'|\niu'* ! 4573: (putbasehooks 'hooklist 'defblock) -- macro \h'|\niu'* ! 4574: (putdb1 'db1 'db) -- macro \h'|\niu'*** ! 4575: (putdb2 'db2 'db) -- macro \h'|\niu'*** ! 4576: (putdbchildren 'childlist 'db) -- macro \h'|\niu'*** ! 4577: (putdbname 'name 'db) -- macro \h'|\niu'* ! 4578: (putdbparent 'parent 'db) -- macro \h'|\niu'*** ! 4579: (putdef 'defblock 'valblock) -- macro \h'|\niu'*** ! 4580: (putdefaultinst 'valblock 'defblock) -- macro \h'|\niu'*** ! 4581: (putenforce 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4582: (putexpansionlist 'explist 'defblock) -- macro \h'|\niu'*** ! 4583: (putformatinfo 'slotnum 'hashnum 'defblock) -- macro \h'|\niu'*** ! 4584: (puthash* 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4585: (puthash** 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4586: (puthash1 'num1 'db1 'item) -- macro \h'|\niu'* ! 4587: (puthash2 'num1 'num2 'db2 'item) -- macro \h'|\niu'* ! 4588: (puthash3 'num1 'num2 'num3 'db2 'item) -- macro \h'|\niu'* ! 4589: (puthash: 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4590: (puthash:: 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4591: (puthash< 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4592: (puthash> 'slotnum 'defblock) -- macro \h'|\niu'*** ! 4593: (puthashalias 'hashnum 'defblock) -- macro \h'|\niu'*** ! 4594: (puthashinfo 'slotnum 'hashnum 'defblock) -- macro \h'|\niu'*** ! 4595: (putisa 'isa 'valblock) -- macro \h'|\niu'*** ! 4596: .sp ! 4597: (putpath 'item 'path 'value) \h'|\niu'10 ! 4598: (putpname 'name 'defblock) -- macro \h'|\niu'*** ! 4599: (putppset 'slotnum 'setname 'defblock) -- macro \h'|\niu'* ! 4600: (putpred 'slotnum 'value 'inst) -- macro \h'|\niu'* ! 4601: (putslot 'slotnum 'value 'inst) -- macro \h'|\niu'*** ! 4602: (putslothooks 'slotnum 'slothooklist 'inst) -- macro \h'|\niu'* ! 4603: (putslotname 'slotnum 'slotname 'defblock) -- macro \h'|\niu'*** ! 4604: (putslottype 'slotnum 'typenum 'defblock) -- macro \h'|\niu'*** ! 4605: (putstructlength 'size 'defblock) -- macro \h'|\niu'*** ! 4606: (putsymbolpname 'name 'block) -- macro \h'|\niu'*** ! 4607: (putuniquenum 'num 'defblock) -- macro \h'|\niu'*** ! 4608: (putvarval 'slotnum 'value 'inst) -- macro \h'|\niu'*** ! 4609: (reallitatom 'potatom) \h'|\niu'* ! 4610: .sp ! 4611: (releasedb 'db) \h'|\niu'38 ! 4612: (removedb 'item ['db]) \h'|\niu'12 ! 4613: (removedb1 'item 'db) \h'|\niu'12 ! 4614: (removeslot) -- macro \h'|\niu'** ! 4615: (revassq 'value 'alist) \h'|\niu'* ! 4616: (runbasehooks1 'fcn 'item) \h'|\niu'33 ! 4617: (runbasehooks2 'fcn 'item1 'item2 'result) \h'|\niu'33 ! 4618: (runslothooks1 'fcn 'item 'slotname 'value) \h'|\niu'33 ! 4619: (runslothooks2 'fcn 'item1 'item2 'slotname 'val1 'val2) \h'|\niu'33 ! 4620: .sp ! 4621: (savecontinue 'directory 'name) \h'|\niu'53 ! 4622: (savefresh 'directory 'name) \h'|\niu'53 ! 4623: (savepearl) \h'|\niu'* ! 4624: (scopy 'item) -- macro \h'|\niu'55 ! 4625: (scopyslot) -- macro \h'|\niu'** ! 4626: (setblock blockname) -- fexpr \h'|\niu'48 ! 4627: .sp ! 4628: (setdbactive 'db) -- macro \h'|\niu'*** ! 4629: (setdbsize 'poweroftwo) \h'|\niu'39 ! 4630: (setv var 'val 'environment) -- fexpr \h'|\niu'47 ! 4631: (slotequal 'slotnum 'item1 'item2) \h'|\niu'* ! 4632: (slotnametonumber 'slotname 'defblock) -- macro \h'|\niu'** ! 4633: (smerge 'build 'from) \h'|\niu'55 ! 4634: .sp ! 4635: (standardfetch 'item ['db]) \h'|\niu'43 ! 4636: (standardfetch1 'item 'db) \h'|\niu'43 ! 4637: (standardmatch 'item1 'item2) \h'|\niu'46 ! 4638: (streamp 'potstream) \h'|\niu'30 ! 4639: (streamtolist 'stream) \h'|\niu'14 ! 4640: .sp ! 4641: (strequal 'item1 'item2) \h'|\niu'46 ! 4642: (structurenamep 'potname) \h'|\niu'30 ! 4643: (structurep 'potstruct) \h'|\niu'30 ! 4644: (symatom 'symbol) \h'|\niu'4 ! 4645: (symbol name1 name2 ...) -- fexpr \h'|\niu'4 ! 4646: (symbole 'symname) \h'|\niu'4 ! 4647: (symbolnamep 'potname) \h'|\niu'30 ! 4648: .sp ! 4649: (thawbindings 'struct) \h'|\niu'49 ! 4650: (thawblock 'blockname) \h'|\niu'49 ! 4651: (thawstruct 'struct) \h'|\niu'49 ! 4652: (unbind globalvar) -- fexpr \h'|\niu'45 ! 4653: (unbindvars 'structure) -- macro \h'|\niu'46 ! 4654: (unboundatomp 'yyy) \h'|\niu'* ! 4655: .sp ! 4656: (valform 'item) \h'|\niu'20 ! 4657: (valprint 'item ['lmar ['rmar]]) \h'|\niu'20 ! 4658: (valprint1 'item 'lmar) \h'|\niu'20 ! 4659: (valslotform) -- macro \h'|\niu'** ! 4660: (valueof 'var 'struct) \h'|\niu'17 ! 4661: .sp ! 4662: (*var* varname) -- fexpr \h'|\niu'46 ! 4663: (varset 'var 'val) -- macro \h'|\niu'* ! 4664: (varvalue var 'val) -- fexpr \h'|\niu'17 ! 4665: (visible 'command) -- macro \h'|\niu'35 ! 4666: (vp 'item ['lmar ['rmar]]) \h'|\niu'56 ! 4667: (while 'val &rest 'body) -- macro \h'|\niu'54 ! 4668: .fi ! 4669: .bp ! 4670: .nr PS 9 ! 4671: .nr VS 11p ! 4672: .ps 9 ! 4673: .vs 11p ! 4674: .NH ! 4675: Concept Index ! 4676: .LP ! 4677: .nr PS 8 ! 4678: .nr VS 10p ! 4679: .ps 8 ! 4680: .vs 10p ! 4681: .nf ! 4682: abbreviations \ki55-56 ! 4683: accessing slots of structures \h'|\niu'8-10 ! 4684: accessing structure default instances \h'|\niu'7 ! 4685: accessing structure definitions \h'|\niu'7 ! 4686: accessing symbols \h'|\niu'4 ! 4687: .sp ! 4688: adding slots to structures \h'|\niu'40 ! 4689: adding to the data base \h'|\niu'12 ! 4690: adjunct variables \h'|\niu'30 ! 4691: affecting forced aliasing (^) \h'|\niu'27 ! 4692: ako's (expanded structures) \h'|\niu'40-42 ! 4693: .sp ! 4694: aliasing of commands \h'|\niu'51 ! 4695: aliasing in hashing \h'|\niu'27 ! 4696: ampersand (&) hashing \h'|\niu'26 ! 4697: and, in predicates \h'|\niu'28 ! 4698: anti-aliasing in hashing (<) \h'|\niu'27 ! 4699: *any* \h'|\niu'15 ! 4700: automatic storing of structures \h'|\niu'8, 56 ! 4701: .sp ! 4702: base hooks \h'|\niu'32-37 ! 4703: bases \h'|\niu'5 ! 4704: blocks \h'|\niu'47-48 ! 4705: building structures \h'|\niu'5 ! 4706: building upon data bases \h'|\niu'38, 39 ! 4707: .sp ! 4708: changing slots of structures \h'|\niu'8 ! 4709: clearing data bases \h'|\niu'39 ! 4710: colon (:) hashing \h'|\niu'23 ! 4711: colon-colon (::) hashing \h'|\niu'24 ! 4712: .sp ! 4713: command aliasing \h'|\niu'51 ! 4714: command history \h'|\niu'51-53 ! 4715: command history, printing \h'|\niu'53 ! 4716: compatibility functions (UCI, Franz) \h'|\niu'58-62 ! 4717: .sp ! 4718: controlling running of hooks \h'|\niu'33-34 ! 4719: controlling results with hooks \h'|\niu'35 ! 4720: controlling unbinding of variables \h'|\niu'48-49 ! 4721: converting from internal form \h'|\niu'20 ! 4722: copy redefined \h'|\niu'54 ! 4723: copying structures \h'|\niu'55 ! 4724: .sp ! 4725: creating data bases \h'|\niu'38, 39 ! 4726: creating patterns \h'|\niu'15-16 ! 4727: creating base structures \h'|\niu'5 ! 4728: creating individual structures \h'|\niu'6 ! 4729: creating symbols \h'|\niu'4 ! 4730: .sp ! 4731: data bases \h'|\niu'11 ! 4732: data bases, building upon \h'|\niu'39 ! 4733: data bases, clearing \h'|\niu'39 ! 4734: data bases, creating \h'|\niu'38 ! 4735: data bases, fetching from \h'|\niu'12, 19, 25, 42, 43, 46 ! 4736: data bases, freeing \h'|\niu'40 ! 4737: data bases, inserting into \h'|\niu'12 ! 4738: data bases, printing \h'|\niu'21 ! 4739: data bases, releasing \h'|\niu'40 ! 4740: data bases, removing from \h'|\niu'12 ! 4741: data bases, setting size of \h'|\niu'39 ! 4742: .sp ! 4743: debugging \h'|\niu'21 ! 4744: debugging print \h'|\niu'21 ! 4745: declaring global variables \h'|\niu'45 ! 4746: .sp ! 4747: default fetch function \h'|\niu'43 ! 4748: default instance for a structure \h'|\niu'15 ! 4749: default instance, accessing \h'|\niu'7 ! 4750: default match function \h'|\niu'46 ! 4751: default printing functions \h'|\niu'20, 58, 60-61, 62 ! 4752: default values for slots \h'|\niu'14-15 ! 4753: defaults, inherited \h'|\niu'41-42 ! 4754: .sp ! 4755: defining structures \h'|\niu'5 ! 4756: defining symbols \h'|\niu'4 ! 4757: definitions of structures, accessing \h'|\niu'7 ! 4758: deleting from the data base \h'|\niu'12 ! 4759: demons (hooks) \h'|\niu'32-37 ! 4760: .sp ! 4761: disguising in path \h'|\niu'10-11 ! 4762: disguising in predicates \h'|\niu'29 ! 4763: don't-care matching variable \h'|\niu'15 ! 4764: double-colon (::) hashing \h'|\niu'24 ! 4765: double-star (**) hashing \h'|\niu'24 ! 4766: dumping PEARL for later \h'|\niu'53 ! 4767: .sp ! 4768: efficiency despite variables \h'|\niu'30 ! 4769: enumerated (ordinal) types \h'|\niu'30 ! 4770: environment for variable evaluation \h'|\niu'46-47 ! 4771: environment, top level \h'|\niu'51-53 ! 4772: environments, in hooks \h'|\niu'33 ! 4773: .sp ! 4774: equality of structures \h'|\niu'46 ! 4775: equivalences of functions (UCI-Franz) \h'|\niu'58-62 ! 4776: error messages \h'|\niu'21 ! 4777: evaluating function structures \h'|\niu'51 ! 4778: evaluating in create \h'|\niu'22 ! 4779: expanded structures \h'|\niu'40 ! 4780: expanded structures, fetching \h'|\niu'42 ! 4781: .sp ! 4782: feedback, sending \h'|\niu'21 ! 4783: fetch, standard \h'|\niu'46 ! 4784: fetching expanded structures \h'|\niu'42 ! 4785: fetching from all buckets \h'|\niu'19, 25 ! 4786: fetching from the data base \h'|\niu'12 , 19, 25, 42, 43, 46 ! 4787: fetching with equality (not matching) \h'|\niu'46 ! 4788: .sp ! 4789: filling in special forms (in hooks) \h'|\niu'33 ! 4790: for loop \h'|\niu'54 ! 4791: forced aliasing (>) \h'|\niu'26 ! 4792: forest of data bases \h'|\niu'39-40 ! 4793: freeing data bases \h'|\niu'40 ! 4794: freezing variables \h'|\niu'48-49 ! 4795: .sp ! 4796: function equivalences (UCI-Franz) \h'|\niu'58-62 ! 4797: function structures \h'|\niu'49-51 ! 4798: function structures, evaluating \h'|\niu'51 ! 4799: getting symbols \h'|\niu'4 ! 4800: global variables \h'|\niu'45 ! 4801: greater-than (>) hashing \h'|\niu'26 ! 4802: .sp ! 4803: hash aliasing (&) \h'|\niu'26 ! 4804: hash marking \h'|\niu'17, 23-27 ! 4805: hashing problems \h'|\niu'18 ! 4806: hashing with variables \h'|\niu'30 ! 4807: hiding functions from hooks \h'|\niu'35 ! 4808: hierarchy of structures \h'|\niu'40 ! 4809: .sp ! 4810: history mechanism \h'|\niu'51-3 ! 4811: history number, printing in prompt \h'|\niu'53 ! 4812: hooks \h'|\niu'32-37 ! 4813: hooks, affecting result with \h'|\niu'35 ! 4814: hooks, controlling running of \h'|\niu'33-34 ! 4815: hooks, hiding functions from \h'|\niu'35 ! 4816: hooks, making functions visible to \h'|\niu'35 ! 4817: hooks, multi-argument \h'|\niu'28 ! 4818: hooks, running \h'|\niu'33-34 ! 4819: .sp ! 4820: if-added functions (hooks) \h'|\niu'32-37 ! 4821: indirection in path \h'|\niu'10-11 ! 4822: individuals \h'|\niu'6 ! 4823: inheritance in structures \h'|\niu'41-42 ! 4824: (.)init.prl file \h'|\niu'2-3 ! 4825: .sp ! 4826: inserting in the data base \h'|\niu'12 ! 4827: instances \h'|\niu'6 ! 4828: integer slots \h'|\niu'30 ! 4829: internal access functions \h'|\niu'57 ! 4830: internal form printing \h'|\niu'21 ! 4831: .sp ! 4832: invisible functions to hooks \h'|\niu'35 ! 4833: invisible results from functions \h'|\niu'53 ! 4834: isa's (expanded structures) \h'|\niu'40-42 ! 4835: less-than (<) hashing \h'|\niu'27 ! 4836: lexically scoped variables \h'|\niu'47-48 ! 4837: .sp ! 4838: looping functions \h'|\niu'54 ! 4839: low level access functions \h'|\niu'57 ! 4840: macros, special \h'|\niu'56 ! 4841: main data base \h'|\niu'11 ! 4842: marking structures for hashing \h'|\niu'17, 23-27 ! 4843: .sp ! 4844: match, standard \h'|\niu'46 ! 4845: match, without unbinding variables \h'|\niu'46 ! 4846: match-anything variable \h'|\niu'15 ! 4847: matching process \h'|\niu'44 ! 4848: matching two structures \h'|\niu'43 ! 4849: matching unbound variables \h'|\niu'44 ! 4850: matching-variables \h'|\niu'16-17 ! 4851: .sp ! 4852: merging structures \h'|\niu'55 ! 4853: modified input line, printing \h'|\niu'53 ! 4854: multi-argument matching predicates \h'|\niu'28, 32 ! 4855: next item in a stream \h'|\niu'13 ! 4856: nilstruct(ure) \h'|\niu'14 ! 4857: nilsym(bol) \h'|\niu'14 ! 4858: .sp ! 4859: or, in predicates \h'|\niu'28 ! 4860: ordinal types \h'|\niu'30-31 ! 4861: path functions \h'|\niu'10 ! 4862: path indirection \h'|\niu'10-11 ! 4863: pattern-matching variables \h'|\niu'16-17 ! 4864: .sp ! 4865: patterns \h'|\niu'12, 15, 43 ! 4866: patterns in matching \h'|\niu'43 ! 4867: predicates for object types \h'|\niu'30 ! 4868: predicates in matching \h'|\niu'27-29 ! 4869: predicates in matching, when run \h'|\niu'44 ! 4870: predicates in matching, multi-argument \h'|\niu'28 ! 4871: .sp ! 4872: print names \h'|\niu'4 ! 4873: printing PEARL objects \h'|\niu'20 ! 4874: printing command history \h'|\niu'53 ! 4875: printing data bases \h'|\niu'21 ! 4876: printing functions \h'|\niu'20 ! 4877: printing functions, standard \h'|\niu'3-4, 58, 60-61, 62 ! 4878: printing history number in prompt \h'|\niu'53 ! 4879: printing modified input line \h'|\niu'53 ! 4880: printing warnings \h'|\niu'17 ! 4881: .sp ! 4882: processing a stream \h'|\niu'13 ! 4883: prompt \h'|\niu'3-4 ! 4884: prompt-read-eval-print loop \h'|\niu'2-3, 51 ! 4885: read-eval-print loop \h'|\niu'2-3, 51 ! 4886: redirecting in create (! and $) \h'|\niu'22 ! 4887: releasing data bases \h'|\niu'40 ! 4888: removing from the data base \h'|\niu'12 ! 4889: .sp ! 4890: reporting bugs \h'|\niu'21 ! 4891: retrieving from the data base \h'|\niu'12 ! 4892: returning invisible results \h'|\niu'53 ! 4893: running hooks \h'|\niu'33-34 ! 4894: running under Franz Lisp \h'|\niu'2 ! 4895: running under UCI Lisp \h'|\niu'3 ! 4896: .sp ! 4897: saving PEARL for later \h'|\niu'53 ! 4898: scalar types \h'|\niu'30 ! 4899: short-circuiting in create \h'|\niu'22 ! 4900: side effect setting of adjunct variables \h'|\niu'30 ! 4901: size of data bases \h'|\niu'39 ! 4902: .sp ! 4903: slot hooks \h'|\niu'32-37 ! 4904: slot names to numbers \h'|\niu'57 ! 4905: slot types \h'|\niu'6 ! 4906: slot types, more specific \h'|\niu'30 ! 4907: slot values \h'|\niu'8-10 ! 4908: slot values in hooks \h'|\niu'32 ! 4909: slot values in predicates \h'|\niu'28 ! 4910: .sp ! 4911: special forms in hooks \h'|\niu'32 ! 4912: special forms in predicates \h'|\niu'28 ! 4913: special forms, filling in \h'|\niu'33 ! 4914: special macros \h'|\niu'56 ! 4915: standard fetch function \h'|\niu'43 ! 4916: standard match function \h'|\niu'46 ! 4917: .sp ! 4918: star (*) hashing \h'|\niu'17, 23 ! 4919: star-star (**) hashing \h'|\niu'24 ! 4920: (.)start.prl file \h'|\niu'2-3 ! 4921: startup files \h'|\niu'2-3 ! 4922: storing structures in the data base \h'|\niu'12 ! 4923: storing of structures in atoms \h'|\niu'8, 56 ! 4924: streams \h'|\niu'13 ! 4925: .sp ! 4926: structure equality \h'|\niu'46 ! 4927: structure matching \h'|\niu'44-45 ! 4928: structure predicates \h'|\niu'28-29 ! 4929: structure slots, further typing \h'|\niu'30 ! 4930: structured escapes to Lisp \h'|\niu'49-51 ! 4931: structures \h'|\niu'5 ! 4932: structures, copying \h'|\niu'55 ! 4933: structures, expanded \h'|\niu'40 ! 4934: structures, function \h'|\niu'49-51 ! 4935: structures, merging \h'|\niu'55 ! 4936: .sp ! 4937: symbols \h'|\niu'4 ! 4938: testing for nilstruct \h'|\niu'42 ! 4939: testing for nilsym \h'|\niu'42 ! 4940: testing for object types \h'|\niu'30 ! 4941: thawing variables \h'|\niu'48-49 ! 4942: .sp ! 4943: top level loop \h'|\niu'2-3, 51 ! 4944: top level loop functions \h'|\niu'59, 62 ! 4945: triple (**) hashing \h'|\niu'24 ! 4946: type tests for objects \h'|\niu'30 ! 4947: types in structure slots \h'|\niu'31-2 ! 4948: .sp ! 4949: unbinding global variables by match (lack of) \h'|\niu'45 ! 4950: unbinding global variables by user \h'|\niu'45 ! 4951: unbinding local variables by match \h'|\niu'45-6 ! 4952: unbinding local variables by user \h'|\niu'46 ! 4953: unbinding of variables, controlling \h'|\niu'48-49 ! 4954: up-arrow (^) hashing \h'|\niu'27 ! 4955: .sp ! 4956: values of variables \h'|\niu'17, 46 ! 4957: values of variables, setting \h'|\niu'47 ! 4958: variables in hooks \h'|\niu'32 ! 4959: variables in predicates \h'|\niu'28 ! 4960: variables with hashing \h'|\niu'30 ! 4961: variable, accessing values \h'|\niu'17, 46 ! 4962: variables, adjunct \h'|\niu'30 ! 4963: variables, controlling unbinding \h'|\niu'48-49 ! 4964: variables, freezing \h'|\niu'48-49 ! 4965: variables, global \h'|\niu'45 ! 4966: variables, lexically scoped \h'|\niu'47-48 ! 4967: variable, setting values \h'|\niu'47 ! 4968: variables, side effects \h'|\niu'30 ! 4969: variables, thawing \h'|\niu'48-49 ! 4970: variables, unbinding \h'|\niu'46 ! 4971: .sp ! 4972: visible functions to hooks \h'|\niu'35 ! 4973: warnings \h'|\niu'17 ! 4974: while loop \h'|\niu'54 ! 4975: .fi ! 4976: .nr PS 10 ! 4977: .nr VS 12p ! 4978: .ps 10 ! 4979: .vs 12p ! 4980: .bp 0 ! 4981: .DS C ! 4982: .LG ! 4983: \fBTable of Contents\fR ! 4984: .SM ! 4985: .DE ! 4986: .DS L ! 4987: 1. Introduction \ka 1 ! 4988: 2. Running PEARL \h'|\nau' 2 ! 4989: 2.1. Under Franz Lisp \h'|\nau' 2 ! 4990: 2.2. Under UCI Lisp \h'|\nau' 3 ! 4991: 3. Creating Simple Objects \h'|\nau' 4 ! 4992: 3.1. Defining Symbols \h'|\nau' 4 ! 4993: 3.2. Defining Structures \h'|\nau' 5 ! 4994: 4. Creating Individual Instances of Defined Structures \h'|\nau' 6 ! 4995: 5. Accessing Slots of Structures \h'|\nau' 8 ! 4996: 6. Storing In and Retrieving From the Data Base -- The Simplest Way \h'|\nau'11 ! 4997: 6.1 Storing In the Data Base: \fIInsertdb\fR and \fIRemovedb\fR\h'|\nau'11 ! 4998: 6.2 Retrieving Hash Buckets From the Data Base: \fIFetch\fR \h'|\nau'12 ! 4999: 6.3 Accessing the Results of \fIFetch\fR: \fINextitem\fR \h'|\nau'13 ! 5000: 7. The Default Values for Unspecified Slots \h'|\nau'14 ! 5001: 8. Using \fIPattern\fRs For More Flexible and Powerful Retrieval \h'|\nau'15 ! 5002: 9. Marking Structures During Creation For More Efficient Retrieval \h'|\nau'17 ! 5003: 10. Printing Structures, Symbols and Other PEARL Objects \h'|\nau'20 ! 5004: 11. Error Messages, Bugs, and Error Handling Abilities \h'|\nau'21 ! 5005: 12. Short-Circuiting and Redirecting \fICreate\fR Using !, $ and Atoms \h'|\nau'22 ! 5006: 13. More Flexible Hash Selection \h'|\nau'23 ! 5007: 14. Using Predicates to Constrain Fetching \h'|\nau'27 ! 5008: 15. More Useful Slot Types \h'|\nau'30 ! 5009: 16. Attaching Hooks to Structures (If-Added Demons) \h'|\nau'32 ! 5010: 17. Creating and Manipulating Multiple Data Bases \h'|\nau'38 ! 5011: 18. Creating a Forest of Data Bases \h'|\nau'39 ! 5012: 19. Creating Expanded Subtypes of Previously Defined Objects \h'|\nau'40 ! 5013: 20. Fetching Expanded Structures \h'|\nau'42 ! 5014: 21. How Two Objects \fIMatch\fR \h'|\nau'43 ! 5015: 21.1 When Is a Pattern not a \fIPattern\fR? \h'|\nau'43 ! 5016: 21.2 The Matching Process \h'|\nau'44 ! 5017: 22. Binding Blocks of Structures Together Via Common Variables \h'|\nau'47 ! 5018: 23. Controlling the Unbinding of Variables by \fIMatch\fR \h'|\nau'48 ! 5019: 24. Function Structures \h'|\nau'49 ! 5020: 25. More About the PEARL Top Level Loop and History Mechanism \h'|\nau'51 ! 5021: 26. Looping and Copying Functions \h'|\nau'54 ! 5022: 27. Miscellaneous Variations and Abbreviations \h'|\nau'55 ! 5023: 28. Low Level Access Functions \h'|\nau'57 ! 5024: 29. Appendix of UCI Lisp functions added to Franz PEARL \h'|\nau'58 ! 5025: 30. Appendix of Franz Lisp functions added to UCI Lisp PEARL \h'|\nau'62 ! 5026: 31. Bibliography \h'|\nau'63 ! 5027: 32. Index of Global Variables and Functions With Their Arguments \h'|\nau'64 ! 5028: 33. Concept Index \h'|\nau'71 ! 5029: .DE
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.