<<

Session 25 Hardware and for

CLISP - Conversational LISP

Warren Teitelman Xerox Palo Alto Research center Palo Alto, California 94304

Abstract

CLISP is an attempt to make LISP programs The syntax for a conditional expression is easier to read and write by extending the correspondingly simple:* syntax of LISP to include infix operators, IF-THEN statements, FOR-DO-WHILE statements, Figure 2 and similar ALGOL-like constructs, without Syntax of a conditional Expression changing the structure or representation of the language. CLISP is implemented through ::x LISP's error handling machinery, rather than (COND ... ) by modifying the : when an :;= (

) expression is encountered whose evaluation causes an error, the expression is scanned Note that there are no IF's, THEN's, for possible CLISP constructs, which are BEGIN's, END'S, or semi-colons. LISP avoids then converted to the equivalent LISP the problem of parsing the conditional expressions. Thus, users can freely expression, i.e., delimiting the individual intermix LISP and CLISP without having to clauses, and delimiting the predicates and distinguish which is which. Emphasis in the consequents within the clauses, by requiring design and development of CLISP has been on that each clause be a separate element in the system aspects of such a facility, with the conditional expression, namely a the goal in mind of producing a useful tool, sublist, of which the predicate is always not just another language. To this end, the first element, and the consequent the CLISP includes interactive error correction second element- As an example, let us and many 'Do-what-I-Mean* features. consider the following conditional expression which embodies a recursive * * * definition for FACTORIALS** Figure 3 Recursive Definition of Factorial The syntax of the LISP»»»»» is very simple, in the sense that (COND it can be described concisely, but not in ( (EQ N 0) the sense that LISP programs are easy to read or write! This simplicity of syntax is ( (TIMES N (FACTORIAL (SOB1 N))))) achieved by, and at the expense of, extensive use of explicit structuring, namely grouping through parenthesesization. For the benefit of readers unfamiliar with LISP syntax, the basic element of LISP programs is called a fgr.m. A form is either * Actually, a clause can have more than (1) atomic, or (2) a list, the latter being two consequents, in which case each form denoted by enclosing the elements of the is evaluated and the value of the last list in matching parentheses. In the first form returned as the value of the case, the form is either a variable or a conditional. However, for the purposes constant, and its value is computed of this discussion, we can confine accordingly. In the second case, the first ourselves to the case where a clause has element of the list is the name of a only one consequent. function, and the remaining elements are again forms whose values will be the arguments to that function. In Backus ** The expression in Figure 3 is shown as notation: it would be printed by a special formatting program called PRETTYPRINT. PRETTYPRINT attempts to make the Figure 1 structure of LISP expressions more Syntax of a LISP Form manageable by judicious use of identation and breaking the output into ::« || separate lines. Its existence is a ( ... ) tacit acknowledgment of the fact that LISP programs require more information For example, assign x the value of the sum than that contained solely in the of A and the product of B and is written parenthesization in order to make them in LISP as (SETQ X (PLUS A (TIMES B C))) . easily readable by people.

