4 HB88 WSSSim Hi USB fflm SB H89HB Hnl(119lffillSSwR! ■MMnniir HMffl roH Boom Hois H Bun rail H H ■ ■ ffifitnUK — ins& in BflHfi dO 151$ Km IH BIS ■ Hmsilra mm mm Blum B8S8S8U KuoBeaG hu88i8! ^BBSDHflKWIHWIBi alltff 4tMKoH 95 ■ KfflMMW ilB lfl flftg ngflffl rafU InffiHllftni outX BlIWIBnnTMlWlTTOW HHHl 8S»EiUU9Sa8i LIBRARY OF THE UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAIGN 510.84 IAGi- ho. 511-51 6 cop-2 ?2 June 1972 ARRAY PATTERN MATCHING by Lynne Schaber Sanford LIBRARY OE IKE NOV 9 1972 ty or MA-CHAMPAIGN DEPARTMENT OF COMPUTER SCIENCE UNIVERSITY OF ILLINOIS AT URBANA-CHAMPAIGN URBANA, ILLINOIS Report No. UIUCDCS-R-72-513 ARRAY PATTERN MATCHING by Lynne Schaber Sanford Department of Computer Science University of Illinois at Urbana-Champaign Urbana, Illinois 61801 June 1972 Ill TABLE OF CONTENTS Page 1. INTRODUCTION 1 2. ARRAY PATTERN MATCHING 5 2.1 Pattern Matching Function 5 2.2 Array Patterns 6 2.3 Scanning Direction 10 2.4 Modes of Scanning 13 2.5 Needle Position 13 2.6 Patterns and Primitive Functions 18 3- IMPLEMENTATION 22 3.1 Pattern Matching 22 3-2 Subject Evaluation 25 3.3 Pattern Evaluation 28 3.4 New Alternative 28 3.5 Position in Pattern 29 3-6 Subject Position 31 3-7 Scanning Directions 31 3-8 Expressions with Parentheses 34 3-9 Additional Functions 35 4. PREDICATES AND PRIMITIVE FUNCTIONS 36 4.1 ATAB(X,Y) 36 4.2 AP0S(I,J) 37 4.3 CURS(.X,.Y) 37 4.4 SIM(A,B) 38. 4.5 ABREAK(X) and \SPAN(X) 38 4.6 EQUIV(A,B) 39 4.7 ALOOP(ARG) 40 5- CONCLUSION 43 BIBLIOGRAPHY 4 4 APPENDIX A 45 APPENDIX B 57 Digitized by the Internet Archive in 2013 http://archive.org/details/arraypatternmatc513sanf 1. INTRODUCTION In SNOBOL the pattern matching statement is very useful for the manipulation of strings. This thesis is an attempt to extend this usefulness to another data structure, the two di- mensional array. Since an array is a collection of elements, a string pattern match can be performed on each element, pro- vided that the element is acceptable as a subject of a string pattern match. The array pattern then should provide the pattern against which the subject is to be matched. A string pattern match is then performed. If the match succeeds, a new subject element and a new pattern structure are obtained by following a certain set of rules for scanning the array; this process con- tinues until the entire array pattern has been matched. If at any time the string pattern match fails, a new alternative is selected according to the rules that will be explained later. If no more alternatives exist, the array pattern match is attemp- ted at a new position in the subject. These steps are all sim- ilar to the steps taken in a string pattern match. In the following discussion a knowledge of SNOBOL is assumed. Since this thesis is an attempt to extend SNOBOL, every effort has been made to retain all existing features of SNOBOL pattern matching. These existing features can only be applied, however, to a single element of an array. It is obvious that new structures must be added to the existing ones so that array I 2 patterns can be written as easily as regular SNOBOL string pat- terns. These new features of the language should be as similar Lble to their counterparts in string pattern matchir where no counterparts exist, the new structures should be com- patible with the other structures of array pattern matching. In SNOBOL arrays can be of any dimension; however, this thesis considers only two dimensional arrays. For the purposes of this project a string, integer, or real was considered to be a one by one array. Any array element can have the null string as its value, but there was no attempt to define or use a null or zero by zero array. The null array should be distinguished from an N by M array whose elements are all the null string; this array has a size of N by M, not zero by zero. Arrays whose elements point to other arrays are not con- sidered to be two dimensional. They should be avoided in using any of the programs described in this thesis. Since patterns can not be used as the subject of string pattern matches, arrays whose elements are pattern structures can not be used as the subject of an array pattern match. However, such arrays may be used as the pattern of an array pattern match. Other datatypes used as the elements of the subject array will cause unpredict- able results. An attempt was made to define primitive functions and predicates to be used in array patterns. These patterns are as general as possible so that they can be used in many circumstance These patterns are similar to programmer defined functions, and 3 the main program views all array patterns as such. These func- tions can be used with any scanning direction. If a user has a specific goal in mind he can construct his own predicates and primitive functions which are suited to that goal. However, these new functions are expected to take charge of the pattern match, and little help is to be expected from the main program. Finally no attempt was made to introduce error messages in the program. The program assumes that the user is always correct and it attempts all interpretable matches. Overview of the Thesis The next chapter is an introduction to array pattern matching. It defines this type of matching, and discusses the assumptions made in the implementation. A general idea of what happens in array pattern matching is presented. Chapter 3 discusses the actual implementation of the ideas given in Chapter 2; this implementation shows the feasi- bility of those ideas, it is by no means the only approach to the problem, or even the best approach in every instance. Users are encouraged to develop their own routines that are adapted to their specific goals. However, the implementation discussed in Chapter 3 does indeed express all the general ideas from the previous chapter . Chapter 4 briefly discusses the patterns and primitive functions which have been implemented. These functions are intended to help the user write his own array patterns. The appendices give the listing of the actual programs and provide examples of the programs in action. These examples are intended as a guide for the use of the programs. 2. ARRAY PATTERN MATCHING This chapter is an overview of array pattern matching. It is intended to provide a general understanding of the con- cepts of array pattern matching. These concepts have been imple- mented and that implementation will be discussed specifically in Chapter 3 • 2.1 Pattern Matching Function Array pattern matching can take place in any kind of statement that allows a function call to be made, because the array pattern matching statement is really a function. This function can occur as a statement by itself or as part of another statement. For example, the array pattern match could be performed in a string pattern matching statement. The pat- tern matching function has the form SUBJECT & 'PATTERN' where SUBJECT is an array, PATTERN is an array pattern (in quotes), and & is the binary array pattern matching operator (defined by OPSYN) . The pattern may be an array, a string, a variable, or an array predicate of primitive function. PATTERN may also contain any of these used with array concatenation and/or alternation. The pattern may be thought of as specifying a set of arrays. Notice that PATTERN is passed to the function as a string . During the pattern matching function the subject is scanned for an 6 occurrence of an array from the set given by the pattern. If an occurrence is found the function succeeds; if not the func- tion fails. The array pattern matching operator, & , has precedence of 1 as given in the SNOBOL manual. If this operator is used in an expression, the array pattern match will be the last opera- tion performed in the expression, because & has the lowest pre- cedence of all the binary operators. Parentheses can be used in expressions to force evaluation in a given order. 2.2 Array Patterns Array patterns are formed by the operations of array alternation and concatenation. Alternation is indicated by ' A| '. This was done so that alternation could be recognized by nearly the same symbol as in string alternation, but array alternation would be easily distinguished from string alternatior. For example the statement P = 'PI A| P2' assigns to P a string which is an array pattern structure that matches PI or P2. Concatenation with arrays is not analogous to concantena- tion with strings. For arrays, the problem is really where do we attach the second array to the first? Since arrays are two dimensional, there are two possible ways of concatenating arrays. For example if A and B are two by two and three by four arrays respectively, then B concatenated to A can look like either part a or b of Figure 1. After using the first operand the cursor a) @1 b) A X B Figure 1. Two Types of Concatenation 8 positioned at the spot marked by an X so that the concatenation is done properly. There are really two concatenation operations, gl as in Figure la, and @2 as in Figure lb. These opera- tors were chosen because they are convenient for scanning the pattern string. Regular binary operators were not used because there are not enough undefined operators provided in SNOBOL which have the proper precedence. Note also that when two arrays are concatenated the re- sult is not always another rectangular array. This can sometimes cause certain parts of the subject array to be skipped entirely during array pattern matching. The precedence of alternation and concatenation is the same for patterns as for strings. (21 and @2 have equal pre- cedence. If the pattern contains two or more instances of either type of concatenation, the concatenation is done from left to right . For example P = *A @1 B @2 C is the same as P = ' (A @1 B) @2 C After each concatenation the cursor is moved so that the next concatenation is done properly. An example of this is given in Figure 2. Given the arrays A, B, C, were A is a two by two, Bi a three by four, and C is a five by two, the pattern given by P above gives the indicated result. The precedence of these operators may be changed by using parentheses. Anything that is enclosed in parentheses is A = 2 x 2 B = 3 x H C = 5 x 2 P = A @1 B @2 C becomes A 4 B 2 i 5 n ^ Figure 2. Example of Concatenation 10 associated together and the entire expression is considered to be one operand. Expressions may have as many levels of paren- theses as desired. However, the parentheses must be matched. An expression containing an unmatched parenthesis will cause the whole array pattern match to fail. When using array patterns in array pattern matching, they should be stated explicitly. They cannot be assigned to variables first. If such variables are used in array pattern matching, they will not be evaluated properly, because the array alternation and array concatenation operators are not binary operators as defined by SNO.BOL. During pattern matching, no new arrays are created as a result of concatenation. For example execution of the pattern string 'A @1 B' causes the scanner to look for an occurrence of A followed by an occurrence of B. However, no array is actually created with the shape of A @1 B. 2.3 Scanning Direction For pattern matching to proceed, the scanner must know where to begin the search and how to move about in the subject array. Since there are many possible ways to scan an array, it is best to let the user decide which one is best in each instanc Specifying a scanning direction is done by calling a function SCAN from the array pattern. One of the arguments of SCAN is a number which points to a block of code that gives the desired direction. SCAN is a function that always succeeds. It does not change the position of the cursor when it is encountered 11 during pattern matching; it only indicates the direction of the cursor for the remainder of the pattern match. The scanning direction may be changed after pattern matching has begun by calling SCAN with a new number to Indi- cate the new scanning direction. If no scanning direction is specified, a default direction, illustrated in Figure 3 5 is assumed. A call to SCAN must also indicate the origin of the array. This Information is passed as arguments to SCAN. This origin tells the scanner where to begin in the subject array and in any pattern arrays. If the user wishes to define a new scanning direction he must supply a block of code labelled NEXN. Here N is the number that was used in the call to SCAN. It points to that block of code that actually moves the cursor position. N must not be equal to one. (NEX1 is the default scanning direction.) Within this new block of code the cursor can be moved in any way desired. Movement of the cursor is done by changing two indices, CURI and CURJ . These are the indices used to access the subject array. This new block of code must determine if the new position is really in the subject array. If not, the block of code should contain an FRETURN. The block of code should also contain a RETURN. The process of defining a scan- ning direction is duscussed in detail in Chapter 3- 12 NEX1 .Origin Figure 3. Default Scanning Direction 13 2.H Modes of Scanning In string pattern matching, the programmer can control the scanner by use of the keyword &ANCHOR. Two dimensional pat- tern matching uses this same keyword with approximately the same meaning. When &ANCHOR has the value zero, the scanner is in the unanchored mode. This means that the scanner is free to search the entire subject array to find an occurrence of the pattern. The subject array is scanned according to the scanning direction that has been indicated. The unanchored mode is the default mode . If &ANCHOR has a nonzero value the pattern must match the subject array at its origin. The origin of the subject array is defined by the current scanning direction. In the de- fault scanning direction, the origin of the subject array is as indicated in Figure 3« In programmer defined scanning directions, the programmer must define the origin of the subject array. If the array pattern match fails at the origin, the cursor is not advanced, and the entire pattern match fails. As with string pattern matching, the value of &ANCHOR can be changed during the program, thus changing the scanning mode. 2.5 Needle Position During pattern matching the scanner must know what part of the pattern it is trying to match. The pattern alternatives are kept in a queue. When a new alternative is needed it is u further broken down to all the operands that need to be concat- enated together during this alternative. These operands are stored in another queue. When the scanner is ready to do the pattern match, it gets an operand from the queue. Then it must decide what kind of an operand it is dealing with. If the operand is a string, the pattern match is simple. Only one element of the subject array needs to be matched. Since the operand has only one element, there is no need for a needle position. If the operand is a function, then the function must set the needle position, if necessary; the main routine simply transfers to the function and resets several variables upon return. If the operand is an array, the scanner must keep track of the elements of the operand. This is done by using a pointer called the needle which points to the current element in the pattern array. The needle is moved in the pattern array as follows. Initially the needle points to the position in the pattern array that corresponds to the origin in the subject array as defined by the current scanning direction. When the cursor finds an element in the subject array that matches the current element in the pattern array, the needle is moved to the next position in the pattern array as defined by the current scanning direction. The cursor is also advanced to its next position. Once a partial match has begun the subject array must be partitioned so that only an area as large as the pattern array is considered. For this partition, the current position of the cursor assumed to be the origin of the pattern. For example in 15 Figure H if the subject array has been scanned as indicated and a partial match has been found at position X, the cursor now considers only that part of the subject array enclosed in the box. The cursor moves in the box in the direction indicated. Originally the needle is at position Y and moves in the pattern in the indicated direction. If the match fails at some element of the pattern, then the cursor is returned to position X and a new alternative is obtained. Once one element of the pattern array has been matched, all of the elements must be matched. Otherwise the match fails, and the scanner looks for another alternative. The cursor is returned to its position before the match was found, and the needle is returned to its original position. Note that the movement of the needle is specified by the current scanning direction. The example in Figure 5 illustrates the movement of the cursor and the needle. In Figure 5a no scanning direction has been specified so the default direction is assumed. Assume also the unanchored mode. The elements of the subject and pattern arrays have been labelled as indicated, merely for convenience. The cursor starts at position A and the needle starts at position S. These do not match, so the cursor moves to B. These do match, so the subject matrix is partitioned as indicated in Figure 5b. The cursor is now moved to position C and the needle is moved to T. These match, so the cursor is moved to E and the needle to U. These do not match, so the needle is moved Subject 16 Pattern Cursor movement Needle Movement Figure 4. An Example of Partitioning 5b 5c I ,1 i 2 G* HT 1^ 12 4 A- B £ G- 1 17 5a Subject Array Pattern Array 2 T i A I B 2 C 2 Gi Hi i2 ui v 2 2 4 S- T~ ul v2 2 4 S- T- Figure 5- Example of Array Pattern Matching 18 back to S and the cursor is moved to C. The old partition is now removed . The cursor is then moved to C, then D, then E, where a match is found. Now the subject array is partitioned again as indicated in Figure 5c. The cursor and needle then move to F and T, H and U, E and V, where matches are found at each posl tion. At this point the array pattern match succeeds. When the match succeeds, the partition is again removed. The cursor would not be set at SUB<2,4> if a concatenation of type @1 is to be performed next or at SUB<4,2> if a concat- enation of type @2 is next. The type of the concatenation is specific in the pattern or it is assumed to be type @1 if not specified. Notice that in either case position G is skipped entirely . 2.6 Patterns and Primitive Functions 1. ATAB(X,Y) This primitive positions the cursor during pattern match- ing. X and Y must be integers or integer variables. If S is the subject array, ATAB moves the cursor so that it points to S. If there is no such element in the subject array, ATAB fails. 2. APOS(I,J) APOS acts as an anchor; that is, if S is the subject array, this primitive tests to see if the cursor is at S. If so, APOS(I,J) succeeds; if not it fails. I and J must be integers or integer variables. If the element S does not 19 exist, the primitive will always fail. The position of the cur- sor is not changed by APOS(I,J). By using APOS a pattern can be constructed that will match the subject array, beginning or ending at a given point in the array. 3. CURS(X,Y) This pattern assigns to the variables X and Y the cur- rent position of the cursor. The position of the cursor is known always in the main routine AMATCH, and CURS(X,Y) merely assigns this position to X and Y, where X is the first subscript and Y is the second. CURS(X,Y) does not change the position of the cursor. The assignments take place as an immediate assign- ment, that is X and Y are given values when CURS(X,Y) is en- countered even if the succeeding pattern match fails. CURS(X,Y) always succeeds. 4. SIM(A,B) This predicate tests if the arguments A and B are simi- lar, i.e., if they have the same dimensions. If so, SIM(A,B) succeeds; otherwise it fails. A and B must be variables. If A and B are both strings, integers, or reals they are similar, since these types are considered to be 1 by 1 arrays. During pattern matching SIM(A,B) does not move the cursor. 5. ABREAK(STRING) This pattern is similar to BREAK(X) for strings. ABREAK(STRING) is a pattern structure that begins at the cursor position and matches elements of the subject array as long aj the elements do not match the variable STRING. STRING may be 20 a variable, string, integer, or real. If it is a variable, its value must be acceptable as a pattern in string pattern matching. If the argument is a string, it must be enclosed in double quotes . ABREAK must match at least one element of the subject array, or else it fails. ABREAK moves the cursor to the last element in the subject array that did not match STRING. If STRING is not found in the subject array, ABREAK fails and does not move the cursor. 6. ASPAN(STRING) This pattern is similar to SPAN(X) for strings. ASPAI begins at the present cursor position and matches elements of the subject array as long as they match STRING. STRING may be a variable, string, integer, or real. Since STRING will be used as a pattern in string pattern matching, its value must be accep- table as a pattern. A string in the argument must be enclosed : double quotes . ASPAN must match at least one element of the sub- ject array. ASPAN moves the cursor to the last element in the subject array matched by STRING. If ASPAN matches the rest of the subject, the cursor points to the last element in the subject array. ASPAN uses the current scanning direction to obtain ele- ments in the subject array to be matched. 7. EQUIV(A,B) This predicate tests whether A is equivalent to B. A is equivalent to B if and only if every element of A is identical to the corresponding element of B. Identical is defined by the predicate IDENT for strings. If this is the case EQUIV succeeds; 21 otherwise it fails. If EQUIV succeeds during pattern matching, it does not change the position of the cursor. 8. ALOOP(X) This predicate tests whether there is a loop of the string X in the subject array, starting at the present cursor position. This is done by successively examining all possible paths of X's from the present cursor position. All the neighbors of the given element are examined. If one of the neighbors of an element is an X, its position is recorded in a stack. Then all of the neighbors of this recorded position are checked by this same procedure. A neighbor is considered to be directly above, below, or to the side of a position. If a position is already in the stack, it is not added again. Now if the starting position is ever added to the stack there must be a loop of X's in the subject array, starting at the given point of the array, i.e., we started there and we got back following a path of X's. This predicate succeeds or fails; in neither case is the cursor moved . 9- ASIZE(X) This routine returns the upper and lower bounds of the subscripts of the array X. X must be a variable whose value is a string integer, real or array. The upper and lower bounds of the first subscript are assigned to the variables N2 and Nl respectively. The upper and lower bounds of the second subscript are assigned to the variables M2 and Ml respectively. Only the first two subscripts of an array are checked. If X is not a string, integer, real, or array, ASIZE(X) fails. ASIZE(X) does not move the cursor. 22 3. IMPLEMENTATION 3.1 Pattern Matching Array pattern matching is done by means of the follow- ing statement. SUB & PAT Here & is a binary operator that is defined to be the same as the routine AMATCH by including the following statement at the beginning of the program. OPSYN( '&' , 'AMATCH' ,2) SUB and PAT are the subject and pattern of the array pattern match, respectively. The pattern matching statement is evaluated according to the rules given in the SNOBOL manual, with one exception. It is more convenient to obtain the new subject position after the new pattern position is obtained. In this program array alternation is indicated by A| , The two types of array concatenation are indicated below. A gl B is A A @2 B is S Notice that ordinary concatenation and alternation may still be used, but only for a pattern that is to be matched to a single element of the subject array. If a string pattern is to be used 23 in array pattern matching, it can not be used explicitly in the array pattern. Instead the string pattern must be assigned to a variable, and the variable is used in the array pattern. The following example is correct. A = LEN(2) 'CAT' RPOS(O) ARR = ARRAY ( *1,1 T , '2' ) ARR & 'A A | B' The pattern for the array pattern match must be enclosed in quotes. If a string is to be included in the array pattern, the usual convention of double quotes should be used. Strings enclosed in double quotes can only be used as the arguments of functions. If a string is to be used for any other purpose, it must be assigned to a variable and the variable is used In place of the string in the array pattern. Ordinary immediate and con- ditional value assignments can be used, but they only indicate strings found in one element of the subject array. Parentheses can be used to change the precedence of array alternation and concatenation. However, the expression must be enclosed by '( ' and ' )'. This aids in the scanning of the array pattern. Parentheses that are used in function calls must not have this form . The pattern match will fail at an element of the subject array if that element can not be used as the subject of a string pattern matching statement. For example, if the element is a pattern or a pointer to an array, the match for that element will always fail no matter what the pattern is. 24 The subject of an array pattern match must be an array or a string. It may not contain A| or @1 or @2 because these constructs are not arrays. The subject can be a string since strings are considered to be one by one arrays. However, if the subject is a string, all occurrences of A| and @1 wil" be replaced by the corresponding string operations, and a string pattern match will be performed using the subject and the alteret pattern. If the subject is a string and the original pattern contains an occurrence of @2 the string pattern match will always fail because @2 implies that the pattern is at least a two by one array. This pattern can never match a subject that is a one by one array. If a part of the pattern is an array, then it must be given special consideration. The subject array must be par- titioned during array pattern matching so that only an area as large as the pattern array is considered. The partitioning is done during the routine NEX . This partitioning involves tem- porarily changing the upper and lower limits of the subject arra subscripts. Before they are changed, the old values of these limits are saved. As soon as this pattern piece is finished or if the piece fails, the partition must be erased. The old upper and lower limits of the subject array subscripts are restored. A more complete description of partitioning is given in section 3-7. All alternatives are tried at a given subject position. If all these fail, a new subject position is obtained using the 25 scanning direction. If no new subject position can be found, the array pattern match fails. The flow chart of AMATCH is given in Figure 6. Each routing of AMATCH is discussed separately. A listing of each routine is given in Appendix A. 3.2 Subject Evaluation Since the subject of an array pattern match must be an array, integer, real, or string, the routine ESUB checks the data type of the subject. If the subject is a string, integer, or real, then @1 and A| are changed to ' ' and ' ' res- pectively in the pattern, and an ordinary string pattern match is performed. If §2 occurs in the pattern, the match fails. During subject evaluation several variables are ini- tialized. INT is a variable used to control a new scanning direction if one is ever specified. MATCH tells if the array pattern match is successful. ASIZE(A) gets the upper and lower bounds for the indices of A. These limits will be used later to move the cursor in the subject. The call to SCAN sets the scanning direction to the default direction. NEDI and NEDJ are the row and column indices of any arrays used in the pattern. CRUI and CURJ are the row and column indices of the subject array. STI and STJ are used to store the row and column indices of the subject array whenever a new alternative is tried. These variables are used to reset the cursor if the alternative fails. The flow chart of ESUB is given in Figure 7- 26 AMATCH ± Evaluate Subject y. Evaluate Pattern ± Get Alternative V Get Position in Pattern ±. Get Position in Subject NO > Try Another Alternative in Pattern ^ There is an, Alternative No Alternative Try Another Position in Subject with All Alterna- tives J^ There is Another Position No Other Position Possible Fail Figure 6. Flow Chart of AMATCH c Start 27 Ak_ Test if Subject is string, inte- ger, or real Yes Change Alternation and Concatenation as for Strings No Do String Pattern Match \ ( Yes Subject is OK Initialize Variables, Return Fail ^ Succeed Pail 1* Figure 7. Flow Chart of ESUB 28 3.3 Pattern Evaluation Pattern evaluation is done in a routine called EPAT. An array pattern is one or more alternatives, so this routine puts these alternatives in a queue called ALTN, where N points to the element of the queue. The alternatives are found by concatenating balanced expressions until an occurrence of A | is found. These expressions are put in the queue, and the search for more alternatives is resumed after the A| A function INCR(I) is used to adjust the queue pointer. Since EPAT can be called recursively, a variable STA is used to point to the end of the present queue when the routine is called. By using the queue ALTN, the alternatives can be considered one by one during pattern matching at a given subject position. If EPAT does not find at least one balanced expression, the routine fails. The variable FIN is an end test for each alternative and is set to zero during EPAT. 3.^ New Alternative The routine ALTERN is called each time a new alternative is used in array pattern matching. When a new alternative is needed it must be further simplified since the alternative is one or more operands concatenated together. These operands can con- tain expressions enclosed in parentheses, or they may be variable. When an alternative is needed, each of its operands is placed in another queue by concatenating balanced expressions from the alternative until a concatenation operator is found. The bal- anced expression is placed in the queue CONN where N is a pointer 29 to the queue. The search for more operands is resumed after the concatenation operator. As each operand is placed in the queue, it is labelled to tell how the next operand is to be concatenated to it. The label tells if the concatenation is @1 or @2 . For an alternative to be successful, all items in its queue must match the subject. ALTERN is also recursive so STC is used to move the pointer to the last element of the present queue. Certain flags are set in this routine. INCI and INCJ are used to position the cursor after each operand is used in pattern matching so the concatenation is done properly. These variables are set in AMATCH by looking at the label of each operand. The last oper- and in the alternative is labelled by the value of the variable ALE. ALE is used so that if ALTERN is entered recursively, the concantenation will be done properly upon return from it. BEGALT is a flag indicating that a new alternative has just been started. 3.5 Position in Pattern The routine POSPAT finds the position in the pattern. If an operand has just been finished, (FIN = 1), then the cursor must be moved to the correct position to concatenate a new oper- and to the old one. CK is set to 1, indicating that the cursor is already in the proper position, and a new element is obtained from the queue CONN. If there are no more elements in the queue, the pattern match has succeeded, and MATCH is set to 1. 30 If not, the label of the present queue element is stored by the variable AL, and several alternatives are considered. The queue element is examined to see if it is an expres- sion enclosed in parentheses. If so, the values of some current variables are stored and the routine REC is called. This routine handles expressions and is described in section 3*8. On return from REC the variables are reset. REC fails if the expression did not match the subject and succeeds if a match was made. If the queue element is the function SCAN, a new scan- ning direction is set. SCAN is discussed in section 3«7. If the queue element is a function, then control is transferred to that function. Each function must then take care of moving the cursor and needle and deciding if this part of the array match succeeds or fails. If none of these alternatives is chosen, the current queue element is checked for its datatype. If it is a string, integer, real, or pattern, it is assigned to the variable S. FIN is set to 1 indicating this element is finished, and POSPAT returns to AMATCH. If the element is an array, and this is the first time the element has been used, the subject array must be partitioned. The needle is set to the origin of the pattern piece and POSPAT returns. If this is not the first time the element has been used, the subject array has been partitioned. The needle is advanced and POSPAT returns. If the needle can not be advanced, then this element is finished and POSPAT is called again. (A new position in the pattern must still be 31 obtained.) If the match fails or if the pattern array is fin- ished, the subject array must have the partition removed. This is done by restoring the old upper and lower limits for the subscripts of the subject array. Partitioning is discussed in section 3-7. Each time an operand is finished INCI and INCJ are set to the appropriate values so that the cursor will be advanced correctly in the subject array. A flow chart of POSPAT is given in Figure 8. 3.6 Subject Position The routine SUBPOS changes the cursor position. If INT is 1, then the cursor position is set to the current origin. If BEGALT is 1, then the new cursor position is saved in STI and STJ , so the cursor can be returned to this position if this alternative fails. If INT is not 1, then the routine NEX is called. This function increments the cursor position, by trans- ferring to the current scanning direction block. The variable XXX points to the current scanning block. If the cursor can not be incremented, then SUBPOS fails. The cursor can not be moved if &ANCHOR is one or if there are no more elements of the subject array to be examined. 3-7 Scanning Directions Two functions, SCAN and NEX, are needed to move the cur- sor and needle. The scanning direction is obtained from a block of code labelled by NEXN where N is an integer. The default scanning direction is labelled NEX1. To use another scanning 32 ii x o Eh < s CQ QJ U 09 •H a o 2 r*\ •> % PC w PC w ■p CD O 5 o w CD JU o cd cd 4-5 -P 0) 0) a.' 0) 0) CO H 3 wacr A" ^^ DC Eh W PC r~s DC :=> Eh w PC DC Eh DJ PC C O •H 4-3 O C 3 Ph r^\ c o •H 2 O P P o J g c • Eh O 3 W O Ph VV A ii < C CO 7F co CD >H Eh < CO o p.. Q-i P o ? H 00 CD ; 3 -d CD .c c co O •H -H bH C P < •H CD «H (H Cm O P CO CD m O CD -H aj "V Dm ? C6 rH O £ CO II O P •H S T5 _ (DCH C ° 13 P fc 3 UL 33 direction the user should label a block of code by NEXN where N is not one. CURI and CURJ have been passed by name as the parameters I and J. The user's program should increment or decrement the values of I and/or J. The user must decide if the new value is out of the subscript range. If this happens the routine should fail. The range of I is from Nl to N2 . J ranges from Ml to M2 . These values are supplied to the user. Finally, the last statement must contain a return (PRETURN or RETURN) to the main routine. The partitioning of the subject array must be done in the block of code labelled NEXN. The first time an array is encountered in the pattern, the routine NEX is called with the argument P having the value one. If P is one, a block of code must be provided to do the partitioning. The subject array is partitioned by changing the upper and lower limits of its sub- scripts. Before these are changed, the old values must be stored in variables as follows: ST1=M1 ; ST2=M2 ; ST3=N1 ; ST4=N2. The present cursor position is the origin of the parti- tioned array. The user must change the value of the subscript limits so only an area the size of the pattern array is included by the limits. The routine ASIZE is helpful in obtaining the size of the pattern array. If P is not one, then the partition- ing has already been done. Another block of code must move the cursor in the desired manner. 3* A new scanning direction is specified by using the function SCAN(X,N,M) in the array pattern. X is the integer used in the label NEXL. (X=L) N is the first subscript of the origin position; M is the second. The origin becomes SUB N and M are tested to see if they are in the proper range. If not, SCAN fails; otherwise it succeeds. 3.8 Expressions with Parentheses The routine REC handles expressions with parentheses. During pattern matching an expression with parentheses is treated like any other operand. To evaluate such an expression one must realize that it is just a miniature array pattern. All the opera- tions that were applied to the original pattern are reapplied to this expression, so the routine REC looks very much like the routien AMATCH . The only exception is that REC does not move the cursor position if all the alternatives in the miniature pattern fail. Instead, it returns to the main routine with an FRETURN. If one alternative is successful in the expression, then REC re- turns with a RETURN. Several problems result from calling the same routines as AMATCH. All of the queues used in AMATCH must be left intact after a return from REC or the rest of the pattern match will not work properly. To insure that the queues are not overwritten, the queue pointer is set to point to the end of the queue before calling REC. On return the pointer Is reset to its original value. The label from the current queue element must be stored so that 35 the last operand used in the expression will also be labelled with this value. The values of INCI and INCJ must be saved so that on return the old values are added to the present values, so that the cursor will be moved properly. Other variables must also be saved by making them arguments of the routine REC . On return their old values will be restored automatically. 3.9 Additional Functions Some other useful functions are used in the program. INCR increments its parameter by one. This is used to control the queues. The argument must be passed by name for this routine . The routine ASIZE finds the upper and lower limits of the subscripts of its argument. If the parameter is not an array or string, ASIZE fails. The lower and upper bounds of the first subscript are returned in Nl and N2 respectively, and the lower and upper bounds of the second subscript are returned in Ml and M2 respectively. If the parameter has only one sub- script, then M1=M2=1. If the argument is a string, the values of all the variables are one. 36 k. PREDICATES AND PRIMITIVE FUNCTIONS This chapter describes the predicates and primitive functions that have been implemented for array pattern matching. These functions can be used with any scanning direction during pattern matching. Since all of these patterns have been written as functions, a define statement is needed for each one if it la to be used with AMATCH. The defining statements as well as the routines are listed in Appendix A. H.l ATAB(X.Y) This routine is similar to TAB(X) for string pattern matching. However, since forward or backward moves are ambig- uous for arrays, no attempt was made to distinguish between TAB and RTAB . This means that any movement of the cursor is possibl. The only test that is necessary is to see if X and Y are within the proper ranges for the subscripts of the subject array. If this is not true, then the routine ATAB fails. Otherwise ATAB gives CURI the value of X and CURJ the value of Y. X and Y must be integers or integer variables. ATAB does not test the arguments to be sure they are integers. However, if they are not integers, the subsequent use of CURI and CURJ in AMATCH car. cause array references to fail or other patterns to fail. The results are totally unpredictable so such cases should be avoide. 37 ij.2 APOS(I,J) APOS (I, J) is similar to POS for string pattern matching. Since forward and backward movement of the cursor are ambiguous, there is no difference between POS and RPOS for arrays. APOS accomplishes the same function as both POS and RPOS. APOS tests if the cursor is presently positioned at SUB. If not, APOS fails; otherwise it succeeds. I and J are not tested to see if they are in the proper subscript range. If they are not in the proper range, APOS will always fail. I and J should be integers or integer variables, because APOS uses IDENT to test the cursor position. If I and J are not integers, then APOS will always fail. A call to APOS does not change the cursor position. 4.3 CURS(.X,.Y) The cursor position operator inspired this function. In string pattern matching the cursor position operator is a unary operator, but for array pattern matching a binary operator is needed since there are two subscript values to be stored. Since a binary operator would be confusing for the scanning routines in AMATCH, a function was used instead of a binary cursor posi- tion operator. X and Y must be variables, and they are passed to the routine by name . This is done by using the unary name operator . as shown above. If X and Y are not variables, the results of the routine are unpredictable. In some cases this will cause an error and termination of the program. No test is performed during CURS to determine if X and Y are variables. 38 During CURS X is assigned the value of CURI, and Y is assigned the value CURJ . CURS always succeeds. Execution of a call to CURS during array pattern matching does not chance the cursor position. H.l\ SIM(A,B) SIM(A,B) tests if A is similar to B. Similar means that A has the same shape as B. If so, the routine succeeds; if not it fails. In array pattern matching this test is not as easy as it sounds. If A and B are both arrays then they are similar If they have the same size. The routine ASIZE is used to obtain the size of the arrays. If A and B are both strings, integers, or reals, they are obviously similar. However, if one of the arguments is a string, it can be similar to a one by one array. Similarity is only defined for strings, integers, reals, or arrays. If either A or B is not a string, integer, real, or array, then SIM automatically fails. DATATYPE is used to determine the type of the arguments. This means that some- times the type 'string' is given to unusual arguments. For example, the name of a function is sometimes considered to be a string. In this case the function name is similar to another string or a one by one array. The routine SIM does not change the cursor position. 4.5 ABREAK(X) and ASPAN(X) These patterns are like BREAK and SPAN for strings. The only difference is that the array patterns continue as long as 39 the elements of the subject array are of the proper form. ABREAK matches the longest continuous series of elements beginning at the present cursor position that do not match X. ABREAK matches all these elements up to but not including the first element that matches X. The cursor is set to point to the last element that that did not match X. If X is not found in the subject array, ABREAK fails. ASPAN matches the longest series of elements of the sub- ject array that match the argument X. The cursor is positioned at the last element matched. ASPAN always matches the longest series of elements. If the end of the subject array is reached, ASPAN stops, and the cursor points to the last element of the array . Both ASPAN and ABREAK must match at least one element or they will fail. Both use the current scanning direction to ob- tain the next element. Both patterns reset INCI and INCJ so that any concatenation is done properly. H.6 EQUIV(A,B) This routine tests to see if the two arguments A and B are equivalent. A is equivalent to B if and only if every ele- ment of A is identical to the corresponding element of B. The elements are identical if the predicate IDENT is true when the elements are used as its arguments. EQUIV succeeds if this is the case; otherwise it fails. EQUIV first tests to see if A and B are similar, using the array pattern SIM, because the arguments can not be equivalent 40 without also being similar. Then the datatype of the arguments is tested. If the arguments are strings, the equivalence test is trivial. If one is a string, the other argument must either be a string or a one by one array. In either case only one test of IDENT is needed for EQUIV. If the arguments are both arrays, all the elements of the arrays must be searched. If an element is not identical to its corresponding element, EQUIV fails. If one or both of the arguments is not a string, integer, real, or array, EQUIV always fails. EQUIV does not change the cursor position . *J.7 ALOOP(ARG) ALOOP(ARG) tests to see if there is a loop of ARG start- ing at the present cursor position. Here ARG may be anything that can be used as the pattern of a string pattern match. ALOOP tests all the neighbors of the present cursor position to see if any of them are ARG. If one is, then it is assumed to be the start of the loop. Its position is put on a stack. Now its neighbors are checked in the same way. The first neigh- bor to be checked is the one directly above the current element. This process is continued until either the starting position is reached or there are no more possible paths to check. If the starting position is reached again, then there is a loop, and the routine successfully returns. If there are no more possible paths at this point, then the routine assumes it made a mistake at the last element it put on the stack. This one is removed, and the process continues. When the elements are stored in the 41 stack, they are labelled telling which direction was used to find the next neighbor or element in the stack. When an ele- ment is removed, the routine will not find the same neighbor. After the element has been removed from the stack, the rest of its neighbors are checked. If one is ARG, then it is assuemd to be the continuation of the path. This whole process will then search all possible paths starting from the original cursor position. If an element that is already in the stack is obtained as a neighbor, this element should not be considered again. Otherwise this will lead to an infinite loop in the routine. The variable LASTEL is used so that the routine never tries to go backwards along the current path. If a neighbor is LASTEL it is automatically thrown away. LASTEL points to the element that was found before the current element. ALOOP does not change the cursor position. A flow chart of ALOOP is given in Figure 9- ALOOP iJ2 ± Get a neighbor There is a neighbor A A St Put on stack. Use this as new starting posi- tion This neighbor is wrong, Try another neighbor Remove element from stack YeT Return successfully Figure 9. Plow Chart of ALOOP 43 5. CONCLUSION This thesis has shown how SNOBOL pattern matching can be extended to include two dimensional arrays as the subjects of pattern matching. The routines developed here show that this project is feasible. However, if array pattern is to be used extensively, the SNOBOL compiler should be patched to in- clude this type of pattern matching. If the compiler is changed, then many of the routines can be simplified considerably, but the basic ideas should be retained. The patterns that have been included in this project show the user how to construct other routines and are useful in constructing array patterns. With a little imagination most pattern matching necessary for arrays can be done using only these patterns and the proper scanning direction. kH BIBLIOGRAPHY Griswold, R. E., Poage , J. P., and Polonsky, I. P., The SnobolU Programming Language , Bell Telephone Laboratories, Incorporated, Englewood Cliffs, New Jersey: Prentice- Hall, Inc., 1971. "5 APPENDIX A LISTING OF THE ROUTINES I * ROUTINE AMATCH DO THE PATTERN NATCH **$**$*£*:******************************************************* DEF IN- ( • AMATCHI SOB, PAT ) • ) AMATCM FSUB< ) :F( FRETURN) r rQ(MATfH, 1) :S(RETURNI jP t-P^T(PAT) :F(FRETUKN) 4ML ALTr RN< ) :F(FRF TURN) HEkE PHSPATO :F(AMH) cQ ( MATCH, 1) :S< RETURN) lK = r O(CK,l) :S(AM) SU3P0S< ) :r ( AMH) 4M S.i = SUH LINT = OUTPUT = • SJ' SJ ■S* S SJ ol S(0) S PPOS(O) :S(HERE) * * T^Y ANOTHER ALTERNATIVE * *HM QURI = STI CUR J = ST J SJ = DATATYPE!* ($( »CON' CUM SJ 'A^RAY' :F(AAM) * * UNDO PARTITION Ml = STI ; M2 = ST2 ; Nl = ST 3 ; N2 = ST^ U« &J = AJ ♦• 1 SCANd ,N1 ,M1 > GT(AJtMAXA) :F(AM2) > TRY ANOTHER POSITION IN SUBJECT AJ s STA ; BEGALT = 1 SU8P0S< ) :F( FRETURN) \*2 ALTERN1 ) : F( FRETUPN ) BEGALT = POSPAT( ) : F( AMH) EOIMATCH,!) : S ( P fcTUKN ) F ( AM ) ♦ bUfUKT FVALUA11UN lb SUBJECT AN A^WAY? ♦ IN IT IAL I/f- VAW 1ABLES * [>EF INE ( ' FSUBI )• ) 6 Sl/a INT = ; STA ■ 1 ; STC = l ; FLAG = LINT =1 ; CK = ; MATCH = ; ALb ■ '1 ' S = DATATYPE- < SUB ) rUTPUT = ' DATATYPE Of SUBJECTf ' S SI ■ 'STRING' I 'INTEGER 1 I • a E AL • si : F I E V S ) SUBJECT IS STRING oul • a)2 ' :S (PRE TURN 1 E V 1 PU'fll' =•' :S(tVll EV2 PAT ■ A | • = ' I ' :S(EV2) PAT = $(PAT) SUB PAT :F (FRETURN ) MATC^ ■ 1 : (KbTURN) EVS S •ARRAY* ;P (FRETURN I SUBJECT IS OK ASIZE(SUB) sCAN{ i,Nl ,M1) NEOl = NED J = CUR I = riRGN LURJ = ORGM STI = CUkI E (FRETUkN) :F( FRETUkN) ST J = CUR J :( i E TUkN ) * EVALUATE PATTERN * PUT ALL ALTERNATIVES IN QUEUE DEF INb( • £PAT( PAT ) • ) EPAT AJ = STA ; A = PLOOP PAT PCS (A) HAL . $('ALT' A J ) ' A| • * *INCP(.AJ) *A :S(PLOOP) cat POS(A) HAL . $('ALT' AJ ) RPnS(O) :F(FRETURN) MAX A = AJ AJ = STA c IN = 1 : (KfcTURN) *********************** ************** ******** ****** ************* * GET NEW ALTERNATIVE * PUT ALL PARTS TCI BE CONCATENATED IN QUEUE * LABEL EACH ONE v **************************************************************** OtHNtl «ALTEPN( ) • ) ALTlPN CI - STC ; A = ; 8EGALT =1 ; I NCI = I NC J = F IN = I LOOP $('ALT« AJ ) POS(A) HAL . SCCON 1 CI) ■ i 1 Ml ■ .01 I * * 2 ' . 01) i)A : S( AT T ) $( 'ALT' AJ) PQS(A) BAL . tt'CON* CI) RPHS(O) : E (FR L TUR N ) %( 'CON' C I ) = ALE $( •CUM' CI ) OUTPUT = ' CONCI ' i(»CON» CI) MAXC = CI CI = STC. - 1 : (RETURN) UT $( 'CCN' CI ) = Gl $( 'GUN' CI ) INCR(.CI) :PAT EQlFINtOI :S(PHSP) CUR I = ST I + INC I ; CUKJ = ST J + INCJ CK = 1 IC1 CI = CI ♦ 1 : STPART = i FIN = GT(CItMAXC) :F(POSPO) HATCH = 1 : (RETURN) * NCW PIECE IS FOUND 'USPO $( 'CON' CI ) LEN( 2) . AL = AL = TRIV(AL) M'CON' CI) POS(O) •( • :F(POSPI t ■ PARhNTHESbS AROUND PIECE. DU RECURSION. FIRST INITIALIZE PAT = $(»CON« r. I ) ; RAT POS(O) '( • = RAT • )• RPf)S(O) = OLA = ST A ; OLC = STC 5 STA = MAXA ♦ 1 STC = MAXL «■ 1 ' ' L I I = INC I ; OLIJ = INCJ ; ALE = AL • ■ R EC (A J, CI , MAxAt MAXCtS rA»STC f RAT f STI t STJ r OLA , OLC f OLI I t OLIJ t ALJ : F ( R E S T ) EbfrT I NCI = INC I ♦ OL II ; INCJ = INCJ + ULIJ STA = OLA ; STC = OLC ; MATCH » ; FIN * 1 FLAG= EQ(FLAG,1) : S ( FP ETURN ) F ( HP SP AT ) EST HAG = 1 : (RESET ) ♦ m PAkFNTHESES. L()(JK F DM SCAN * PQSP IC'CON 1 CI) ('SCAN' BPFAK(')') ')') . F :FI^) INT = iO(LIMT, II 1 VAI (t ) :MPT ) UN = F U( I INT ,0) 1 :S(PDSPATI l INT = o : CURI = URGN ; CUPJ ■ orgm ST1 ■ CUR] ; ST j ■ cukj SUCH » 1 INT - J(FP r TUPN) * Sfcl U PIECI IS FUNC T I UN •x PP tCCON' CI) •(• :S(PIX) US = DATATYPE! K S( •C'JN 1 CI ) ) ) MJTPUT = ' DATATYPf OF C0NC1 ' DS •STRING* I 'INTEGER 1 I 'REAL 1 I 'PATTERN' :S(PP1) OS 'ARRAY 1 :S(PP2) 48 * DO '-"UNCTION CALL * * : S(RFTURN )F (FRETURN ) rfE HAVh FINISHED THIS PIECE J Pb FIN = 1 ; E0( AL,2 ) :F(PP6) INCI = INCI + N2 - Nl + 1 :(PP7) j ^-j INCJ s M2 - HI ♦ I ♦ INLJ PP/ Ml = ST1 ; M2 = ST2 ; NI = ST3 ; N2 = ST4 :(PGSPAT) ***** ********************************************** ************* * * GET POSITION IN SUBJECT **************************************************************** OEFINE( «SUBPOS( ) ' ) SUB°OS FOUNT, 1) :F(SBP) * * HIRST TIME HERE. CURSOR AT ORIGIN 49 UJR I = ORGN ; CURJ = ORGM ; I NT = EQ(BFGALT,1> :F(RFTURN) STI = CUkI ; STJ = CURJ ; BEGALT = MUVtr CURSOR IN ARRAY : < RETURN) idP ANC = SANCHPR ; EQ(ANCtl) :S(FR£TURN) MEX( XXX, .CUR I , .CURJ ,0) :F (FRET URN) E0(BEGALT,1) :F(RETURN) STI = CUR! ; STJ = CURJ ; BEGALT = MsETUkN) **************************************************************** * SET SCANNING DIRECTION ********************************* *********** ********* *********** DEFINE! ' SCAN(X,N,M) • ) iCAN XXX = X ORGM = M ; ORGN = N >Cl GMM,M2) :S(FRBTURN) ; GT(N,N2) :S(FR£TURN) IT(M,'«U) :S(FRETURN) ; LT(N,N1) : S ( F RE TURN ) F ( KE TUR N ) *************************************************************** AN AID IN SETTING QUEUE **************************************************************** DEFINE! • I NCR! I) ■ ) NCR $1 - $1 + 1 : (RETURN) 50 * CRTS NEX1 POSITION DEFAULT NEX IS NEX1 I IMt ( »NEX(X, I ,J.P ) ' > J' X : ( i( 'NEX' X ) I kxi EO(Pfl) :S(NX) * * Nl partition SJ = $J ♦ 1 ; GT($J,M2> :F(RETURN) tj = Ml ; II ■ tl + 1 ; GT($I,N2) :StFRETURN)F(RETURN) * STA-JT PARTITION NX ST1 = Ml ; ST2 = M2 ; ST* = Nl ; S1-* = N2 ASIZF ($($( 'CON' CI))) :F :S(FkrTURN) IT( M 1,ST1) :S(FRETURN) ; GT(M2 t ST2) : S( FRET URN ) F ( Rt TJft N ) * * PARENTHESES IN PATTERN. 00 AMATCH AGAIN ONLY DON'T * MOVE CURSOR IN SUBJECT IF FAIL DEFINE(»REC(AJtCI ,MAXA,MAXC , STA ,STC ,PAT f STI t STJ , OLA,OLCt « * ,r, Ll I tOLIJtAL) « ) REC ^ AT (PAT) :F( FRF TURN) ALTbRN( ) :F (FRETURN) LAB POSPAT( ) : F( LOB) EO(MATCHfl) :S(RETURN) CK = EOICK, I) :S(RLAB) SUBPGStl :F(LOB) RLAti SJ = SUB LINT = OUTPUT = • SJ ' SJ ' S • S SJ POS(O) S PPOS(O) :S(LAB) * TkY ANOTHER ALTERNATIVE LOB CURI = STI ; CURJ = STJ :>J = OATATYPE( $( $( »CON' CI))) SJ • A'^RAY' :F(ROfl) Ml = STI ; M2 = ST2 ; Nl = ST 3 ; N2 = ST4 ROB AJ = AJ + i ; GT(AJ,MAXA) : S ( FRETURN ) ALTEON! ) :F (FRETURN) iALT * ; POSPAT( ) : F(L0 3) E0(MATCH,1) :S(PETURN)F(RLAB) 51 # * A VERY USEFUL ROUTINE. GIVFS UPPER ANO LOWER BOUNDS OF ARRAY * UPPER ANO LOWER BOUNDS OF FIRST SUBSCRIPT IN N2 AND Nl * UPPER AND LOWER BOUNDS OF SECOND SUBSCRIPT IN M2 AND Ml DEFINE! • 4SIZE( A I I ,P • I AS I Z E S = DATATYPE( A) S 'ARRAY' :F(L5) AP = PROTOTYPE (A ) I = 2 LOOK FOP N 4P RQFAK ( ' , ' ) . N » i ■ REM . M IF ^AIL THEN A IS ONE DIMENSIONAL S(L1) I * 1 N = AP ML a 1 ; M2 = 1 N BREAM 1 :' I . Nl •:• REM . N2 :S(L2) Nl = i ; N2 = N LI Nl * Nl + ; N2 = N2 * ; EQ(I,1) :S(RETURN) f,ET m m rtkEAM*:') . Ml •:' REM . M2 :S(L6) Mi = i ; M2 = M Mi = Ml + U *, M2 = M2 + J : (RETURN) '5 P = •STRING' I 'INTEGER 1 I 'REAL' S o :F( FRF. TURN) * SUBJECT IS A STRING. STRING IS 1 BY 1 Nl - 1 ; N2 = 1 ; Ml = 1 ; M2 = 1 : ( RETURN) 52 « « LIK( SPAN. CONTINUES IN SUBJfcd AS LUNG SUBJECT PfulTIUN * WATCHI I IRGUMENT ,. *» <-****<-*************** **** *************#*******V*<«***V**lC< FINE!* ASPAN(C)' I AN II » ; Hmpi = CUK1 ; TEMpj = CURJ Ml S.I = SU IK CUR I ,CUKJ> I PIT = IUIPUT = ' LUMP THkO AS^AN* SJ C :T (ASPF ) 11 = 1 ; mm = CUPI ; OLDJ = CURJ Nf x( XXX, ,CU« 1 , ,CUKJ ,UI : S( ASPNL >F ( ASPf ) ASP r EQ( 11,0) : 5CF-RFTURN1 ( Uk I s OLDI ; CURJ = OLDJ ; TEMPI = CUKl - TfcMPJ IF'^PJ = CUP J - TEMPJ ; INC I = INC I * TEMPI INC J = INC J * TEMPJ : I RETURN I ***** **** ****** ******** ****** ********** ********** ***********>,:*** * * ABPEAK ACTS LIKE BREAK. IT MATCHES UP TO THE- SUBJECT * U LF<«F\7 THAT MATCHES rHI: ARGUMENT. IT MUST MATCH UNE ELEMENT * *v*v ********************************************* *************** DEFINE! ■A'BREAKIC) • I AB&EAK 11 = ; TEMPI = CURI ; TT-MPJ = CURJ *BLP SJ = SUB ; LINT = ; SJ C :S(ABRK) 11 = 1 ; tJLDI « CURI ; OLDJ = CUP J NEXIXXX, .CURI , .CURJ ,0 ) : F ( f-RETURN) St \ftLP > ABRK r 0( 11,0) : SIFRETURN ) CURI = OLDI ; CURJ = OLDJ ; TEMPI = CURI - T^.MPI rEMPJ = CURJ - TEMPJ ; IMCI = I NC I ♦ TFMPI INC J = INCJ + TEMPJ : (RETURN) *************** ************************************************* * TESTS IF CURSOR IS AT ARGUMENTS * *********** ****************************** *************<:*-t^^***** DEFINE! • APOS( I , J) • ) APOS I DENT (I fCURI) :F(FRE1URN) IUENT(J,CURJ) :F< FRET URN) S (RETURN) 53 * * ROUTINE EQUIV * DEMNL( , EQUIV lUFNTIAEtXl : S( RETURN )F( FRET URN) * SOTH ARE ARRAYS M = M2 -Ml +1 :F(FRETURN) :QU ASIZf.(Q) mSIZ5( A ) PI = Nl P2 = N2 01 = Ml Q2 = M2 * E J5 ST^RT EQUIV SEARCH I = Nl J * PI A F = A < I , M 1 > BE = B IDENTtAEtBE) :F(FRETURN) 1=1 + 1 J = J + 1 GT(I f N2l :F(EOo> T = Nl J = PI Mi = Ml ■«■ I 01 = Ql ♦ 1 GT(Ml f M2) :F (t:06)S< RETURN) IF }FAI_ OH INTEGER OK STRING :Q7 I OFNT( A, B) : S( \ETURN)F( FRETURNI 54 ♦ ♦**********************************************^***<-*********** * ROUTINE SIM **************************************************************** f [NEf 'SIMlA^ISiP'l > I M >A t DATATYPE (A) ; SH = UATATYPE(B) > 1 = •STRING' I » INTEGER 1 I • RE AL • sa SB :MSIMli i/\w L TYPF ; STR4 * N2 ASZN = N2 - Nl «- 1 8SZN = N^ - NL ♦ 1 ; M2 ■ STR4 NoT SAMP TYPE, CAN MATCH IF JNE IS STRING, ONE IS 1X1 AR^AY OP IF BOTH MATCH SI SA SI :S( SIM2) SB SI : S( SIM3IF (hkET'JRN) SA SI : S( SIMF ) SA ' ARRAY ' :F (FRETHkN) ST*l = Ml ; STR2 a M2 ; STk3 = NL 1SIZHAI ; ASZM s M2 - Mi ♦ 1 ; ASIZEIBI ; BSZM * M2 - Ml «■ 1 ; Ml = STR1 ; M2 = STR? ; Nl = STR3 LQI ASZM, rtSZM) :F(FRfcTURNI F(0(AS/N,BSZN) :F(FRETURN)S(SIMF) * * * * iiMi * * A IS STRING * SIM2 SB SI :S(SIMF) ; C = B :(SIM4) * * B IS STRING * 5IM3 SB = SA ; C = A KSIM4) SIM^ SB •ARRAY 1 :F(FRETURNI STR1 = Ml ; STR2 = M2 ; STR3 = Ni ; STR<» = N2 ASIZE(C) ; BSZM = M2 - Ml ♦ 1 ; BSZN = N2 - NL + 1 EO(BSZM,n :F(SIMFF) ; EO(BSZN,l) :F(SIMFF) Mi = STRi ; M2 = STR2 ; Nl = STR3 ; N2 = STR4 SI me FIN = 1 : (RETURN) SIMFF Mi = STRI : M2 = STR2 ; Ni = STR3 N2 = STR4 : (FRETURN) **************************** ******************* ***************** * * MOVES CURSOR TO POSITION GIVEN BY ARGUMENTS. FAILS * IF ARGUMENTS ARF NOT IN RANGE * ****************** ******~*********~****************** *********** DEFINE I • ATAB• PATHJ = CURJ ; LASTEL = LPPAT CHARL " SUB ^.HAWL ARC :F( FRF TURN) PATHI = CUR I NE IGH = PTk = * GET NEIGHBORS . FAIL IF NEIGHBORS ARE GUT OF RANoE. * LPPO NHI = PATHI - I ; LT(NHI,N1) :S(LPPF) NHJ = DATHJ : (LPPLPl LPPi NHI = PATHI J NHJ = PATHJ - 1 LT(NHJ,M1) : SI LPPF )F (LPPLP) L PP? MMI = PATHI + 1 ; NHJ = PATHJ GT(NHI,N2» :S(LPPF) F(LPPLP) LPP3 NHI = PATHI ; NHJ = PATHJ + 1 GT(NHJ,M2) :S(LPPF) F(LPPLP) * * IF NEIGHBOR IS UK f ADO TO LIST LPPU 1 POST = •(' NHI »,• NHJ •)• * * IF POST IS LASTtL. WE ARE GOING BACKWARDS. THROW AWAY THIS FLFM^NT * * POST LASTEL : S( LPP^ ) SEE IF ELEMENT MATCHES ARG CHARL = SUB ; CHA«L ARG :F(LPPF) HAVE At RETURNED TO THE STARTING ELEMENT? POST LPPAT :S(PETURN) IF POST IS ALREADY IN NEIGHBOR LIST, THROW 4WAY THIS ELEMENT NEIGH POST :SILPPF) P ; )T UN LIST NEIGH = NFIGH •(' PATHI •,» PATHJ •)' •:• PTR •¥' LASTFL = M' PATHI ',' PATHJ •)• JT^ = ; PATHI = NHI ; PATHJ = NHJ tUI'LPP 1 PTkl) WE WENT THL WPONG WAY, T«Y AGAIN LPPF f-aiPTR,3) :S(LPPS) PTR = PTR ♦ 1 -.(SI'LPP' PTR)) * WF CHOSE THE WRONG PATH, BACK OP ONE ELEMENT AND TRY AGAIN * 56 LP«>i> NfcIGH ( •(• bRFAKI'M) ')* ) . LASTf-IL ♦ •(• BREAM 1 ,') . PATHI ',• b«tAK('l'l . PATHJ •)' •:• » BREAM *«* I . Hk •«• RPUS(O) = LASTEL :F(LPLT) PATHI ■ PATHI ♦ ; PATHJ = PATHJ ♦■ : • RAIHl = PATHI ♦■ ; PATHJ ■ PATHJ ♦ : ( L PP F ) #**»^ *******«****«******************************#** ************* * GETS CURSOR POSITION. S TURFS IN X,Y DEFINHl »CURS« X,Y) • ) CURS tx - CUR I ; $Y = CUR J OUTPUT = 'LOOP THRU CUPS' :(P=TURN) 57 APPENDIX B The following programs are examples of the use of the routines described in this thesis. The first example tests the subject array for a spiral of the character string X. The sub- ject array used in this example looks like this: X X X X X X X X X X X X X X X X X X X X The pattern used in this example looks for an occurrence of an X by using the pattern ABREAK. When an X is found it is assumed that the X is the center of the spiral. Next the routine SET is called. This initializes some variables that will be used in the new scanning direction. The new scanning direction is specified by calling SCAN where the 9 points to the block of code that will be used to obtain new subject elements. ASPAN is now called. Since ASPAN uses the current scanning direction to obtain subject elements, the pattern will follow the shape of a spiral. When a subject element is found that does not match the string X, ASPAN returns to the main routine. Now the routine TEST is called. 58 This routine tests to see if the spiral found is big enough. A variable is incremented every time the spiral changes direc- tion. TEST checks to see if this variable is large enough. For La example a spiral must be at least the shape indicated below, I This pattern will recognize any spiral as long as it is at 1< this big. The pattern will find the first such spiral found by the original scanning direction. In this case the default scanning direction was used. The output indicates that each time the cursor was positioned at an element that matched X, the spiral routine was tried. Example 2 This example looks for a block letter M composed of the string 'M'. ABREAK is used to find the first occurrence of 'M' in the subject. This is assumed to be the upper left hand cor- ner of the block M. The routine SET partitions the subject array so that the largest block M is found. SET scans the array to the right until it finds another M. It assumes this M is the upper right hand corner of the block M. Then SET scans down from the original M until it finds some element that is not an M. SET assumes that the position above this character is the bottom of the block M. Then the cursor is positioned at this M. (the lower left hand corner of the block M) SCAN specifies the new scanning direction. ASPAN now uses this direction to 59 follow the shape of M. ASPAN must match everything up to the lower right hand corner of the block M. This condition is checked by calling APOS . The routine UNSET removes the parti- tion created by SET. This example was tried on an array that looked like this : OMOOOOOM OMMOOOMM OMOMOMOM OMOOMOOM After this was successful, ARR<4,2> was changed so that the sub- ject array no longer had the shape of an M. The output correctly shows the steps the program took before failing. 60 1 2 3 4 5 6 7 a 9 10 LI 12 13 14 15 16 17 18 19 20 23 26 29 32 33 34 3b 36 37 38 39 40 THIS PROGRAM TRIES TO MATCH A BLOCK LETTER M. IT ASSUME THAT WHEN IT FINOS AN M IN THE SUBJECT ARRAY THAT IT IS THE UPPER LEFT HAND CORNER OF THE BLOCK LETTER M. THEN IT FOLLOWS THE SHAPE OF THE M BY THE SCANNING DIRECTION FOR M, *** * * *** ♦ • A ♦ •A ♦ • *** * *** AMA UP AMI HER {.DUMP = DEFINE! DEF INE( DEF INE< DEF INE( DEF INE( DEFINE( DEFINE( DEFINE! DEFINE! DEF INE( DEF INE( •OLII ,OL DEF INE( DEFINE! DEFINE! DEFINE! DEFINE OPSYNC ARR = AR ARR<1 ,2 ARR<4,2 ARR<4,5 ARR<1 ,8 ARR<4,8 ******** AMATCH! ESUB! )• EPAT! PA ALTERN! POSPAT! SUBPOS! SCAN! X, INCR! I) NEX(X,I AS1ZE(A REC (AJ, J»AL) ») ASPANIC ABREAK! APOS! I, SET! ) •) •UNSET! &• , ■ AMAT •4,8 •M» •M» •M' •M» •M« SUB, PAT) • ) ) T) • ) M ) ) • > )• ) N,M) ■ ) •) ,J.PI' ) IIiPM CI,MAXA,MAXC,STA,STC,PAT,STI , ST J ,OL A ,OLC , • ) ■ ) C) »| J)» ) ) » > CH« ,2) • ) t i » RAY! > = > = > = > = > = *************************************************»; ARR<2, ARR<2t ARR<3, ARR<2, 2> = »M' 3> = 'M» 6> = »M» 8> = •M 1 ARR<3,2> = 'M» ARR<3 f 4> = 'M 1 ARR<2,7> = 'M 1 ARR<3,8> = "M* THIS IS THE TEST **************** OUTPUT = ! ARR BREAK("M») 31 SE 31 UNSET! ) • ) ■ ARR<4,2> = OUTPUT = (ARR & BREAKCM") ai SE ai UNSET!) • ) ■ **************** ROUTINE AMATCH **************** TCH ESUB!) : EO(MATCH, I) EPATIPAT ) ALTERN! ) E POSPAT!) ************ L TO ai SCAN! MATCH1* TO ai SCAN! MATCH2 1 ************ ******************************<» 4,N2,M1) ai ASPAN!"M W )» 4,N2,M1) ai ASPAN( M M")» :( END) ******************************' DO THE PATTERN MATCH ****************************************** ' F(FRETURN) :S(RETURN) :F!FRETURN) :F(FRETURN) :F( AMH) 61 41 EQ(MATCH,l) :S(RETURN) 42 CK = EQ(CK, 1) :S(AM) 43 SUBPOSO :F(AMHI 44 AM SJ = SUB 45 LINT = 46 OUTPUT = • SJ' SJ 'S' S 47 SJ POS(O) S RPOS(O) :S(HERE) * TRY ANOTHER ALTERNATIVE * 48 AMH CURI = STI 49 CURJ = STJ 50 SJ = DATATYPE<$($< 'CON' CI))) 51 SJ 'ARRAY 1 :F(AAM) * * UNDO PARTITION 52 Ml = STI ; M2 = ST2 ; Nl = ST3 ; N2 = ST4 56 AAM AJ = AJ ♦ 1 57 SCAM 1,N1,M1) 58 GT(AJ,MAXA) :F(AM2) * * TRY ANOTHER POSITION IN SUBJECT * 59 AJ = STA ; BEGALT = 1 61 SUBPOS( ) :F(FRETURN) 62 AM2 ALTERNO :F(FRETURN> 63 BEGALT = 64 POSPATU :F(AMH) 65 EQ(MATCH,1) : S( RETURN) F ( AM ) ******************************************* ********************* * * SUBJECT EVALUATION IS SUBJECT AN ARRAY? * INITIALIZE VARIABLES **************************************************************** 66 ESUB INT = ; STA = 1 ; STC = 1 ; FLAG = 70 LINT =1 ; CK = ; MATCH = ; ALE = '1 » 74 S = DATATYPE(SUB) 75 OUTPUT = • DATATYPE OF SUBJECT, • S 76 SI = 'STRING* I 'INTEGER* I 'REAL' 77 S SI :F(EVS) * * SUBJECT IS STRING * 78 PAT • 32 ' :S(FRETURN) 79 EV1 PAT '31' = • • :S(EV1) 80 EV2 PAT • A| • = ' I ' : SCEV2) 81 PAT = $(PAT) 82 SUB PAT :F(FRETURNI 83 MATCH = 1 MRETURN) 84 EVS S 'ARRAY' :F(FRETURN) * * SUBJECT IS OK * 85 ASIZE(SUB) :F(FRETURN) 62 86 SCAN! ltNlfHll :F(FRETURN) 87 NEDI = 88 NEDJ ■ 89 CUR I = ORGN 90 CURJ = ORGM 91 STI = CURI ; STJ = CURJ MRETURN) *************************** ****** ****** ****** ****************** * * EVALUATE PATTERN * PUT ALL ALTERNATIVES IN QUEUE * *************************************************************** 93 EPAT AJ = STA ; A = 93 PLOOP PAT POS(A) BAL . SMALT' AJ) ■ A| • * *INCR(.AJ) a)A :S(PLOOP) 96 PAT POS(A) BAL . SMALT* AJ) RPOS(O) :F(FRETURN) 97 MAXA = AJ 98 AJ = STA 99 FIN = 1 :(RETURN) **************************************************************] * * GET NEW ALTERNATIVE * PUT ALL PARTS TO BE CONCATENATED IN QUEUE * LABEL EACH ONE * ****** ********************************************************J 100 ALTERN CI = STC ; A = ; BEGALT = 1 ; INCI = 104 INCJ = 105 FIN = 1 106 LOOP $(«ALT» AJ) POS(A) BAL . S(»CON» CI) • 3' (»1 • . QI I * f 2 • . QI) aA :S(ATT) 107 $<»ALT» AJ) POS(A) BAL • S(»CON» CI) RPOS(O) :F(FRETURN) 108 $(»CON« CI) = ALE S(»CON» CI) 109 OUTPUT = ■ CONCI • $( •CON* CI) 110 MAXC = CI 111 CI = STC - 1 :(RETURN) 112 ATT SCCON* CI) = QI S(»CON» CI) 113 INCR(.CI) :(LOOP) ************************************************************** ■ * * GET POSITION IN PATTERN * THE WORKHORSE. TEST IF DONE. IF NOT, THEN GET NEXT * PIECE TO BE CONCATENATED AND FIND THE CORRECT NEEDLE * POSITION * *************************************************************** 114 POSPAT EQ(FIN,0) :S(POSP) 115 CURI = STI ♦ INCI ; CURJ = STJ ♦ INCJ 117 CK = 1 118 ICI CI - CI ♦ 1 ; STPART = 1 120 FIN = 121 GT(CI.MAXC) :F(P0SP0) 122 MATCH = 1 : (RETURN) * * NEW PIECE IS FOUND * 63 123 POSPO $('CON' CI) LEN(2) . AL = 124 AL = TRIM(AL) 125 $('CON» CI) POS(O) •( • :F(POSP) * * PARENTHESES AROUND PIECE. DO RECURSION. FIRST INITIALIZE 126 RAT = $('CON' CI) ; RAT POS(O) '( • = 128 RAT • )• RPOS(O) = 129 OLA = STA ; OLC = STC ; STA = MAXA ♦ 1 132 STC = MAXC ♦ 1 133 OLII = INCI ; OLIJ = INCJ ; ALE = AL • • 136 REC(AJ,CItMAXA,MAXC,STA f STC,RAT,STI , S T J ,OLA ,OLC ,OLI I , OL I J , AL ) «• :F(REST) 137 RESET INCI = INCI ♦ OLII ; INCJ = INCJ * OLIJ 139 STA = OLA *, STC = OLC ; MATCH = ; FIN = 1 143 FLAG = EQ(FLAGtl) : S( FRETURN) F ( POSP AT ) 144 REST FLAG = 1 : (RESET) * NO PARENTHESES. LOOK FOR SCAN * 145 POSP $('CON' CI) ('SCAN* BREAM') 1 ) •)•) . F :F(PP> 146 INT = EQ(LINT,1) 1 147 EVAL(F) :F(PT) 148 FIN = EQ(LINT,0) I :S(POSPAT) 149 LINT = » CURI = ORGN ; CURJ = ORGM 152 STI = CURI ; STJ = CURJ :(ICI) 154 PT INT =0 :( FRETURN) * * SEE IF PIECE IS FUNCTION * 155 PP $( 'CON' CI ) ■(■ :S(PIX) 156 DS = DATATYPE<$<$( 'CON* CI))) 157 OUTPUT = ■ DATATYPE OF CONCI ■ DS 158 DS 'STRING* I 'INTEGER* I 'REAL' \ 'PATTERN' :S(PP1) 159 DS 'ARRAY' :S(PP2) * * DO FUNCTION CALL * 160 PIX S = $( 'CON' CI) 161 EVAL(S) :F(FRETURN) 162 FIN = 1 r(POSPAT) * PIECE IS STRING 163 PP1 S = $($( 'CON' CI) ) 164 FIN = 1 ; EQ(AL,2) :S(PPP1) 166 INCJ = INCJ ♦ 1 :(RETURN) 167 PPP1 INCI = INCI ♦ 1 MRETURN) # * PATTERN IS ARRAY 168 PP2 EQ(STPART,l) :F(PP3) * PARTITION SUBJECT 169 STPART ■ en 170 NEXIXXX, .NEDI ,.NEDJ, 1 > : F < FRET URN ) S ( PP : S( RETURN )F ( F RE TURN ) * * WE HAVE FINISHED THIS PIECE * 183 PP5 FIN = 1 ; EQ(AL,2> :F(PP6) 185 INCI = INCI «■ N2 - Nl *■ 1 :(PP7) 186 PP6 INCJ = M2 - Ml f 1 f INCJ 187 PP7 Ml = ST1 ; M2 = ST2 ; Nl = ST3 ; N2 = ST4 MPOSPAT * GET POSITION IN SUBJECT * ****************************** 191 SUBPOS EQ(INT,1) :F(SBP) * * FIRST TIME HERE. CURSOR AT ORIGIN * 192 CUR I = ORGN ; CURJ = ORGM ; INT = 195 EQ(BEGALT,n :F(RETURN) 196 STI = CURI ; STJ = CURJ ; BEGALT = MRETURN) * * MOVE CURSOR IN ARRAY * 199 SBP ANC = ^ANCHOR ; EQ(ANC,1) :S(FRETURN) 201 NEXIXXX,. CURI ». CURJ, 0) :F(FRETURN» 202 EQ(BEGALT,1» :F(RETURN) 203 STI = CURI ; STJ = CURJ ; BEGALT = MRETURN) ***************************************************************> * SET SCANNING DIRECTION ******* ** ******************************************** ********** 206 SCAN XXX = X 207 ORGM = M ; ORGN = N 209 SCI GT(M,M2) :S(FRETURN) ; GT(N,N2> :S(FRETURN) 211 LT(M,M1) :S(FRETURN) ; LT(N,N1) : S ( FRETURN ) F< RETUR N) *************************************************************** * * AN AID IN SETTING QUEUE * *************************************************************** 213 INCR $1 = $1 ♦ 1 MRETURN) *************************************************************** * 65 * GETS NEXT POSITION DEFAULT NEX IS NEX1 ♦*******************<^***************** ************************* 214 NEX :($( *NEX* X) ) 215 NEX1 EQ(P,1) :S(NX) * NO PARTITION 216 $J = $J ♦ 1 ; GT($J,M2) :F(RETURN) 218 JJ = Ml ; SI ■ $1 ♦ 1 ; GT(SI,N2) : S ( FRETURN ) F (RETURN ) * START PARTITION * 221 NX ST1 = Ml ; ST2 = M2 ; ST3 = Nl ; ST4 = N2 225 ASIZE($($( •CON 1 CI)>) :F(FRETURN) 226 SZI = N2 - Ni ; SZJ = M2 - Ml 228 SI = Nl ; $J = Ml 230 Nl = CURI ; N2 = CURI ♦ SZI ; Ml = CURJ ; M2 = CURJ ♦ SZJ 234 LT(N1,ST3) :S(FRETURN) ; GT(N2,ST4) :S(FRETURN) 236 LT(M1 V ST1) :S(FRETURN) ; GT(M2,ST2) : S( FRETURN ) F( RETURN ) **************************************************************** * A VERY USEFUL ROUTINE. GIVES UPPER AND LOWER BOUNDS OF ARRAY * UPPER AND LOWER BOUNDS OF FIRST SUBSCRIPT IN N2 AND Nl * UPPER AND LOWER BOUNDS OF SECOND SUBSCRIPT IN M2 AND Ml * **************************************************************** 238 ASIZE S = DATATYPECA) 239 S •ARRAY 1 :F(L5) 240 AP = PROTOTYPE(A) 241 1=2 * LOOK FOR N * 242 AP BREAM***) . N •*• REM . M :S(L1I * IF FAIL THEN A IS ONE DIMENSIONAL * 243 1=1 244 N = AP 245 Ml = 1 ; M2 = 1 247 LI N BREAM*:*) . Nl •:• REM . N2 :S(L2) 248 Nl = 1 ; N2 = N 250 L2 Nl = Nl 4- ; N2 = N2 ♦ ; EQ(I*1) :S(RETURN) ♦ * GET M * 253 M BREAM*:*) . Ml •:• REM . M2 :S(L6) 254 Ml = 1 ; M2 = M 256 L6 Ml = Ml ♦ ; M2 = M2 ♦ : (RETURN) 258 L5 P = 'STRING* | 'INTEGER* I 'REAL* 259 S P :F(FRETURN) * * SUBJECT IS A STRING, STRING I S 1 BY 1 260 Nl = 1 ; N2 = 1 ; Ml = 1 ; M2 = 1 :(RETURN) 66 2 64 265 266 267 268 269 270 271 2 72 273 274 276 277 278 282 2 84 285 287 288 289 291 293 295 297 299 301 3 03 305 307 310 311 312 313 314 317 318 **************************************************************„ * * PARENTHESES IN PATTERN. DO AMATCH AGAIN ONLY 00N' T * MOVE CURSOR IN SUBJECT IF FAIL * *************************************************************** REC EPAT(PAT) :F(FRETURN) ALTERN( ) :F(FRETURN) LAB POSPATU :F(LOB) EQ(MATCH ? 1) :S(RETURN> CK = EQ(CKtl) :S(RLAB> SUBPOSO :F(LOB> RLAB SJ = SUB LINT = OUTPUT = • SJ • SJ • S • S SJ POS(O) S RPOS(O) :S(LAB) * * TRY ANOTHER ALTERNATIVE * LOB CUR I = ST I ; CUR J = ST J SJ = DATATYPE! $($< «CON» CI))) SJ 'ARRAY* :F(ROB> Mi = ST1 ; M2 = ST2 ; NL = ST3 ; N2 = ST4 ROB AJ = AJ ♦ 1 ; GT(AJ,MAXA) :S(FRETURN) ALTERNI ) :F (FRETURN) BEGALT = ; POSPATO :F(LOB) EQ(MATCH,1) :S(RETURN)F(RLAB) ******************************* ****************************** * * THIS IS THE SCANNING DIRECTION FOR M ************************************************************* NEX4 MSI'MX 1 PTR)) MXO $1 = $1 - 1 ; LT($I,N1) :F(RETURN) INCR(.PTR) ; $1 = $1 ♦ 1 MX1 $1 = $1 ♦ 1 ; GT($I,N2) :S(MXX) $J = $J + 1 ; GT($J,M2) :S(FRETURN)F(RETURN) MXX INCR(.PTR) ; $1 = $1 - 1 MX2 $1 = $1 - 1 ; LT($I,N1) :S(MXM) $J = $J ♦ 1 ; GT($J,M2) :S(FRETURN)F(RETURN) MXM INCR(.PTR) ; $ I = $1 ♦ 1 MX3 $1 = $1 + 1 ; GT($I,N2) : F( RE TURN ) S (FRETURN) *************************************************************** * LIKE SPAN. CONTINUES IN SUBJECT AS LONG SUBJECT POSITION * MATCHES ARGUMENT * *************************************************************** ASPAN 11=0 ; TEMPI = CURI ; TEMPJ = CURJ ASPNL SJ = SUB LINT = OUTPUT = • LOOP THRU ASPAN 1 SJ C :F(ASPF) 11=1 ; OLDI = CURI ; OLDJ = CURJ NEX( XXX, .CURI ,.CURJ f 0) : S( ASPNL )F( ASPF) ASPF EQ(II,0) :S(FRETURN) 67 319 CURI = OLDI ; CURJ = OLOJ ; TEMPI = CUR I - TEMPI 322 TEMPJ = CURJ - TEMPJ ; INCI = I NC I •*• TEMPI 324 INCJ = INCJ ♦ TEMPJ : (RETURN) **************************************************************** * * ABREAK ACTS LIKE BREAK. IT MATCHES UP TO THE SUBJECT * ELEMENT THAT MATCHES THE ARGUMENT. IT MUST MATCH ONE ELEMENT * **************************************************************** 325 ABREAK 11=0 ; TEMPI = CURI ; TEMPJ = CURJ 328 ABLP SJ = SUB ; LINT =0 ; SJ C :S(ABRK) 331 11=1 ; OLOI = CURI ; OLDJ = CURJ 334 NEX(XXX, . CURI ,. CURJ, 0) : F( FRETURN) S ( ABLP ) 335 ABRK EQ(II,0) :S(FRETURN) 336 CURI = OLOI ; CURJ = OLDJ ; TEMPI = CURI - TEMPI 339 TEMPJ = CURJ - TEMPJ ; INCI = INCI ♦ TEMPI 341 INCJ = INCJ ♦• TEMPJ : (RETURN) **************************************************************** * * TESTS IF CURSOR IS AT ARGUMENTS *************************************** ************************* 342 APOS IDENTU ,CURI) :F(FRETURN) 343 IOENT( J, CURJ) : F ( FRETURN) S( RETURN ) **************************************************************** * ROUTINE TO START M **************************************************************** 344 SET PTR = ; TOLI = CURI ; TOLJ = CURJ 347 NEX(XXX,. CURI,. CURJ, 0) :F(FRETURN) 348 INCI = INCI * CURI - TOLI 349 INCJ = INCJ ♦ CURJ - TOLJ 350 TOLI = CURI 351 ST1 = Ml ; ST2 = M2 ; ST3 = Nl ; ST4 = N2 355 Ml = CURJ ; Nl = CURI 357 TOMI = Ml 358 NXLP TOMI = TOMI ♦ 1 ; GT(T0MI,ST2) :S(FRETURN) 160 STP = SUB ; STP »M« :F(NXLP) 362 M2 = TOMI 163 TOMI = Nl 164 MXLP TOMI = TOMI ♦ 1 ; GT(T0MI,ST4) :S(MXDI) 366 STP = SUB; STP • M» :S(MXLP) 168 MXDI TOMI = TOMI - 1 169 MXD N2 = TOMI ; CURI = N2 »71 INCI = INCI ♦ CURI - TOLI : (RETURN) **************************************************************** * RESETS THE UPPER AND LOWER LIMITS OF SUBJECT ARRAY **************************************************************** •72 UNSET APOS(N2,M2) :S(UN2) 73 Ml = ST1 ; M2 = ST2 ; Nl = ST3 ; N2 = ST4 KFRETURN) 77 UN2 Ml = ST1 ; M2 = ST2 ; Nl = ST3 ; N2 = ST4 t(RETURN) 81 END DATAT CUNC I LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP MATCH DATAT CONCI LOOP LOOP LOOP LOOP LOOP LOOP CONCI CONCI CONCI CONCI CONCI CONCI CONCI CONCI CONCI CONC I YPE OF 1 UNS THRO A THRO THRO THRO THRO THRO THRO THRO THRO THRO THRO THRO THRO 1 YPE OF 1 ONS THRO A THRO THRO THRO THRO THRO 1 1 ONS ONS ONS ONS ONS ONS ONS ONS ONS ONS SOBJECT, ET( ) SPAN SPAN SPAN SPAN SPAN SPAN SPAN SPAN SPAN SPAN SPAN SPAN SPAN SOBJECT, ET( ) SPAN SPAN SPAN SPAN SPAN SPAN ETO ETC > ET( I ET( ) ET( ) ETO ETO ET( ) ET( ) ET( ) ARRAY 68 ARRAY 69 1 l 3 5 6 7 H 9 U 11 12 13 1<* 15 16 17 IP 19 11 25 28 29 30 31 32 33 34 35 36 *** * * *** ****************************************** + ;**$**$.***$$$$£$$$£ THIS PROGRAM TESTS FOR THE SHAPE UF A SPIRAL. T BY FIRST SCANNING FUR AN X. WHEN THIS IS FUUNDt ASSUMED TO BE THE BEGINNING OF A SPIRAL. THE SP LEAST COME BACK AROUND TO THE BEGINNING AGAIN. DIRECTION FOLLOWS THE SHAPE OF A SPIRAL. HIS IS DONE IT IS IRAL MUST AT THE SCANNING *** * * *** ♦ • A *** * * *** AMA UP AMI HER **** DEF DEF DEF DEF DEF DEF DEF DEF DEF DEF DEF • OLI DEF DEF DEF DEF Dt OPS ARR ARR ARR AKR ARR PTR **** **** INE( INE( INE( INE( INE( INE( INE( INE( INE( INF( INE( ItOL INE( INE( INE( INE( FINE YN( » = A <2,1 <2,4 <4,<+ <5,3 = I **** ***************************************************** AMATCH( SUB» PAT ) • ) ESUB( »» ) EPATtPAT ) • » ALTERN( ) • ) POSPATl ) • ) SUBPOS( > ') SCAN( X,N,M) • ) INCR< DM NEX(X ,IfJ»P)'l ASIZE(A) I,P« | REC(AJ,CI ,MAXA,MAXC,STA f STC,PAT ,S T I , ST J ,OL A , OLC , • J,AL) M ASPANiC »• ) ABREAM C) ' ) APOS( I, J) • ) TEST! )• ) { 'SET( M ) L* ,' AMATCH* ,Z) RRAY( • 6, 5' , • X' ) > = ; ARR<2,2> = > = ; ARR<3,4> = > = ; ARR<5,2> = > = ARR<2,3> = ARR<4,2> = ARR<5,4> = ***************************************************** THIS IS THE TEST ************* ************************************************: OUTPUT = ( ARR I BRFAKC'X") 91 SETU If (AMH) 5J ■ SU4 LINT = HJIPUT = ' SJ' SJ 'S 1 S SJ PnS(O) S RPDS(U) :S(HtRL> n 38 ) . AM 40 •♦1 • 43 *MH CUK I = ST I 44 CURJ = SI J 45 SJ - UATMYPt U ($( •CON' CIIII SJ 'ARRAY' :f-(AAM) * UM)il PARTITION 1! 92 MAXA = AJ 91 AJ = STA 94 F IN = 1 : (RbTURN) * GET NEW ALTERNATIVE * PUT ALL PAPTS TG BE CONCATENATED IN QUEUE * LABEL EACH ONE 95 ALTERN CI = STC ; A = ; BEGALT ■ 1 ; I NC I = 99 INC J = 100 FIN = 1 101 LOOP $<»ALT« AJ) POS(A) BAL . $('CUN* CI) ' a)' ('1 • . QI | * '2 • . QI) a A :S(ATT) 1J2 $('ALT' AJ ) POS(A) BAL . $('CGN» CI) RPOSIO) :F(FRETURN) 103 $('CGN' CI) = ALE $(»CGN' CI) 10* OUTPUT = • CONC I ' $('CGN' CI) 105 MAXC = CI 106 CI = STC - 1 MRETURN) 107 ATT $<«CON' CI) = QI $('CON« CI) 109 INC R (.CI) :(LOf)P) 109 110 IU .13 115 116 117 ill * GET POSITION IN PATTERN * THE WORKHORSE. TEST IF DONE. IF NOT, THlN GET NEXT * PIECE TG BE CONCATENATED AND FIND THE CORRECT NEEDLE * POSITION * *******$************$*4 ***$**$****$$**$**** ********************* POSPAT EQ(FIN,0) :S(POSP) CURI = STI ♦ INC I ; CURJ = STJ ♦ 1NCJ CK = 1 1CI C I = CI ♦ 1 ; STPART = 1 FIN = GT(CI,*AXC) :F(POSPO) MATCH * 1 : (RETURN) * NEW PIECE IS FOUND POSPO $(«CON« CI) LEN(2) . AL = 72 11 9 121 123 12* 127 124 131 132 13a 139 140 141 U2 143 144 1*7 1*^ 150 151 15^ 153 I 5* 155 156 157 15o 159 161 162 163 16* 165 AL ■ TRIM(AL) *( 'CON' CI I PUS(O) M • :F( POSP) PARENTULSLS AROUND PIECE. DO RECURSION. Fl^ST INITIALIZE RAT POS(O) M ■ ■ HAT = t ( ' CON' C I ) RAT ' I ' RPOSIO > = OLA = STA ; ULC ■ STC ; STA * MAXA «- 1 STC = M AXC 4- l ilLH = INCI ; OLIJ = INCJ ; ALE = AL ' ' REC (A J, CI , "AXA, MAXC ,STA,STC,RAT,Sri,STj,GLA f OLC,JLII, f :F(KtST > RESET I NCI = IMC I ♦ OLII ; INCJ = INCJ ♦ OL IJ STA = Gl A ; STC = OLC ; MATCH = ; FIN = 1 FLAG = EQ(FLAGtl) : S< FRETURN > F ( P SP AT ) REST FLAG = 1 : (RESET) * NO PARENTHEShS. LOOK FOR SCAN POSP $('CGN» CI) ('SCAN' BRtAKO'l ')') . F :F(PP) INT = EOILINT ,1 ) 1 EVAL( F I :F (RT > FIN = EO(LINT,0) 1 :S(PGSPAT> LINT = ; COkl = ORGN ; CURJ = GRGM STI = CURT ; STJ = CURJ : ( ICI ) PT INT = : ( FKETURN) * Sf E IF PIFCE I S FUNCTION p P S ( • CON • CI) •(• :S(PIX) DS = DATATYPE! $( $( 'CON' CI))) OUTPUT = ■ DATATYPE OF CGNCI » DS DS 'STRlNb' I 'INTEGER' I 'REAL' I 'PATTERN 1 :S(RP1) DS 'ARRAY' :S(PP2) * * DO FUNCT IGN CALL * PIX S = $( »CiJN« C I > f VAL ( S) :F( FRET URN) FIN a 1 : ( PGSPAT ) * PIECE IS STRING PP1 S = $ ($ ( 'CUN' CI) ) F IN = i ; t(j( AL,2) :S( PPP1 ) INCJ = INCJ * 1 MRETURN) PPP1 INCI = I NCI + 1 MRETURN) * * PATTERN IS ARRAY p P2 EOISTPARTtl) :F(RP3) ♦ PARTITION SUBJECT STPART = NfcX( XXX, .NEDI ,.NEDJ ,1 ) :F( F RETURN! SIPP4) 73 ro '2 "l * SUBJECT ALREADY PARTITIONED * PP3 THP1 = Ml ; THP2 = M2 ; THP3 = Nl ; THP4 = N2 ASI ZE($($( »CON' CI))) NFXtXXX, .NEOI ,.NEDJ,0) :F(PP5) **l = THP1 ; M2 = THP2 ; Nl = THP3 ; N2 = THP4 * * PATTERN TO BE MATCHED IN S * PP4 DS = $($( •CON* CI) ) S = DS : S ( RETURN > F ( F RETURN ) * *E HAVE FINISHED THIS PIECE 110 11 12 16 17 10 11 14 16 I 7 Id PP6 FIN = 1 ; EU(AL,2) :F(PP6) I NCI = I NCI «■ N2 - Nl ♦ 1 :(PP7) PP6 INCJ * M2 - Ml ♦ 1 ♦ INCJ PP7 Ml = Sri ; M2 = ST2 ; Nl = ST3 ; N2 = ST4 MPOSPAT) **************************************************************** * GET POSITION IN SUBJECT **************************************************************:«<* SUrtPOS EQ( INT, I) :F( SBP) * ♦ FIRST TIME HERE. CURSOK AT ORIGIN CURI = ORGN ; CURJ = ORGM ; INT = EQ(BEGALT,1) :F(RETURN) STI = CURI ; STJ = CU4J ; BEGALT = MOVE CURSOR IN ARRAY (RETURN) 12 * * SBP ANC = &ANCHOR ; EO(ANC,l) :S(FRETURN) NEX(XXX,.CURI t.CURJtO) :F( FRET URN) EQ(BEGALT,1) :F(RETURN) STI = CURI ; STJ = CURJ ; BEGALT = : (RETURN) **************************************************************** * * SET SCANNING DIRECTICN **************************************************************** SCAN XXX = X ORGM = M ; ORGN = N SCI GT(M,M2) :S(FRETURN) ; GT(N,N2) :S(FRETURN) LT(M,Ml) :S(FRETURN) ; LT(N,N1) : S (F RETURN ) F ( R ETUR N ) **************************************************************** * AN A ID IN SETT ING QUEUE * **************************************************************** INCR $1 = $1 ♦ 1 '.(RETURN) *********************************** ********************** ******* * * GETS NEXT POSITION DEFAULT NEX IS NEX1 n ,j \ 211 21 i 21o iz^ 221 223 2 2 ; » 2 2 < 2 51 233 234 2 it> 236 237 23o 2 39 240 242 243 24^ 2fi 25 A 2S3 2')4 2^5 ME X : <$< 'NEX' X) ) Mt XI EQ(P, 1 > : S(NX ) * * NO PART I HON $J = iJ *■ 1 ; GT($J.M2) :F(RETURN) J.J = Ml ; $1 = 41 ♦ l ; GT(SI,N2) : S( FRE TURN ) F ( KE TURN ) v ST ART PART IT IUN * NX ST1 = Ml : ST2 = M2 : ST3 = Nl ; ST4 = HZ ASl/FI $< $( •CON* C I ) ) > :F(FRETURN) SZI = N2 - Nl ; SZJ = M2 - Ml SI = Nl ; $J = Ml Jl = FORI ; N2 = CURI ♦ SZI ; Ml = CURJ ; M2 = CURJ LT(N1,ST3) :S(FRETURN) ; GT(N2,ST4> :S(FkETURN) LT(Mi f STl) :S(FRETURN> ; GT(M2tST2l : S ( FRE TURN ) F ( RETURN I «:*«*****»**********)»:*****iJc^*»******#**V **************** ********* * A VERY USEFUL ROUTINE. GIVES UPPER Ai>JD LOwER BOUNDS OF AR * UPPER AND LOWER BOUNDS OF FIRST SUBSCRIPT IN N2 AND Nl * UPPlR AND LOWER BOUNDS OF StCON!) SUBSCRIPT IN M2 AND Ml * AS I ZE S = DATATYPE! A) S 'ARRAY* :F(L5) AP = PROTOTYPE! A ) I = 2 LI L2 * LOOK FOR N AP BREAK! • ,' ) . N ' t ' REM . M IF FAIL THEN A IS ONE DIMENSIONAL :S ( L 1 » I = 1 N = AP Ml = 1 ; N BREAK! • : Nl = 1 ; Nl = Ni *■ GET M N2 :S(L2> M2 = 1 • ) . Nl ' : » REM N2 = N ; N2 = N2 ♦ ; EQ(Irl) :S(RETURN) M BREAK!':') . Ml •:• REM . M2 :S(L6) Ml = 1 ; M2 = M 1.6 Ml » Ml «- ; M2 = M2 ♦ : (RETURN) L5 P = 'STRING' | 'INTEGER' | 'REAL* S P :F(FRETURN) * SUBJECT IS A STRING. STRING I S 1 BY 1 Nl=l ; N2 = l ; Ml = I ; M2=l :( RE TURN) 75 * PARENTHESES IN PATTERN. DO AMATCH AGAIN ONLY DON'T * MOVE CURSOR IN SUBJECT IF FAIL * **************************************************************** 25-> REC EPAT(PAT) :F(FRETURN) 260 ALTERN() :F(FKETURN) 261 LAM POSPATO :F(LOB) 262 FO(MATCH,l) :S(RETURN) 263 CK = EU(CK,1) :S(HLAB) 264 SUBPOS() :F(LOB) 265 RLAB SJ = SOB 260 LINT = Zbf OUTPUT = • SJ • SJ • S • S 268 SJ POS(O) S RPDS(O) :S(LAB) * * TRY ANOTHER ALTFRNATIVt 2b9 LOB CUR I = ST I ; CUR J = ST J 271 5J = DATATYPE! $($( 'CON' CI))) 27? SJ 'ARRAY' :F(ROB) 273 Ml = ST1 ; M2 = ST? ; Nl = ST3 ; N2 - ST4 277 ROB AJ = AJ + 1 ; GT(AJ,MAXA) :S(FRETURN) 279 ALTERN( ) :F (FPETURN) 280 BEGALT = ; POSPATU :F(LOB) 202 EU(MATCH,1) :b(RETURN)F(RLAB) ********************************** V**** ** ******** ****** ********* * * LIKE SPAN. CONTINUES IN SUBJECT AS LUNG SUBJECT POSITION * MATCHES ARGUMENT * **************************************************************** ^8? ASPAN 11=0 ; TEMPI = CURI ; TEMPJ = CURJ 2dt> ASPNL SJ = SUB 287 LINT = 288 OUTPUT = » LOuP THRU ASPAN' 28? SJ C :F(ASPF) 2^0 11 = 1 ; OLD I = CURI ; OLDJ = CURJ 2-^j NEX( XXX, .CURI ,. CURJ ,0) : S ( AS PNL ) F ( AS PF ) 294 ASPF EQ(I1»0) :S(FRETURN) ; LINT =0 ; SJ C :S(ABRK) >07 11=1 ; 0L01 = CURI ; OLDJ = CURJ 310 NEX( XXX, .CURI ,.CUR J,0) : F ( F RETURN) S ( ABLP ) 311 AciKK FO ( 11,0) :S(FRETURN) 312 CURI = OLDI ; CORJ = OLfiJ ; TEMPI = CURI - TEMPI 31b TPMPJ = CURJ - TFMPJ ; INCI = INCI ♦ TEMPI 76 317 INC J = INC J ♦ TEMP J ! (RETURN! ******************************************* ********************* MSTS IF CURSO IS AT ARGUMENTS *********************** ****************************** *********** jln APOS IDENT ( I ,CUKI ) :F(FRETIJRN) iW IDENTC JiCURJI : F < FRE TURN) SI RETURN ) **************************************************************** * THIS IS THE DIRECTION FOR SPIRAL **<-■ ************************************************************* NFX9 EQ(INTNX,1) :F(NX9X) nni = $l ; NN2 = $1 ; mmi = SJ ; MM2 = $j INTNX = 2 :(RFTURN) NX9X EQ(INTNX,2) :F(NX9Y) NNI = NNI - 1 ; $1 = $1 - 1 ; LT(NNltNl) :S(FRETURN> PTR - 2 ; MM1 = MM1 - 2 ; LT(MM1,M1I :SIFRETURN) INTNX = INTNX ♦ 1 :( RETURN) NX«Y : ( $( 'NX9* PTP ) ) NX91 $1 = $1 - 1 ; LT($I,NN1) :F( RETURN J INTNX = INTNX + 1 $1 = $1 ♦ 1 ; PTR =2 ; MML = MMI - 2 LT(MM1,M1) rSIFRETURN) NX92 $J = $J - 1 ; LT($J,MMl) :F(RET'JRN> INTNX = INTNX ♦ 1 iJ = $J + 1 ; PTR = 3 ; NN2 = NN2 ♦ 2 GT(NN2,N2) :S(FRETURN) MX93 $1 = $1 + 1 ; GT($i,NN2) :F(RETURN) INTNX = INTNX ♦ 1 SI = $1 - 1 ; PTR = 4 ; MM2 = *M2 ♦ 2 GT(MM2,M2) :S(FRETURN) MX94 $J = $J + 1 ; GT(SJ,MM2) :F(RETUPN> INTNX = INTNX + 1 $J = $J - 1 ; PTK = 1 ; NNI = NNI - 2 LT(NN1,N1) :S(FPETURN)F(NX91) * * ROUTINE TO START SPIRAL * SET INTNX = 1 ; TULI = CURI ; TOLJ = CURJ NEX(XXX,.CURI , .CUPJiO) :F(FRETURN) INCI = INCI ♦ CURI - TOLI INCJ = INCJ «• CUkJ - TOLJ : (RETURN) **************************************************************** * * THIS TEST TELLS IF THE SPIRAL THAT HAS BEEN FOUND IS * LARGE ENOUGH *************************************** ************************* 369 TEST GT(INTNX,5) : F ( FR ETURN ) S ( RE TURN ) 3 70 END MO 121 325 32t> i27 3 30 J33 334 3*5 337 338 341 i<+Z 3^h 345 348 349 351 352 355 35o 358 359 363 36o 467 368 77 DATATYPE OF SUBJECT, CONC1 1 TEST( 1 TEST< 1 TESK 1 TEST( 1 TEST( 1 TEST( ASPAN ASPAN ARRAY CONCI CONCI conci CONCI CONCI LOOP LOOP LOOP LOOP LOOP LOOP THRU THRU THRU THRU THRU THRU CONCI 1 TEST( ) LOOP THRU ASPAN THRU THRU THRU THRU THRU CONCI I TEST( ) LOOP THRU ASPAN THRU THRU THRU THRU THRU CONCI 1 TES1 ( ) LOOP THRU ASPAN THRU THKU THRU THRU THRU 1 LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP LOOP ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN ASPAN LOOP LOOP LOOP LOOP LOOP CONCI CONCI CONCI CONCI CONCI LOOP THRU LOOP THRU ASPAN ASPAN ASPAN ASPAN ASPAN TEST( ) TEST{ ) TEST< ) TEST( ) TEST( ) ASPAN ASPAN LOOP THRU ASPAN LOOP THRU ASPAN CUNCI 1 TEST( ) CONCI 1 TEST( ) CONCI 1 TEST( > LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LUOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOOP THRU ASPAN LOUP THRU ASPAN 78 LOUP THRU ASPAN LOOP THKU ASPAN LOUP THKU ASPAN MATCH IBLIOCRAPHIC DATA HEET 1. Report No. UIUCDCS-R-72-5I5 3. Recipient's Accession No. 5. Report Date June, 1972 Title and Subtitle ARRAY PATTERN MATCHING Author(s) Lynne Schaber Sanford 8. Performing Organization Rept. No. Performing Organization Name and Address Department of Computer Science University of Illinois at Urbana-Champaign Urbana, Illinois 61801 10. Project/Task/Work Unit No. 11. Contract/Grant No. sponsoring Organization Name and Address Department of Computer Science University of Illinois at Urbana-Champaign Urbana, Illinois 61801 13. Type of Report & Period Covered 14. Supplementary Notes Abstracts This report extends the programming language SNOBOL to include array )attern matching. The concept is defined, and SNOBOL programs were written -erform array pattern matching. Primitive patterns and functions were lemented to help the user construct array patterns. >fv lords and Document Analysis. 17a. Descriptors array pattern matching, array patterns -entifiers/Open-Ended Terms 11 Fie Id /Group 'iity Statement limited 19. Security Class (This Report) UNCLASSIFIED 20. Security Class (This Page UNCLASSIFIED 21. No. of Pages 81 22. Price T S-S5 I 10-70) USCOMM-DC 40329-P7I ^ \Stt igflif ■ BH m I ■ i'. ■ V? ■ ■ H ,^ HB •,V M ^H m sm EBB I ■ 1 HUH HHdH EBB ^«K.wiv HNS HI BEH : i'W BH HB BBfl ■■■■ .- 01 i Hrann bb IIKSH I EBB BH His H mil IB BH ■ • *fl HE S3 BH ii fflHUBT HUB vVK HBBbbbBBbbbbH