Page Numbers: Yes First Page: 1
Heading:
April 26, 1979 7:19 PM[IFS]<KRL>document>match-pattern
7.1 Standardly recognized meta-descriptions in the pattern
Instructions to the matcher are in the form of meta-descriptions attached to anchors and descriptors in the pattern. They are all attached via the functional Do which takes a single argument, which is a Lisp expression according to the syntax below. Most of the arguments within an action form are evaluated, but at the time the action is taken, rather than the time the Alignment is initiated. The exceptions are arguments for variable name type, and count, which are evaluated only if they are not ATOMS.
Binding actions happen as the match proceeds, in order to make use of multiple bindings. All other actions are saved up and done when the entire match has succeeded. Evaluation of the arguments in the specification happens at the time they are carried out, in the environment in which Align was called. The function (ValueOf x) returns the value bound in the match for the variable x.
7.1.1. Standard Arguments
Action specifications involve carrying out some action on an object (descriptor or anchor) found in the course of the alignment. There are some standard ways of specifying what object (or objects) are to be acted on. These are shared by the different action types (Bind, Substitute, and Add) and by the different kinds of enumeration (Descriptors in an anchor, or Elements in a collection). They are designated in the forms below as the arguments test and count.
The basic form of the action specifies a set of candidates for the action. Each of these is tested, using the test, and a list made up (virtually when possible) of the successful ones. The count is then used to decide which member(s) of the list to act on.
When a test is given, it must evaluate to either a lisp predicate of one argument (e.g. the atom NLISTP or a form (LAMBDA(X)...)), a handle to a descriptor or anchor, or the distinguished atom ME. In testing candidates for an action, if a predicate is given, it will be APPLYed, if a handle is given, it will be aligned against it using the current match table if it is a collection element, or simple structural match if it is a descriptor. If the test is NIL or T, all candidates pass the test. The use of ME will be explained below.
When a count is given, it must evaluate to an integer (positive or negative), or the distinguished atoms ALL or COMPLETE. The integers are treated like those in the INTERLisp editor -- the nth element is taken from the list of candidates which pass the test. Positive integers count from the front of the list, negative from the end. ALL does the action for every element of the list. COMPLETE insists that it be known that the list is complete (e.g. that an enumeration on which it is based does not contain a ...) If no count is given, or it evaluates to NIL, it is equivalent to a count of 1 -- i.e. the first candidate passing the test is taken.
7.1.2 Bindings
These are used to bind variable names to objects encountered in the match, both for returning as values of the match, and for use in additions to structure done within a match/describe. If a the same variable name appears in multiple binding meta-descriptions, its value must be the same (EQ or EQHandle) for all for the match to succeed.
(Bind variableName type)
This can appear only in a meta-description of an anchor. The variable name is used in the bindings resulting from the match. The type must be one of:
Pointer: The effective description must include a Lisp pointer descriptor, and the variable is bound to its pointer
Primary: The effective description must have a primary anchor as its structural grounding or include a coreference descriptor to a primary anchor (note, not all labelled anchors are primary -- the meta-description NotPrimary() indicates what it says. The variable is bound to a handle to the grounding anchor or to the anchor pointed to by the coreference.
Hook: The effective description must contain a Handle descriptor or StructureNamed descriptor, and the variable is bound to the handle derived from it.
Post: This is the union of Pointer, Primary, and Hook. It binds a handle for a primary, a pointer for a pointer, and a Handle descriptor for a Hook. Note that this is different from the bare handle bound if Hook is used directly, so that it can be distinguished from a Primary.
Anchor: The effective description must have a structural grounding, and its handle is bound.
(Bind variableName Descriptor test count)
This can appear in a meta-description of an anchor or descriptor. If it appears on an anchor, the effective description aligned with that anchor is searched for descriptors which pass the test (as described above). If count is an integer, the nth such one is returned, while if it is ALL, a list of all the descriptors is returned. In this case, ME is not a legal test value. If a BindDescriptor action appears as the meta-description of a descriptor, then the only legal test is ME, and it means that the action is to be done to the descriptor which achieves the match. If the count is ALL, the action is done to all descriptors found in the effective description which match the pattern descriptor.
As mentioned above, a simple structural match is used in deciding whether a datum descriptor matches a pattern descriptor.
(BindElement variableName type test count)
This must appear in the meta-description of a pattern anchor which is matched against a datum anchor containing an enumeration of a collection. It is like BindDescriptor except that it operates on the elements of an enumeration instead of the descriptors in an anchor. Type is interpreted as with a simple Bind. ME is not a valid test. This can be used to get a list from an enumeration -- e.g. (BindElement x Post NIL ALL) returns a list of posts, one for each element in the enumeration in the datum anchor.
7.1.2 Semantic Changes to descriptions
(Describe newDesc)
This is used to meta-describe a pattern anchor. The corresponding anchor must appear structurally in the datum. newDesc must evaluate to a descriptor or anchor handle or lisp pointer, and changes corresponding to it are made to the anchor in the datum. The argument is evaluated, and the result treated as follows:
An anchor handle: the descriptors in the anchor are copied
A descriptor handle: the descriptor is copied
Any Lisp pointer: a Lisp descriptor is created this is not currently implemented
Note that if the argument is a nexus (entered as a form with \.../) it will evaluate to a handle. All of the ordinary surrogate forms (the bangs) are allowed in the nexus, and the Lisp form (ValueOf atom) evaluates to the bound value, where the atom is one of the variables in the bindings of the pattern.
A Describe causes folding and triggering all the way down -- it can be thought of as a series of actions in which the specified new description is added one level at a time starting at the top. If the piece being added would be redundant, it is not added. This is distinct from Substitute and AddDescriptor, which add their argument as a whole without dealing with its internal structure.
(OverWrite newDesc)
This is used to meta-describe a pattern anchor. The corresponding anchor must appear in the datum, and a set of descriptors corresponding to the new description is put into it. Those previous descriptors in that anchor which are in conflict with the new ones (as defined by the type of match) are removed. This can be used in conjunction with bindings, as in:
(Match foo \A Something with
currentCount = @Do(’(Bind x Pointer))
@Do(’(OverWrite (Add1 (ValueOf x))))/)
(MetaDescribe newDesc)
This is used to meta-describe a pattern anchor or descriptor. The corresponding anchor or descriptor must appear in the datum, and newDesc is added to its meta-description. This addition is done using the same folding mechanisms as for any Describe.
7.1.3 Structural Changes to Descriptions
These are used to change the structures found in the course of the match. After a match has succeeded completely (all bindings are satisfied), the set of changes is made, and can refer to the values bound. A substitution is specified much like a binding, in that it must find the object for which to substitute.
(Substitute newAnchor)
This must appear in the meta-description of a pattern anchor. newAnchor must evaluate to an anchor handle or NIL. The datum anchor against which it is matched has both its descriptors and meta-descriptors removed and replaced with newAnchor, or with null handles, if newAnchor evaluates to NIL. This is a structural replacement, not a semantic describe. No triggering happens within the contents of the new anchor -- only above it in the datum. A labelled anchor cannot be substituted for anything, nor an unlabelled one for a labelled one.
(SubstituteDescriptor newDescriptor test count)
This can appear in the meta-description of a pattern descriptor if the test is ME, or an anchor otherwise. It first acts like BindDescriptor, finding the specified descriptor (or descriptors). It then replaces it (each of them) with a copy of the value of newDescriptor. If the newDescriptor value is NIL, the descriptors are removed from their anchors.
(AddDescriptor newDescriptor)
This is used to meta-describe a pattern anchor. The corresponding effective description must be structurally grounded, and a copy of the newDescriptor is added to it without checking for redundancy or folding.
7.1.4 Changes to enumerations
(AddElement newAnchor)
This is used to meta-describe a pattern anchor. The corresponding effective description must be structurally grounded, and contain an explicit set or sequence enumeration descriptor. A copy of newAnchor is put into a new anchor, which is added to the enumeration. Triggering is done as with describe. If the enumeration is a sequence, the new element is added at the end. If the enumeration was marked as complete, a signal AddingToCompleteCollection is generated.
(AddBefore newAnchor test count)
This is used to meta-describe a pattern anchor. It first operates like BindElement, finding the element (or elements) passing the test and meeting the count. It then adds a new element to the enumeration immediately before the one specified, copying the newAnchor. Note that this can be used to add an element in a specific place. the Command (AddBefore x NIL 3), for example, inserts a new element in position 3, moving the rest down. If the test is ME, the anchor must be in an enumeration in a pattern, and the new elment is inserted before the element matched by the pattern element. In this case, the top-level AddBefore form cannot be used.
(AddAfter newAnchor test count)
This is like AddBefore, but puts the new elment after the one(s) found.
(SubstituteElement newAnchor test count)
This can appear in the meta-description of a pattern anchor, which must be an element of an enumeration if the test is ME. It first acts like BindElement, finding the specified element (or elements). It then replaces it (each of them) with a copy of the value of newAnchor. If the newAnchor value is NIL, the elements are removed from their enumerations.