686 The first clause in this conditional is the embedding, because embedded sentences are list of two elements ((EQ NO) 1), which more difficult to grasp and understand than says if (EQ N 0) is true, i.e., if N is equivalent non-embedded ones (even when the equal to 0, then return 1 as the value of latter sentences are somewhat longer). the conditional expression, otherwise go on Similarly, most high level programming to the second clause. The second clause is languages offer syntactic devices for (T (TIMES N (FACTORIAL (SUB1 N) ) ) ) , which reducing apparent depth and complexity of a says if T is true (a tautology-the ELSE of program: the reserved words and infix ALGOL conditionals), return the product of N operators used in ALGOL-like languages and (FACTORIAL (SUB1 N)). The latter is simultaneously delimit operands and evaluated by first evaluating (SUB1 N), and operations, and also convey meaning to the then calling FACTORIAL (recursively) on this programmer. They are far more intuitive value. than parentheses. In fact, since LISP uses parentheses (i.e., lists) for almost all As a result of the structuring of syntactic forms, there is very little conditional expressions, LISP does not have information contained in the parentheses for to search for words such as IF, THEN, ELSE, the person reading a LISP program, and so ELSEIF, etc., when interpreting or compiling the parentheses tend mostly to be ignored: conditional expressions in order to delimit the meaning of a particular LISP expression clauses and their constituents: this for people is found almost entirely in the grouping is specified by the parentheses, words, not in the structure. For example, and is performed at input time by the READ the expression in Figure 4 program which creates the list structure used to represent the expression. Figure 4 Similarly, LISP does not have to worry about careless Definition of Factorial how to parse expressions such as A+B+C, since (A+B)*C must be written unambiguously (COND (EQ N 0) 1) as (TIMES (PLUS A B) c), and A+(B*C) as (T TIMES N FACTORIAL ( (SUB1 N) ) ) (PLUS A (TIMES B C)). In fact, there are no reserved words in LISP such as IF, THEN, is recognizable as FACTORIAL even though AND, OR, FOR, DO, BEGIN, END, etc., nor there are five misplaced or missing reserved characters like + , -, *, /, =, «-, parentheses. Grouping words together in etc.* This eliminates entirely the need for parentheses is done more for LISP's benefit, parsers and precedence rules in the LISP than for the programmer's. interpreter and , and thereby makes program manipulation of LISP programs CLISP is designed to make LISP programs straightforward. In other words, a program easier to read and write by permitting the that "looks at" other LISP programs does not user to employ various infix operators, IF- need to incorporate a lot of syntactic THEN- ELSE statements, FOR-DO-WHILE-UNLESS- information. For example, a LISP FROM-TO-etc. expressions, which are interpreter can be written in one or two automatically converted to equivalent LISP pages of LISP code.' It is for this reason expressions when they are first interpreted. that LISP is by far the most suitable, and For example, FACTORIAL could be written in frequently used, programming language for CLISP as shown in Figure 5. writing programs that deal with other programs as data, e.g., programs that Figure 5 analyze, modify, or construct other CLISP Definition Of FACTORIAL programs. (IF N=0 THEN 1 ELSE N*(FACTORIAL N-1)) However, it is precisely this same simplicity of syntax that makes LISP Note that this expression would be programs difficult to read and write represented internally (after it had been (especially for beginners), 'pushing down' interpreted once) as shown in Figure 3, so is something programs do very well, and that programs that might have to analyse or people do poorly. As an example, consider otherwise process this expression could take the following two "equivalent" sentences: advantage of the simple syntax.

"The rat that the cat that the dog CLISP also contains facilities for making that I owned chased caught ate the sense out of expressions such as the cheese." careless conditional shown in Figure 4. Furthermore, CLISP will detect those cases versus which would not generate LISP errors, but are nevertheless obviously not what the "I own the dog that chased the cat programmer intended. For example, the that caught the rat that ate the expression (QUOTE ) will cheese." not cause a LISP error, but would never be seen by the interpreter. This is Natural language contains many linguistic clearly a parentheses error. CLISP uses devices Buch as that illustrated in the both local and global information to detect, second sentence above for minimizing and where possible, repair such errors. However, this paper will concentrate * except for parentheses (and period), primarily on the syntax extension aspects of which are used for indicating structure, CLISP, and leave a discussion of the and space and end-of-line, which are semantic issues for a later time. used for delimiting identifiers.

