Page Numbers: Yes First Page: 1 Heading:qjk40(635) UNPUBLISHED WORKING DRAFT - DO NOT COPY OR DISTRIBUTE September 20, 1978 4:08 PM 4: Conversion [IVY]document>str-lev-convz18697l3008y774x2e8qck72\b25f5 29f0B e10 4. CONVERSION FROM INTERMEDIATE LEVEL STRUCTURES c\f5b48f0 The converter scans the intermediate structure, and all of these structures are converted into memory level structures, except certain pseudofunctionals which specify functional definition, category membership, further specification, and procedural attachment. The correspondences between intermediate structures and memory structures are listed in the section on data structure conversions. The pseudofunctionals used in meta descriptions are not converted into memory structures; the information they convey is stored in separate data structures by a process we call cataloging. To indicate that the meta description is not complete with respect to the original message level form, the PartialMeta flag is set in the handle to the metaAnchor for the structure which should have contained the information.x3e12j\4i9I122i17I246i17I 4.1 Data Structure Conversionsx3e12\f5b This section is a brief index into the conversions which go on between message level forms and memory level forms. Interpreted MapDescriptors are an internal form which are structurally very similar to MapDescriptors, but which are treated specially by Align when doing semantic (nonstructural) matching (see section 6 and 7). Two special syntactic forms and a number of pseudofunctionals are converted into these Interpreted MapDescriptors as indicated below.x3e12j\271i9I182b Message Form Memory Formx3e12\b Perspective MapDescriptor Specification MapDescriptor Sequence Sequence Set Set Lisp Invocation Interpreted MapDescriptor Case Interpreted MapDescriptor Functional MapDescriptor or Interpreted MapDescriptor (see below)x3e12j\b1B11b6B13b2B13b6B14b1B8b6B10b1B3b8B5b1B46b1B4b7B27b1B10b5B Functional Unit Prototype Argument Slot Namesx3e12j\b Or Disjunction alternatives Not Negation rejectedDescription SetOf SetDescription elementDescription SequenceOf SequenceDescription elementDescription MemberOf ElementDescription collectionDescription Contains CollectionDescription elementDescription Do Imperative lispForm During Contingency world contingentDescription Always InvariantDescription description Currently PresentDescription description Lisp* LispValue lispForm variables bindings Using* CaseSelection key matchControl patterns resultingDescriptionsx3e8j\21b1B32b1B46b1B51b1B49b1B55b1B * indicates a special syntactic form rather than a functional.x3e12j\f1 The user has two methods for getting access to the fields of an Interpreted MapDescriptor. One is through binding in a structural Align. The other is through a Lisp functionx3e18j\bi GetIA(imd oldHandle) Returns a handle for the anchor which is the argument for the Interpreted MapDescriptor, imd.x3e6j\bi 4.2 Functional Definitionsx3e12\f5b27f0 On any unit one can define an abbreviation for a perspective based on that unit. The pseudofunctional HasFunctional is used in the meta description of a unit to define such an abbreviation. For example, we can define a functional HusbandOf as follows:x3e12j\102i14I37b4B74i10I # Family ^1 1: HasFunctional(maleParent, HusbandOf, femaleParent) self: A Group maleParent: A Person; A Male femaleParent: A Person; A Female children: A Groupl3528d2999x3e12j\b9f1o4B2f0o0 56b5B9b10B19b12B21b8B Using this definition, the following two descriptors are equivalent:x3e12j HusbandOf(Mary) The maleParent from a Family with femaleParent = Mary.x3e12j\i16I1i54I The cataloging process stores the information contained in the HasFunctional declaration on an atom record on the name of the functional; e.g. on the atom HusbandOf. Since atoms are unique throughout the system, functional names are globally defined. The PartialMeta flag is set in the handle of the unit meta description indicating that a functional was defined there, but no other record is left. The conversion process uses these functional definition records to convert intermediate level functionals to their corresponding perspective forms, and then converts the perspective forms into memory level structures. No indication is placed in the memory structure to indicate that a mapping was entered from message level in a functional form.x3e12j\63i13I The syntax for a functional declaration is:x3e8j functionalSpecification = [whichForm *] "HasFunctional" * "(" focusSlotDesig "," functionalNameForm {"," slotDesig} ")" [pairList].z21167l5821d4269x3e6\f6b functionalNameForm = [whichForm] ["Interpreted"] functionalName.z17993l5539d4269x3e6\f6b focusSlotDesig = ["MemberOf"] slotName.z17993l5539d4269x3e6\f6b slotDesig = {"Quoted" | "MemberOf" | "Optional" | "Sequence" | "Set"} slotName.l7446d4268x3e6\f6b The Which and WhichIs alternatives for the functionalNameForm indicate preferred external format for instances of the functional. The keyword Interpreted indicates that that an interpreted map descriptor is to be constructed rather than a standard one. The keyword Quoted indicates that the argument will be enclosed in a KrlPointer descriptor. The keyword MemberOf indicates that a form containing a MemberOf functional should be constructed around the filler, or around the entire perspective if the MemberOf is on the focusSlotDesig. The Sequence and Set alternatives may only appear in a slotDesig in the last postion in the declaration: they specify that the functional may have arbitrarily many arguments after the last named slot which are to be collected as a sequence or set. The Optional alternative specifies that no filler pair should be constructed if the given instance argument is not present, rather than causing an error or building an empty collection.x3e12j\4i5I5i7I22i18I70i1I12f6b11f0B24i11I78b6B87b8B36i8I93b8B11i14I7i8I5i3I35i9I189i9I 4.3 Category Membershipx3e12\f5b23f0i KRL-1 provides a standard mechanism for inheritance from a unit, say Dog, to another unit, say Animal. In the self slot of Dog one puts a unit perspective An Animal. The category mechanism is an additional mechanism which provides a way of specifying mutual exclusion of mappings in a set of simple cases; for example, to reject quickly a match between something described as A Dog, and something described as A Cat, where both Dog and Cat may both be described as An Animal (but need not be). The category mechanism provides a way of specifying trees of mutual exclusions of mappings. The chain in the tree may sometimes be used to verify a simple mapping inheritance without going through each successively more general prototype individually.x3e12j\69i3I23i6I23i3I29i9I213i5I29i5I13i3I5i3I26i9I18i1I Examplesz17639x3e12jk40\b # Dog self:^1 An Animal 1: Category(Animal, Species)z17639x3e12jk40\b5B2b5o4B1f1 1f0o0 # Cat self:^1 An Animal 1: Category(Animal, Species)z17639x3e12jk40\b5B2b5o4B1f1 1f0o0 # Vertebrate self:^1 An Animal 1: Category(Animal, Anatomical)z17639x3e12jk40\b12B2b5o4B1f1 1f0o0 # Invertebrate self:^1 An Animal 1: Category(Animal, Anatomical)z17639x3e12jk40\b14B3b5o4B1f1 1f0o0 [CategoryTree 'Species '(Animal Cat (Dog Poodle (Spaniel CockerSpaniel EnglishSpaniel IrishSpaniel] z17639x3e12jk40\b14B89b1Bi1I Comment on Examplesx3e12jk40\b The footnote on the self slot of the first two units contain the specification of the incompatibility of the descriptions A Dog, A Cat. The first argument of the functional Category is a coreference to the common tree ancestor (in this case Animal). The second argument is a Lisp atom which names the tree in which Dog and Cat should be compared. The units for Vertebrate and Invertebrate indicate why a single tree is insufficient. It is clear that the latter two units are incompatible prototypes with respect to an anatomical description of an animal. But it is plausible (perhaps even correct) to describe a single entity as both A Cat and A Vertebrate. In the above units, note that the descriptor An Animal needed to be put explicitly in the footnoted slot if such inheritance is desired, and is not implicit in the Category meta description on the slot. As mentioned earlier, the chain in the tree may sometimes be used to verify a simple mapping inheritance without going through each prototype individually. x3e12jk40\122i12I40i8I60i6I69i3I5i3I36i10I5i12I248i6I4i12I3b45i9I110i8I30B The call to the Lisp function CategoryTree shows another way of expressing some of the same information that is expressed in the unit meta descriptions. In the tree named Species, Dog and Cat are incompatible, and Dog has two incompatible children Spaniel and Poodle, and Spaniel has three children which are incompatible. This tree could be used to verify quickly the incompatibility of CockerSpaniel and Cat.x3e12jk40\30i12I130i7I2i3I5i3I23i3I30i8I5i6I123i14I4i Basic Lisp Functions for Manipulating Mutual Exclusion Treesx3e24jk40\b For each category tree, there is a Lisp list structure isomorphic to a tree like the one shown in the example. The elements of the tree are slot coreferences. For each slot in a tree, there is a Lisp list paired with a handle to that slot anchor. The pairing is done using the Handle hash link mechanism described below. The associated list is an association list indexed by tree name; each value is an ordered list of handles of slots which are on the ancestor chain starting from the indexed slot.x3e12jk40 In the following functions, the treeName argument is a Lisp atom, and the tree members are handles to slot anchors. If an atom is given instead of such a handle, it is coerced to a handle for the self slot anchor of the unit named by that atom.x3e12jk40\245b (MakeParent parent child treeName) which creates a new linkage between child and parent as described above.x3e12jk40\b34B38i5I5i6I (InsertParent newParent child treeName) replaces the linkage between child and its current parent in treeName with one to newParent, and creates a linkage between newParent and the former parent.x3e12jk40\b39B30i5I27i8I13i9I32i10I (DeleteBranch node treeName saveDescendantsFlag) deletes a portion of the tree named by treeName from node down. If saveDescendantsFlag = T then then descendants from this node are attached as children to the parent of the node in the tree.x3e12jk40\b48B41i8I6i4I11i19I (TreeRelation node1 node2 treeName) returns a specification of the relation between node1 (a handle to a the self slot of a unit) and node2 in tree. Its return values arex3e12jk40\b35B49i5I45i5I4i5I ABOVE node1 is above node2 BELOW node1 is below node2 SAME node1 is identical to node2 CONFLICT node1 and node2 have a common parent and are not identical NONE there is no relation in tree between node1 and node2l4269x3e12jk40\7i5I10i5I8i5I10i5I8i5I17i5I10i5I5i5I75i4I9i5I5i5I If tree is not specified then all possible trees are searched, and if the two units share more than one tree, a signal is generated with the list of shared trees available.x3e12jk40\3i4I (HasCategories node) Returns an alist keyed by the names of category trees that this node (labeled anchor) appears in; returns NIL if it appears in no category trees. x3e12jk40\b20B149i (TreePrint treeName) prints tree in the form shown above (a form using CategoryTree).x3e12jk40\b20B8i4I39i12I (CategoryTree treeName treeList) builds the internal data structures associated with treeName and treeList. As shown in the example, treeList is a nested list structure of unit names (LISP atoms) or handles to slot anchors.x3e12jk40\b32B53i9I4i9I27i8I82i 4.4 Hash Links to Handlesx3e12jk40\f5b25f0 In order to find items associated with certain memory structures without having a field in the memory structure itself (which would require access to the memory file), we provide a facility which is equivalent to the hash linking mechanism for pointers in Interlisp. Since pointers to the file go through the intermediary of a handle, the hash link should work off the contents of the handle rather than the address where the handle is stored. A set of functions comparable to some of those on page 7.4 of the Interlisp manual are provided which work with the contents rather than the address of handles: HPuthash, HGethash, HRehash. The array used by these functions is an ordinary array built by a call to the function ARRAY. Therefore Maphash, ClearHash, and Harray equivalents are unnecessary. The SETA part of the array is used to hold a handle which is a key, and the SETD holds the associated value. The various forms of array specifiers of ordinary hash arrays are not supported. Therefore if an array overflow error occurs, the user is responsible for HRehashing into a new array and setting the appropriate global variable to the value of the new array.x3e12j\606b27B 4.5 Further Specificationsx3e12\f5b26B At the message level, one unit (Son) is designated as a further specification of another (Father) by the following notation:x3e12jk40\32b3B55b6B # Son^1 1: FurtherSpecified(Father)l4269d4904x3e6j\b5o4B2o0 26b6B The meaning of further specification is that the Son inherits all the slots and triggering information from the father unit. At cataloging time, this footnote will cause a direct link from the self slot of the Father unit to the Son unit to be cataloged and placed in the tree called FurtherSpecified (see section 4.8 for further information about trees).x3e12jk40\193i4I13b6B13b3B52i16I This is implemented by distributing information at the time of conversion from intermediate structure to memory structures. A given mapping to be added to an anchor is expanded into a set of mappings reflecting the further specification chain up from the son to father and so on, and attaches the filler pairs given in the initial mapping descriptor to the highest possible prototype in the FurtherSpecified chain. Thus if we have:x3e12jk40\392i16I # Father self: s1: s2: A Barl5984d4896x3e6jk144\b8B # Son^1 1: FurtherSpecified(Father) s2: A Mumble s3:l5984d4896x3e6j\b5o4B2o0 26b6B then a description A Son with [s1 = d1] [s2 = d2] [s3 = d3] would be converted into two mappings, one the equivalent of A Father with [s1 = d1] [s2 = d2] and the other the equivalent of A Son with [s3 = d3].x3e12jk40\19i41I60i14I1i20I32i20I Mappings with prototypes for all the entries in the further specified chain are always added, even if no filler pair is present which necessitates this.x3e12jk40 All relevant triggers will be activated, regardless of position in the hierarchy. Thus in the above example, WhenFilled triggers attached to either s2 in Son or s2 in Father would be activated.x3e12jk40\110i11I28i2I4b3B4i2I4b6B The access compiler converts calls to Seek to look for a filler pair attached to the highest prototype in the tree, and if that fails then it invokes servants from the bottom up. Thus a Seek with main argument the s2 from G00354 viewedAs a Son would look first for the filler of a pair with name s2 in a mapping with prototype Father, then check for servants on the s2 slot of Son, then on the s2 slot of Father.x3e12jk40\38i4I145i4I20i33I53i2I29b6B33i3I8b3B14i2I9b6B 4.6 Procedural Attachmentx3e24\f5b Procedural attachment of triggers and traps is done in KRL-1 in a style very similar to that done in KRL-0. A user can put in the meta description of any slot a special functional which indicates the trigger or trap to be used. As in KRL-0 triggers are probed by the system when using a unit as a template, in certain well defined situations. We will list the system probed triggers below. In addition to triggers on individual slots, the user can specify triggers which will be probed if any of a set of slots in the unit are "touched" by using a special pseudofunctional on the unit meta description. The example below illustrates each of these:x3e24j # Column ^1 1: TriggerOnAny({top, bottom}, WhenFilled, '(TryToAdd)) top:^2 A Number 2: Trigger(ToFill, '(CheckSumAndBottom)) bottom: A Number sum: A Numberx3e24j\b9f1o4 2f0o0B1f1 57f0b4f1o4 2f0o0B11f1 42f0b6f1 1f0 1B10b5B8b The pseudofunctional TriggerOnAny takes three arguments, a set of slotnames, a trigger name, and a Lisp form. The pseudofunctional Trigger takes two arguments, a trigger name and a Lisp form. The cataloging process indexes each trigger lisp form on the unit and slot name (the point of attachment for simple triggers, all those in the slot list for multiple triggers). The system will probe for the existence of specific types of triggers (known by trigger name) in circumstances specified in section 7. The user can of course probe slots for triggers with any name at any time. The pseudofunctionals Trigger and TriggerOnAny are not converted into memory structures, and the PartialMeta bit is set in the metaAnchor of any slot which contained a trigger form in its intermediate level version.x3e24j\21b12B99b8B466b8B4b12B Traps are procedures which can be fired when the anchor they are attached to is "touched" in specific ways. A functional named Trap is provided which takes two arguments, a Lisp atom which is the trap name (eg ToFill, WhenFilled), and a Lisp form which is the expression to be evaluated when the trap is snapped.x3e24j\128b4B The following are the types of triggers and traps probed by the system: ToFind, ToEnumerate, ToMatch, WhenFilled, WhenKnown, WhenEnumerationChanged, WhenDescribed, WhenIdentifiedx3e24\72b 4.7 Other Special Functionalsx3e24\f5b NonPrimary: All labelled anchors are considered primary, that is, the default repository for standard information about an entity. Two entities represented by a primary anchors are considered distinct if their anchors are not the same. To handle what we called in KRL-0 manifestations, we need to be able to specify that a labelled anchor is nonprimary. Attaching the pseudofunctional NonPrimary() to a labelled anchor causes the anchor to be so marked, and all handles which reference that anchor to have a bit indicating that it is a nonprimary anchor. In order to allow references to labelled nonprimary anchors before they are defined in a unit, we will provide a facility to declare a set of labelled anchors to be noprimary at the beginning of a file. A memory level form is created for this pseudofunctional.x3e24j\b13B260i15I101b13B158bi201BI23i2I UniqueMap, NonUniqueMap: In order to know whether two mapdescriptors with the same focus can be considered to be descriptions of the same mapping, we need to specify if a mapping is unique with respect to that focus. The default is that mappings are unique with respect to the self slot (all unit perspectives can be folded), and not unique with respect to any other slot (no slot perspectives can be folded). In order to override this default, two pseudofunctionals UniqueMap() and NonUniqueMap() are provided which can be attached to a slot to indicate a change from the default. This sets a bit in the metaAnchor which is propagated to any handle which points to this anchor. To insure consistent propogation before the unit is defined, we will again provide a declaration mechanism for uniqueness.x3e24j\b26B444b11B5b14B184bi121BI Do: In order to cause side effects in aligning, a special pseudofunctional Do is used. The argument to Do is a single Lisp expression. The operation of Do is described in section 6 and 7.x3e24j\b3B72b2B27b2B48b2B 4.8 Specification of the LISP interface in KRL-1x3e24\f5b48f0B KRL-1 (as seen by the user, not the implementer) depends on INTERLISP in two major ways. First, it uses the low-level INTERLISP data structures, such as strings, atoms, and numbers. Second, although it has agendas and procedural attachment (traps and triggers), it has no mechanisms for ordinary control flow (sequences, conditionals, subroutines, etc.) or argument passing. For this purpose it is parasitic on INTERLISP, using all of the standard mechanisms (including CLISP constructs such as the iterative statement, generators, coroutines, etc.). x3e12jk40 There exists a communication channel from LISP to KRL -- a conversion mechanism by which KRL structure can be created in LISP code using conversion-time values of LISP variables.x3e12jk40 The Nexus and its evaluationx3e12jk40\b When a piece of KRL syntax is embedded in LISP structure (using \.../ or \...//), it is not a direct representation of a memory level structure, but is a representation of an intermediate level structure which can contain surrogates which are to be replaced at evaluation time. The reader creates a data object called a nexus which has file pointers to the original message-level structure, and a record structure representation of the intermediate level structure which resulted from parsing it. When a nexus is evaluated, it carries out an operation of conversion in which surrogates appearing in the intermediate level structure are evaluated and the results used to build a memory structure. The value returned is a handle to this memory structure. If the intermediate level structure contains no surrogates, the conversion is done only once and the result returned on subsequent evaluations. No copying is necessary as e.g. Describe always copies its argument. Otherwise, conversion is done each time the nexus is evaluated. x3e12jk40\222i10I89i5I In fact, this process is shortcut by various subsystems. The access compiler looks at the nexus without first evaluating it, and compiles a piece of code which does the evaluations as needed in the execution. The interpreter, scheduler, etc. may do the same for some set of standard cases which can be easily recognized. However, any such shortcut must preserve the semantics of nexus evaluation.x3e12jk40 The form of surrogatesx3e12jk40\b A surrogate consists of an indicator followed by a LISP expression. The LISP expression is not preceded by a single quote, since it is one field of a surrogate, not an independent LispPointer descriptor. The LISP expression is evaluated when the conversion is done. There are four different kinds of syntactic elements for which surrogates exist: names, descriptors, tails, and paired tails.x3e12jk40\27i9I115i9I21i12I10i1I146i5I2i11I2i7I4i12I Names: Anywhere in the syntax where an arbitrary literal atom could appear (i.e. the non-terminal literalAtom in the syntax document), a surrogate of the form !Name expression can appear (!Name can be abbreviated by !N). The expression must evaluate to a literal atom. In the current syntax, literal atoms can appear as the expansions of unitName, slotName, functionalName, and as the first element in a bindingPair.z18697l4057d3528x3e6jk40\b6B92b11B50b5B1bi10BI165b8B2b8B2b14B5b1B26b11B Descriptors: Anwhere in the syntax where a descriptor can appear, a descriptor surrogate can appear. The indicators for descriptor surrogates are prefixed by a single !. In parentheses after the full name is a short form which can be used as an abbreviation. A descriptor surrogate produces a descriptor (or in one case, !Description, an anchor) which appear in the description where the surrogate appeared. The indicators for descriptor surrogates are:z18697l4057d3528x3e6jk40\b12B31b10B15i10I1i9I236i11I !Descriptor: (!Dr !Descr) The expression must evaluate to a descriptor handle (see the Datatypes document for a further description of handles), which points to a descriptor which is be copied into the constructed form.z18697l5327d4798x3e6jk40\b12B2b10B63i9I !Lisp: (!L) The expression is evaluated, and its value is made into a LispPointer descriptor.z18697l5327d4798x3e6jk40\b6B2b2B !Coreference: (!C !Coref) The expression must evaluate to an anchor handle for a labelled anchor. The surrogate is replaced with a coreference descriptor with that anchor as its target.z18697l5327d4798x3e6jk40\b13B2b9B !Krl: (!K) The expression must evaluate to a handle, which is then embedded in a KrlPointer descriptor.z18697l5327d4798x3e6jk40\b5B2b2B !Description: (!Dn !Descn) The expression must evaluate to an anchor handle. The descriptors in that anchor are copied into the description containing the surrogate.z18697l5327d4798x3e6jk40\b13B2b10B !Post: (!P) If the expression does not evaluate to a handle, its value is made into a LispPointer descriptor. If it evaluates to a labelled anchor handle, then it is placed in a coreference descriptor, otherwise it must be a handle to a KrlPointer descriptor, a copy of which is used.z18697l5327d4798x3e6jk40\b6B2b2B Tails: Anwhere in the syntax where a descriptionSequence can appear (a sequence of descriptions separated by commas in the normal syntax), a tail surrogate can appear. The indicators for tail surrogates are identical to those for descriptor surrogates, but prefixed by a !!. A tail surrogate contains a LISP expression which must evaluate to a list, each of whose elements meets the specification of the corresponding descriptor surrogate. It produces a sequence of anchors, each containing a descriptor (or in the case of !!Description, a list of descriptors) corresponding to an element of that list. The current syntax has descriptionSequence in a setEnumeration, sequenceEnumeration, and the argSequence of a functional.z18697l4057d3528x3e6jk40\b6B31b19B85i4I1i9I117b2B252b13B91b19B6b14B2b19B10b11B6b10B The use of tail surrogates in pseudo-functionals is not supported.z18697l4057d3528x3e6jk40\bi66BI Paired Tails: There are several places in the syntax (fillerPairs, pairList following a Functional) which allow arbitrary sequences of pairs whose first element is a name and whose second is a description. In the usual syntax these are written using "=". In any of these contexts, a Paired Tail surrogate can appear. Its indicator is prefixed by !!!, and is chosen from the same basic set as the descriptor and tail indicators. It is followed by two lisp expressions (again without quotes) separated by an "=". The first expression must evaluate to a list of literal atoms, and the second to a list, each member of which fits the requirements for the corresponding descriptor indicator. The resulting form contains a set of pairs whose length is the minimum of the two list lengths, and which has the corresponding name before each = and the corresponding description following it.z18697l4057d3528x3e6jk40\b13B41b11B2b8B13b10B187i21I43b3B An example:z18697x3e12jk72\b Assume we have:z18697l4057d3528x3e6jk40 x bound to the list (B C D)z18697l5327d4798x3jk40\b1B19b7B y bound to a handle for the self anchor from the unit: #E self: A Frob; Which Gritches thing: A Whateverz18697l5327d4798x3jk40\b1B54b53B w bound to the anchor for the thing slot of the unit Ez18697l5327d4798x3jk40\b1B29b5B18b1B z bound to a list of four descriptor handles corresponding to the descriptors: A Frob, A Bletch, A Blivet, and A Grindle.z18697l5327d4798x3jk40\b1B78b27B5b9B Then the nexus produced by reading the characters:z18697l4057d3528x3e6jk40 \A Frob with !Name (CAR x) = !Coreference y foo = {!!Lisp x, ...} bar = !Coreference w !Description y bletch = !Name (CADR x) Which !Name (CADDR x) (!Krl y, !!Name x) !!!Descriptor (CDR x) = z/z18697l4057d3528x3e6jk180\b produces the same memory structure as would have been produced from a message level structure as follows:z18697l4057d3528x3e6jk40 \A Frob with B = E foo = {'B, 'C, 'D, ...} bar = The thing inUnit E A Frob Which Gritches bletch = C Which D (Structure self inUnit E, B, C, D) C = A Frob D = A Bletch/ z18697l4057d3528x3e6jk180\b Notes:z18697x3e12jk72\b 1. The first pair uses B as a slot name, while E is a coreference descriptor to the self slot of unit E.z18697l4057d3528x3e6jk40 2. The second pair describes a set whose members include the LISP atoms B, C, and D.z18697l4057d3528x3e6jk40 3. The third pair contains a slot coreference and a copy of the descriptors in the anchor bound by y. This is not the same as establishing a coreference to y -- all it says is that the same descriptors are to be used.z18697l4057d3528x3e6jk40 4. The fourth pair describes an entity which is coreferent with the self slot of unit C, and which is in the relationship named by the functional D applied to four arguments. The first of these is a KrlPointer to the labelled anchor handle for the self slot in E, and the other three are coreferential to units B, C, and D.z18697l4057d3528x3e6jk40 5. Unit coreferences can be produced either by giving a !Name surrogate in an appropriate context where an atom name would be parsed as a coreference, or by using a !Coreference surrogate whose expression evaluates to a handle to an anchor which is a self slot.z18697l4057d3528x3e6jk40\56b5B104b12B 6. In the final pairs, even though z contained 4 descriptions, only two pairs appear, since the list of names included only 2 items.z18697l4057d3528x3e6jk40 x3e12jk40