687 There have been similar efforts in other 1) (LIST X*FACT N), where FACT is the name LISP systems, most notably the MLISP of a variable, means (LIST (X*FACT) N). language at Stanford.* CLISP differs from these in that it does not attempt to replace 2) (LIST X*FACT N), where FACT is not the the LISP language so much as to augment it. name of a variable but instead is the In fact, one of the principal criteria in name of a function, means the design of CLISP was that users be able (LIST X*(FACT N)>, i.e., N is FACT'S to freely intermix LISP and CLISP without argument. having to identify which is which. Users can write programs, or type in expressions 3) (LIST X*FACT(N)), FACT the name of a for evaluation, in LISP, CLISP, or a mixture function (and not the name of a of both. In this way, users do not have to variable), means (LIST X* (FACT N)) . learn a whole new language and syntax in order to be able to use selected facilities 4) cases (1), (2) and (3) with FACT of CLISP when and where they find them misspelled! useful. The first expression is correct both from CLISP is implemented via the error the standpoint of CLISP syntax and semantics correction machinery in *. Thus, any and the change would be made without the expression that is well-formed from LISP'S user being notified. In the other cases, standpoint will never be seen by CLISP the user would be informed or consulted (e.g., if the user defined a function IF, he about what was taking place. For example, would effectively turn off that part of to take an extreme case, suppose the CLISP). This means that interpreted expression (LIST X*FCCT N) were encountered, programs that do not use CLISP constructs do where there was both a function named FACT not pay for its availability by slower and a variable named FCT. The user would execution time. In fact, the interpreter first be asked if FCCT were a misspelling of does not •know* about CLISP at all. It FCT. If he said YES, the expression would operates as before, and when an erroneous be interpreted as (LIST (X*FCT) N).* If he form is encountered, the interpreter calls said NO, the user would be asked if FCCT an error routine which in turn invokes the were a misspelling of FACT, i.e., if he Do-what-I-Mean (DWIM) analyzers'»■• which intended X*FCCT N to mean X*(FACT N). If he contains CLISP. If the expression in said YES to this question, the indicated question turns out to be a CLISP construct, transformation would be performed. If he the equivalent LISP form is returned to the said NO, the system would then ask if X*FCCT interpreter. In addition, the original CLISP was to be treated as CLISP, since FCCT is expression, is modified so that it becomes not the name of a (bound) variable.** If he the correctly translated LISP form. In this way, the analysis and translation are done only once. * Through this discussion, we speak of CLISP or DWIM asking the user. Actually, if the expression in question Integrating CLISP into the LISP system was typed in by the user for immediate (instead of, for example, implementing it as execution, the user is simply informed a separate preprocessor) makes possible Do- of the transformation, on the grounds What-I-Mean features for CLISP constructs as that the user would prefer an occasional well as for pure LISP expressions.* For misinterpretation rather than being example, if the user has defined a function continuously bothered, especially since named GET-PARENT, CLISP would know not to he can always retype what he intended if attempt to interpret the form (GET-PARENT) a mistake occurs, and ask the as an arithmetic infix operation. programmer's assistant to UNDO the (Actually, CLISP would never get to see this effects of the mistaken operations if form, since it does not contain any errors.) necessary.' For transformations on If the user mistakenly writes (GET-PRAENT), expressions in his programs, the user CLISP would know he meant (GET-PARENT), and can inform CLISP whether he wishes to not (DIFFERENCE GET PRAENT), by using the operate in CAUTIOUS or TRUSTING mode. information that PRAENT is not the name of a In the former case (most typical) the variable, and that GET-PARENT is the name of user will be asked to approve a user function whose spelling is "very transformations, in the latter, CLISP close" to that of GET-PRAENT. Similarly, by will operate as it does on type-in, using information about the program's i.e., perform the transformation after environment not readily available to a informing the user. preprocessor, CLISP can successfully resolve the following sorts of ambiguities: ** This question is important because many of our LISP users already have programs that employ variables whose names

6 contain CLISP operators. Thus, if CLISP * INTERLISP (formerly BBK-LISP ) is encounters the expression A/B in a implemented under the BBN TENEX 2 context where either A or B are not the timesharing system and is jointly names of variables, it will ask the user maintained and developed by Xerox Palo if A/B is intended to be CLISP, in case Alto Research Center and Bolt, Beranek, the user really does have a free and Newman, Inc., Cambridge, Mass. It variable named A/B, but has mistakenly is currently being used at various sites used A/B here in a context where it was on the ARPA Network, including PARC, not bound. BBN, ISI, SRI-AI, etc.

688 said YES, the expression would be to the form shown in Figure 3, while making transformed, if NO, it would be left alone, 5 spelling corrections and fixing the i.e., as (LIST X*FCCT N). Note that we have parenthesis error.* not even considered the case where X*FCCT is itself a misspelling of a variable name, as This sort of robustness prevails throughout with GET-PRAENT. This sort of CLISP. For example, the iterative statement transformation would be considered after the permits the user to say things like: user said NO to x*FCCT N -> X*(FACT W). The complete graph of the possible (FOR OLD X-M TO N interpretations for (LIST X*FCCT N) where DO (PRINT X) WHILE (PRIMEP X))** FCT and XFCT are the names of variables, and FACT is the name of a function, is shown in However, the user can also write OLD (X--M) , Figure 6. (OLD X-M), (OLD (X-M>) , permute the order of the operators, e.g., DO (PRINT X) TO N FOR OLD X+M WHILE (PRIMEP X) , omit either or both sets of parentheses, misspell any or all of the operators FOR, OLD, TO, DO, or WHILE, or leave out the word DO entirelyl And, of course, he can also misspell PRINT, PRIMEP, M, or N!*** CLISP is well integrated into the INTERLISP system. For example, the above iterative statement translates into an equivalent LISP form using PROG, COND, GO, etc.**** When the interpreter subsequently encounters this CLISP expression, it automatically obtains and evaluates the translation. Similarly, the compiler "knows" to compile the translated form. However, if the user PRETTYPRINTS his program, at the corresponding point in hie function, PRETTYPRINT "knows" to print the original CLISP. Similarly, when the user edits his program, the editor makes the translation invisible to the user. If the user modifies the CLISP, the translation is automatically discarded and recomputed the next time the expression is evaluated. The final states for the various terminal nodes shown in Figure 6 are:

* CLISP also contains a facility for converting from LISP hack to CLISP, so that after running the above definition of FACTORIAL, the user could ,CLISPIFY» CLISP can also handle parentheses errors to obtain: caused by typing 8 or 9 for ' (• or ')'- (On (IF N=0 THEN 1 ELSE N*(FACTORIAL N-1))- most terminals, 8 and 9 are the lower case characters for '(• and «)', i.e., •(< and ** This expression should be self '8' appear on the same key, as do •)' and explanatory, except possibly for the • 9•.) For example, if the user writes operator OLD, which says X is to be the N*8FACTORIAL N-1, the parentheses error can variable of iteration, i.e., the one to be detected and fixed before the infix be stepped from M to N, but X is not to operator * is converted to the LISP function be rebound. Thus when this loop TIMES. CLISP is able to distinguish this finishes execution, X will be equal to situation from cases like N*8*X meaning (TIMES N 8 X), or N*8X, where 8X is the name N. of a variable, again by using information about the programming environment. In fact, by integrating CLISP with DWIM, CLISP has been made sufficiently tolerant of errors that almost everything can be misspelled!* For example, CLISP can successfully translate the definition of FACTORIAL:

(IFFN*0 THENN 1 ESLE N*8FACTTORIALNN-1)

* Where misspelling includes running adjacent words together, as shown in example.

689 In short, CLISP is not a language at all, References but rather a system. It plays a role analagous to that of the programmer's 1. Berkeley, E.C. "LISP, A Simple assistant.* Whereas the programmer's Introduction," in The Programming assistant is an invisible intermediary agent Language LISP, its Operation and between the user's console requests and the Applications. Berkeley, E.C. and LISP executive, CLISP sits between the Bobrow, D.G. (editors), MIT Press, user's programs and the LISP interpreter. 1966.

Only a small effort has been devoted to * Bobrow, O.G., Burchfiel, J.D., Murphy, defining a core syntax for CLISP. Instead, D.L. and Tomlinson, .S. "TENEX, a most of the effort has been concentrated on Paged Time Sharing System for the providing a facility which' 'makes sense' out PDP-10." communications of the. ACM, of the input expressions using context March 1972, vol. 15, Ho. 3. information as well as built-in and acquired information about user and system programs. ' McCarthy, J. et al. LISP 1.5 Just as communication is based on the Programmer's Manual. MIT Press, intention of the speaker to produce an 1966. effect in the recipient, CLISP operates under the assumption that what the user said * Smith, D.c MLISP User's Manual. was intended to represent a meaningful Stanford Artificial Intelligence operation, and therefore tries very hard to Project Memo AI-84, January 1969. make sense out of it. The motivation behind CLISP is not to provide the user with many 5 Teitelman, w. "Automated Programming - different ways of saying the same thing, but The Programmer's Assistant." to enable him to worry less about the Proceedings of Fall Joint Computer syntactic aspects of his communication with Conference. December 1972. the system. In other words, it gives the user a new degree of freedom by permitting * Teitelman, W., Bobrow, D.G., Hartley, him to concentrate more on the problem at A.K., Murphy, D.L. BBN-LISP Tenex hand, rather than on translation into a Reference Manual, Bolt, Beranek, formal and unambiguous language. and Newman, Inc., August 1972.

CLISP has just become operational and the 7. Teitelman, W. "Do What I Mean," expected reactions and suggestions from Computers and Automation. April users will do much towards polishing and 1972. refining it. However, the following anecdote suggests a favorable prognosis: * Teitelman, W. "Toward a Programming after being cursorily introduced to some of Laboratory," Proceedings of First the features of CLISP, two users wanted to International Joint Conference on try out the iterative statement facility, Artificial Intelligence. Walker, D. but neither of them were sure of the exact (editor), May 1969. syntax. The first user thought that if they just typed in something "reasonable", the * weissman, C. LlSP 1.5 Primer. Dickenson system would figure out what they meant. Press, 1967. And it did!

690 Session 25 Hardware and Software for Artificial Intelligence 2.PAK: A SNOBOL-BASED PROGRAMMING LANGUAGE FOR ARTIFICIAL INTELLIGENCE APPLICATIONS JOHN MYLOPOULOS, NORMAN BADLER, LUCIO MELLI AND NICHOLAS ROUSSOPOULOS DEPARTMENT OF COMPUTER SCIENCE, UNIVERSITY OF TORONTO

Descriptive Terms: Programming language, Edge labels (properties) consist of one SNOBOL, backtracking, relational data base, or more atoms separated by underscores. The artificial intelligence. first atom is the attribute of the property, while subsequent atoms are its modi fiers. Abstract Information can be retrieved from the This paper describes a programming langu­ data base by matching (graph) patterns age for Artificial Intelligence applications against i t. which offers (a) a data base, in the form of a collection Patterns arc specified in terms of se­ of labeled directed graphs where knowledge can quences of path descriptions. For example, be stored the pattern (b) pattern directed information retrieval <$X,(LEFT_AARB?YJ, (FAR).SW- and pattern invoked function calls contains one path description which will (c) primitive statements which enable the match paths that user to construct flexible searching algor- (a) Begin at the node which is the value of ithms. atom X , (b) Move along an edge whose label has LEFT The language is an extension of SNOBOL in as attribute and is followed by at least one its design and implementation and uses modifier, SNOBOL's string pattern matching facilities (c) Move along an edge whose label has FAR for its own (graph) pattern matching. as attribute, (d) End at node $W. 1. Introduction If such a path connects nodes $X and l.pak was designed and implemented in $W for a particular data base, the pattern order to facilitate AI research at the Uni- match succeeds and the modifier of LEFT is versity of Toronto. It s design was influenced assigned to atom Y , while the graph pattern by other languages desi gned for similar reasons match returns $W , the last node vi?ited such as C0NNIVF.R[1,2] , PLANNFR[3], QA4[4], during the match. Patterns are evaluated by SAIL[5,6], and our deci si on to implement it as the function SEARCH. an extension of SNOBOL and keep it relatively AARB is a special property pattern which inexpensive (in terms o f the time and space will match any atom. l.pak offers several required for the execut ion of programs). other buiIt-in property patterns and operators This paper only di scusses the main fea- similar to tho se offered by SNOBOL to help the tures of l.pak, how the y can be used, their user speci fy c lasses of edge labels in his relation to features of fered by other languages graph patterns Thus (graph) pattern matching for AI , and the success of the current implc- is essentially driven by property pattern mentation. More detail s on the language are matchi ng and c an be easily implemented using available elsewhere [7] It is assumed that the string pat tern matching facilities in the reader is familiar with the basic features SNOBOL. of SNOBOL [8]. Note that there may be several paths which will mat ch the same pattern. For 2. The Data Base example, the p attern match SEARCH( <$X,(LEFT),(ABOVE^FAR)>) The data base for each l.pak program con- could return n ode n1 or nZ In FIG. 2. sists of a collecti on of directed, labeled The pattern ma tch however will return just one graphs (hereafter g raphs) such as that shown of the two nod es . in FIG. 1. A list of transitive and/or intransitive edges is associated with each node, which define either properties of (the object represented by) the node or relations which hold between the node and other elements of the same graph. A linear order exists for the nodes of each graph defined by special edges labeled NEXT. TYPE SUN

FIG. 2.

ABOVE ABOVE We will show later how to generate all the matching alternatives.

TYPE HOUSE TYPE TREE Information can be added to or deleted from the data base through the special functions ADD and DEL. ADD's main function is to create new in­ formation with a graph as context. For example, the function call

691 ADD(<$X,(LEFT),(FAR),?W>) type of function arguments is fixed inside a will create enough new edges and nodes to make function call; it only helps to check whether the pattern match of its argument against the the function request makes sense. data base successful. In the process, a (node) value will be assigned to W . ADD will also The same function name may be used inside perforin a simple consistency - redundancy test several PDEFINE calls, thus giving the same for each new edge attached to a node, with name to several different functions. This respect to the edge list of that node. Thus means that a statement such as an intransitive edge labeled TYPE HOUSE will NEW($X1,$Y1,?Z) not be added to the edge list of a node which may cause several function calls unti] one is already contains an edge labeled TYPE_H0USE found that succeeds. In fact , the function TALL because it is redundant. name specified by a function request in l.pak can be a string pattern, as in An example of a DEL function call is (T1I|AX) ($X,$Y,?Z) DEL() which will cause the call of any function where the special operator '-' specifies whose name matches the string pattern (THJAX) that the node or edge it operates on must be (i.e., begins with TH or AX) and whose deleted. For this function call, a pattern parameter description is matched by the argu­ match takes place first, and if unsuccessful ments of the function request. the call fails; otherwise the node $Y is deleted along with all the edges that point, to This feature offers the user flexibility or away from it. in specifying a function request similar to that offered by theorem provers where each l.pak also offers SNOBOL tables and axiom can be considered as a function without arrays as means for representing in formation. a name to be called whenever there is a sus­ Moreover, as in SNOBOL, the user can define picion that it may be of use. his own data types. Explicit list facilities Unlike SNOBOL, l.pak treats field desig­ using CONS, CAR and CDR and list notation are nators of programmer-defined data types, array provi ded. Express ions such as references and table lookups as special cases $L = ($A, $B, $C, $D) of a function request. Thus, if the user may be used to construct lists; here the value writes of L is a four element list. CAR($X) 1.pak will try to treat this as a field desig- 3- Program Structure and Control nator, then as an array reference, then as a table lookup, and if all these attempts fail, l.pak statements are similar to their it will start calling functions named CAR SNOBOL cousins. For example, the statement until one of them succeeds. A: DEL(<$X, (LEFT) , - (R1GIITJVB0YE) >) :S(A)F(B) is labeled A , and will attempt to delete the 4.2 Implicit function requests edge whose label matched R1GHT_AB0VE, if the pattern match of <$X,(LEFT),(R]CHT_ABOVE)> It is often the case that information not against the data base succeeds. If the DEL stored in the data base is actually true in funct ion call succeeds, control is passed back the universe of discourse. For example, a to A , otherwise control is passed to the node may represent a house which has been statement labeled B . recognized as one of the objects represented in a line drawing, and the question "Does Each l.pak statement will succeed or fail there exist an object to the left of the and this can be used for program control. Un- house?" may be asked. The user may attempt to less otherwise specified, control will pass to answer it by writing the next statement of a l.pak program. Thus backtracking as encountered in PLANNER and QA4 SEARCH (<-$X, (LEFT_* FCN) ,?Y> ) is only offered during graph pattern matching where X points to the node representing the in l.pak. A different kind of backtracking house, and *,FCN arc special modifiers to be will be discussed later. discussed later. If the pattern match fails, either there is no such object, or it exists but it is not represented by a node in the 4 . Function Requesjts_ graph where $X is imbedded. We would like to keep the value of the pattern match inde­ 4.1. Explicit function requests pendent of these two possibilities and have l.pak functions can be defined through therefore introduced the notion of imp!icit PDEFINE. For example, the statement funct ion requests ■ Informally, such function PDEFINE(NEW(X:NODE]NULL,Y:PROPERTY|PATTERN,? Z) requests will be invoked by the system in an W_W1,NEW) attempt to construct information needed for defines a function named NEW with three formal the successful evaluation of a pattern match parameters; the first must be of type NODE or whenever the special modifier FCN appears at have as value the null string, the second of the end of a property pattern. * is also a type PROPERTY or PATTERN, while the third is special modifier which specifies that modifiers called by result. Thus the statement that follow it should be treated differently NEW($X1,$Y1,$Z1) by l.pak than atoms that precede it. In the will fail even before NEW is called because previous example, if the system has found no the third argument is not called by result, edges which leave $X and match LEFT (not while LEFT *FCN), it will therefore call functions NEW($X1,$Y1,?Z1) named" LEFT with implicit argument $X , looking will proceed with the execution of the function for one that succeeds. call if $X1 is a node or the null string, and $Y1 is a property or a (graph) pattern. Thus the pattern match SEARCH(<$X,(DIMENSIONS AARB?Y AARB?Z AARB?W The specification of allowable types for * FCN)>) each formal parameter does not mean that the will either match an edge label to the pro­ argument to be used for that particular perty pattern generator call. DJMENS10NS_AARB?Y AARB?Z AARB?W and will return its modifiers through Y, 2 There are several built-in generators. and W , or it will call a function named For example, NODES will generate all the nodes DIMENSIONS which has three formal parameters, that lie at the end of a path which matches a all called by result, which will attempt to given graph pattern. Thus if we write find the dimensions of $X . In this case the $Z <= NODES(<$X,(LEFT),(ABOVE_FAR)>) modifiers of the property for which we are the first time Z< > is encountered with trying to establish an edge were used as argu­ background the graph shown in FIG. 2, it will ments of the implicit function call, while the return, say, node n] , the second time node attribute was used as a function name. In the n2 , and if it is called again it will fail. example SEARCH(<$X, (TYPE_HOUSE_TALL_VKRY_*__FCN)>) 6. More on Backtracking on the other hand, we may want to establish the existence of an (intransitive) edge In some cases backtracking (i.e., reset labeled TYPEJIOUSE_TALL_VERY by first calling of the program state in case of failure) will the function TYPE with only argument the node not be necessary, but in others it will save $X , then the function HOUSE with arguments the programmer considerable effort. 1.pak $X and the output of TYPE, then TALL and allows a form of backtracking by extending the finally VERY. In other words, an attempt to feature of declaring variables local to a establish an edge in the data base may cause function or a generator in several directions: several function calls. (a) All variables which appear in a function or generator body can be declared local for a particular function or generator call by using 5. Generator Calls the keyword VLOCAL during the function defin­ ition or generator definition or binding. Generators were introduced by PLANNER LOCALness may be specified as dependent on the and used extensively by CONNIVER where they success of failure of a function or generator provide one of the most important language call by using SVLOCAL or FVLOCAE instead of constructs. l.pak offers them too, as a method VLOCAL. Thus FVLOCAL defines a backtracking of generating alternatives. situation (i.e., reset in case of failure) for A generator is defined by a piece of code program variables only for "the function or and is assigned a name. For example, generator it is associated with. GEN.INT, INTEGER; (b) Changes made to the data base can also $INT = $INT+1; be declared local by using SDLOCAL, FDLOCAL or $DOMAIN = C0NS($]NT,$D0MA1N) : (EXIT); DLOCAL. END.INT; If the user wants a reset of variables defines an integer generator named INT. This and the data base state, he can use SLOCAL, generator simply considers the first element FLOCAL or LOCAL. This way he has some flexi­ stored in its DOMAIN list (which is similar to bility in specifying exactly which changes in CONNTVER's possibilities list), increments it his program he considers reversible and under by 1, stores the result in DOMAIN, and returns what, conditions . it as value. EXIT specifies that execution of this generator call is complete and that its DOMAIN list should be kept active for future 7. Examples calls. This section describe? three simple l.pak A generator can be used once it has been programs which demonstrate the features al­ bound to an atom. Thus ready discussed and point out a few others $X <= INT(5) that arc not as important. assigns the generator INT to X and initial­ Suppose that we want to define a collec­ izes its DOMAIN list to (5). Now whenever we tion of functions named LEFT which somehow write X< > , the INT generator will be evalu­ express adequately our own notion of what LEFT ated returning another integer. Note that means (geometrically). These functions will there can be several active copies of the same be defined with respect to a list, $LIST, of generator, each bound to a different atom. objects and it will be assumed that there For example, exists a function REL.LEFT which succeeds or $X <- INT(51; fails depending on whether the object repre­ $Y <« INT(7); sented by its first argument is to the left of A: $OUTPUT = X< > + Y< >; the object represented by its second argument. LT($OUTPUT,100) :S(A); First we give a definition of LEFT which will assign to X the generator INT with its postulates its transitivity DOMAIN list initialized to (5). It will also PDEFINE(LEFT(TA1L:NODE,HEAD:NODE)Z_AUX, assign to Y the generator INT with its LEFT,DLOCAL); DOMAIN list initialized to (7). 5+7 will BEGIN.LEFT; then be evaluated and assigned to OUTPUT. As $Z <- NODES(<$TAIL,(LEFT)>); in SNOBOL, any string assigned to OUTPUT is $AUX = Z< > :F(FRETURN); automatically printed. It is then checked A: ADIH<$AUX,(TRIED)>) :F(B); whether the value of OUTPUT is less than 100 I DENT($AUX,$HEAD) :S(RETURN); and if so 6+8 is added and printed, then B; $AUX - Z<(<$AUX,(LEFT)>)> :S(A)F(FRETURN); 7+9, 8+10 etc. END.LEFT; In general, the user can pass within the This function will be evaluated as follows angle brackets a list of expressions to be for given $TAIL and $HEAD: appended to the DOMAIN list of a generator (a) Z is bound to the NODES generator des­ each time he calls it. He can also pass an cribed in section S with its DOMAIN list initialized to the pattern <$TAIL, (LF.FT)> . values of the two atoms assigned to A and B Thus the first call of Z will return a node are the elements of $L1ST represented by $TAIL to the LEFT of $TA1L which is assigned to AUX. and $HEAD (FIG. 3). Once these atoms are (b) Each node assigned to AUX is labeled found, REL.LEFT can be TRIED by ADD. If $AUX already has an intrans- itive edge labeled TRIED, ADD fails (because it cannot change the data base) and another node to the LEFT of $TAIL is assigned to AUX. (c) It is checked whether $AUX is IDENTical to $HEAD, and if so the function call RETURNS; (d) Otherwise, another node to the LEFT of $TAIL is assigned to AUX and the new graph pattern <$AUX, (LF.FT)> is appended to the DOMAIN list of Z . When all the nodes to the LEFT of $TAIL have been considered, Z will Start gener• ating nodes to the LEFT of nodes to the LEFT of $TAIL, and this will be repeated until all the nodes to the LEFT of nodes... to the LEFT of $TAIL have been tried. Because of the third argument of PDEFlNE, all changes made to the data base will be erased when the call to LEFT is complete, also AUX, Z will be reset to the values they had before the function call. called with arguments the objects object.i, Thus this definition of LEFT defines a object, j, represented in some way. breadth-first search of the graph where $TAIL A third possible definition of LEFT as a is imbedded in an attempt to find $HEAD, and generator returns nodes representing objects it has been formulated by using the generator to the LEFT of a given node $TAIL which is feature. it is interesting to compare it with passed as message to the generator, and is the following l.pak function which also postu• also a global variable: lates the transitivity properly of LEFT, by $Lt-ir <= LliFTDEF(#$rAILj relying on graph pattern matching and implicit This statement assigns to LEFT the generator function requests: LEFTDEF with its DOMAIN list initialized to PDEFlNE (LEFT (TAIL: NODE ,1IEAI): NODE), the unevaluated expression $TAI1. ('W' keeps its operand unevaluated until it is encount- ered at execution time, and is therefore similar to the SNOB0L, unary operator ' * ' ) - Below we define LEFTDEF. GEN.LEFTDEF, NODE; GA: SLEFTDEF = SEARCH (-- $LEFTDEF , (NEXT)> ) ; Here it is first checked whether there is I DENTf$LEFTDEF,$TAIL) :S(FRETURN) ; an edge with attribute LEFT connecting $TAIL SEARL'H(<$TAIL, (LEFT_*_FCN) ,$LEFTDEF>) to $HEAD, and if this is not the case, it is :F(GA>; checked whether there is a node, say nl , such $D0MA1N = ($LEFTDEF) : (EXl'I'") ; that there is an edge with attribute LEFT con• END.LEFTDEF; necting $TA1L to nl , and nl and $HEAD can Whenever this generator is executed, be connected with an edge labeled LEFT. In LEFTDEF is first assigned the value of TAIL checking for the latter condition, the user (this is done automatically by the system). has specified that implicit function requests Then the NEXT node is found and assigned to involving LEFT-named functions are allowed. LEFTDEF; NEXT defines a circular order on the This is a recursive definition of transitivity nodes of the graph where STAIL is imbedded, for LEFT in other words. The searching algor- and we are using it here in order to traverse ithm it defines is depth-first and may enter the graph. It is checked whether SLEFTDEF is an infinite loop for graphs representing geo• IDENTical to $TAIL, which would mean that we metrically strange worlds. are back at the starting node and there are no The second definition of LEFT accepts two more nodes to the LEFT of $TAIL; if not, it is nodes as arguments and succeeds or fails de• checked whether the current value of LEFTDEF pending on whether the object represented by is to the LEFT of $TA1L. Implicit function the first node is to the LEFT of the object requests are allowed for this check. If the represented by the second answer is negative, control returns to the PDEFlNE[LEFT(TAIL:NODE,HEAD:NODE)A B, statement labeled GA and another node is assigned to LEFTDEF', otherwise the DOMAIN list T LEFT)7 of LEFTDEF is set to ($LEFTDEE), a one-element list, and we EXIT. Next time this copy of LEFTDEF is called, search will resume with the NEXT node in the graph where $TAIL is imbedded until they have all been considered.

The user can now write The graph pattern match executed by SEARCH(<$X,(LEFT * FCN),$Y>) SEARCH finds the atoms which modify REPR on or SEARCH(<$X,(LEFT~*_GEN),?Y>) intransitive edges associated with $TAJL and and expect the system to either find the $HEAD and assigns them to A and B respec• necessary information in the data base or to tively. ':' specifies the end of one path call the appropriate functions or generators description and the beginning of another. The (depending on whether the special modifier is

694

10. Palme, J. Making computers understand natural language. In Artificial Intelligence and Heuristic Programming, Findler N." and Meltzer, B. (Eds . ). Edinburgh University Press, 1971. 11. Rumelhart, D,, Lindsay, P.H., Norman, D.A. A process model for long-term memory. In Organization of Memory, Tulving, E. and 'Donaldson, W. (Eds .), Academic Press, 1972.

696