Document not found! Please try again

Applying Techniques to Skeletons - CiteSeerX

44 downloads 841 Views 177KB Size Report
programs as enhancements of skeletons, and presenting standard Prolog ... Anyone experimenting with MIS quickly discovers that some ...... MIT Press, 1988.
Applying Techniques to Skeletons L. S. Sterling and M. Kirschenbaum

This paper concerns our research on developing a theory and methodology appropriate for systematically building complicated Prolog programs. Programs are constructed procedurally from standard components. We identify skeletons, basic Prolog programs with a well-understood control ow, and techniques, standard Prolog programming practices, as basic components. Applying a technique to a skeleton creates an extension of the skeleton. Complicated programs are built by choosing a skeleton and repeatedly applying techniques. Separate extensions of the same skeleton can be composed into a single program, simplifying the process of program development. We describe our application of skeletons and techniques within the framework of Shapiro's Model Inference System.

1.1 INTRODUCTION Stepwise re nement, as advocated by Wirth [Wir71], emerged as a methodology to develop programs in procedural programming languages to produce clear, well structured code. There is no analogous method for the systematic construction of Prolog programs. Sporadic attempts have been made over the years to automatically/systematically construct logic programs, for example [LP90, Fri90]. However, much of the e ort has been concentrated on logic and formal transformations. Our experience in teaching Prolog suggests that students do not naturally develop programs by developing and then transforming correct statements of logic. Rather, they think of programming in procedural terms. This need not con ict with the declarative ideal of logic programming if well structured programs are used. Procedural beConstructing Logic Programs, J.-M. Jacquet (editor)

c 1993 John Wiley & Sons Ltd

2

APPLYING TECHNIQUES TO SKELETONS

havior of such programs needs to be easily understood, but they should also have a clear declarative interpretation. We advocate the identi cation and use of skeletons in Prolog programming, that is basic programs with a well-understood control ow, and techniques, that is idioms of programmingpractice. Applying a technique to a skeleton yields an enhancement, that is a program created by adding extra computations, in the form of arguments, goals, and/or clauses, to a program. A special type of enhancement, called an extension, restricts the added computations to not a ect the control ow of the skeleton. Separate extensions of the same skeleton can be easily composed into a single program combining the functionalities of the individual extensions. Our current research deals primarily with the class of extensions and we do not consider more general enhancements in this paper. Underlying theory can be found in [KSJar]. Here, we implicitly make use of the theory in the way we represent techniques, compose extensions, and in presenting the material. In this paper, we give simple examples of applying techniques to a skeleton to produce extensions, and the use of composition. We argue for explaining good Prolog programs as enhancements of skeletons, and presenting standard Prolog programming practice as applying techniques. Skeletons, which often consist of nothing more than a control ow for manipulating a data structure, are to be thought of as basic building blocks for program development. This separation of control ow and technique is our key idea for structuring programming in Prolog. This paper also describes our application of skeletons and techniques to a special case of inductive learning, synthesizing Prolog programs from examples of their input/output behavior. An incremental inductive inference algorithm was developed in [Sha83] for synthesizing logic programs. Shapiro named his implementation the Model Inference System (MIS). Anyone experimenting with MIS quickly discovers that some programs are easy to learn, others can be synthesized with diculty, and others are beyond the scope of the system. The reason for the variation in performance can be traced to the re nement operator used to produce new clauses, and the search strategy employed to determine if the new clause correctly implies the examples.

1.2 SKELETONS An important stage of program development for a procedural language requires the selection of a proper data structure for storing and retrieving necessary information. We believe the corresponding rst step for program development in Prolog is to pick out a control ow or skeleton for the proposed program. The choice of skeleton is greatly in uenced by the type of data structure required and the order chosen for processing the data. There are various methods for handling recursive data structures. These methods can be naturally partitioned into several groups based on a common control ow. These control ows, which we call skeletons, constitute the basic building blocks for program development. One of Prolog's strengths is the ease of manipulating recursive data structures such as lists and trees. In particular, there are various skeletons concerned with the processing of lists, and explicit examples are restricted to this class. We would like to point out that the extraction of the proper control ow for programs needing 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

SKELETONS

3

recursive data structures is often a straightforward process. We would also like to point out that many skeletons can be understood in terms of induction schemes, for example as developed in [Dev90], a perspective not elaborated on in this paper. Through attempting to identify and classify skeletons, it has become clear that slight changes in the speci cation of a problem, such as changing the base case, leads in general to di erent skeletons. This volatile nature makes it dicult to apply program schemas [Lak89a, O'K90] to nd similarities between programs. Schemas are a general framework for a class of problems to be solved where the control ow and the techniques are indistinguishable. This forces the programmer, who wants to use schemas, to nd a particular instance of a schema that is similar to the problem being worked on. This is expecting a lot from the average programmer. We believe a better approach is to have programmers decide upon the basic control ow necessary for their application in the form of a skeleton and then, using standard techniques, enhance the skeleton to solve their particular problem. If the problem is subdivided using top-down design, it can be easy to determine a suitable control ow. Here are three skeletons which process lists. They are typical examples of skeletons for recursive data structures and they will be referred to throughout this paper. %searching a list search([X|Xs]):search(Xs). search([X|Xs]). %traversing a list simple_traverse([X|Xs]):simple_traverse(Xs). simple_traverse(Xs).

%partition traverse traverse([X|Xs],Ys):member(X,Ys),traverse(Xs,Ys). traverse([X|Xs],Ys):nonmember(X,Ys),traverse(Xs,Ys). traverse([ ],Ys).

The control ow for searching a list exempli ed by search will continue to process the list until what is being searched for has been found. The base case for traversing a list in simple traverse, in contrast, ensures that the entire list will always be processed. The third skeleton traverse, processes the entire list by partitioning the control ow into two separate branches based upon the membership of the head of the rst list with the second list. Parsers are another class of skeletons. The texts [PS87, SS86] demonstrate that any De nite Clause Grammar constitutes a skeleton parser for a particular grammar. In fact [PS87] states that `We might extend the axiomatization of the grammar and dictionary with an additional argument in certain predicates ... '. This is exactly the idea of applying techniques to skeletons, and corresponds to the approach to programming we advocate. Meta-interpreters form another class of skeletons. Indeed, the experience in [SB89] of trying to compose Prolog meta-interpreters triggered the search for a methodology for structuring program development. The well-known four clause solve meta-interpreter is a prototypical skeleton. It has been applied for program debugging and expert system shells, for example, as described in [SS86]. 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

4

APPLYING TECHNIQUES TO SKELETONS

1.3 TECHNIQUES In contrast to the characterization of skeletons in terms of control ow, techniques should be conceived in terms of the speci c goal to be accomplished. For example, the appropriate method for counting the number of elements of a list, the number of nodes in a tree, or the number of goal reductions or depth in a proof tree, is to increment an argument and carry it as a context. Standard Prolog programming practices, or techniques, like this one have the common feature that they build upon an already existing program. The result of applying a technique to a skeleton gives an extension. For example the counting technique described informally above can be applied to simple traverse to produce a program to nd the length of a list. Note that counting the number of elements of a list requires adding a di erent goal than counting the number of nodes in a binary tree. Indeed a technique may vary for each type of skeleton. Conversely various arithmetic operations could be added to the skeleton as an extra goal. For example, adding the elements of a list di ers from counting the number of elements in a list only in the arithmetic operation used in the extra goal. Our conception of techniques allows such variation. A skeleton determines both the data structure and the method of its processing. Techniques do not alter the control ow of a skeleton. In this section we present several techniques which are commonly found in the literature.



Build

It is possible to create a new data object by following the control ow of a skeleton and selectively adding appropriate data elements. An extra argument is added to the de ning predicate in the skeleton and an extra goal is added to the body to relate the constructed object from the body with the nal object in the head of the clause. We apply the build technique to the skeleton traverse to obtain both a program for union and intersection. To simplify our presentation, lists are taken as approximations of sets, and that the initial lists do not have multiple occurrences of any element. Thus union can be considered as a set union. union([X|Xs],Ys,Us):member(X,Ys), union(Xs,Ys,Us1), Us = Us1. union([X|Xs],Ys,Us):non_member(X,Ys), union(Xs,Ys,Us1), Us = [X|Us1]. union([ ],Ys,Us):Us = Ys.



intersect([X|Xs],Ys,Is):member(X,Ys), intersect(Xs,Ys,Is1), Is = [X|Is1]. intersect([X|Xs],Ys,Is):non_member(X,Ys), intersect(Xs,Ys,Is1), Is = Is1. intersect([ ],Ys,Is):Is = [ ].

Calculate

This technique is similar to the technique build. An extra argument is added to the de ning predicate in the skeleton and an extra arithmetic goal is added to the body of each recursive goal to relate the calculation from the body with the nal result in the head of the clause. For example, it is possible to nd both the length

27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

5

TECHNIQUES

of a list and the sum of the elements of a list by applying the calculate technique to the skeleton simple traverse. length([X|Xs],Len):length(Xs,Len1), Len is Len1 + 1. length([ ],Len):Len is 0.

sum([X|Xs],Sum):sum(Xs,Sum1), Sum is Sum1 + X. sum([ ],Sum):Sum is 0.

Which program is a skeleton can depend on what nal program is being constructed. Often a well-understood program developed as an extension of a simple skeleton is itself regarded as a skeleton for further development. This leads to a methodology of stepwise enhancement [Lak89b] sketched brie y in the next section. For example, we can apply calculate to the program intersect to produce an extension which also calculates the number of elements in the intersection of two lists. The program is: intersection([X|Xs],Ys,Is,Number):member(X,Ys), intersection(Xs,Ys,Is1,Number1), Is = [X|Is1], Number is Number1 + 1. intersection([X|Xs],Ys,Is,Number):non_member(X,Ys), intersection(Xs,Ys,Is1,Number1), Is = Is1, Number is Number1. intersection([ ],Ys,Is,Number):Is = [ ], Number is 0.



Context

Here an extra argument is added for the propagation of information. Techniques applied to the extension created from the context technique can make use of the information in the context variable. Applying context to simple traverse yields the program position which carries as context the position of the element in the list. It is assumed that the context variable is grounded before execution begins. position([X|Xs],Pos):Pos1 is Pos, position(Xs,Pos1). position([ ],Pos).



Accumulate-build

This technique adds two arguments to the de ning predicate in the skeleton to allow for global variables in a program. The rst argument is used to record the current value of the variable in question and the second one contains the nal result of the computation. The base case uni es the two arguments. Note that the di erence between build and accumulate ? build is that build adds arguments in the head of the clause whereas accumulate ? build adds arguments in the body. Applying accumulate ? build to simple traverse yields the program reverse.

27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

6

APPLYING TECHNIQUES TO SKELETONS reverse([X|Xs],Ys,Final):reverse(Xs,Ws,Final), Ws = [X|Ys]. reverse([ ],Ys,Final):Final = Ys.

Accumulate ? build requires an extra clause to initialize the accumulator. reverse(Xs,Ys):reverse(Xs,[ ],Ys).

There is another technique called accumulate ? calculate which bears the same relation to calculate that accumulate ? build has to build.

1.4 COMPOSING SEVERAL EXTENSIONS In this section we give examples of how to compose two extensions of the same skeleton. Our composition algorithm informally described in [SL88] uses the goals in the skeleton to connect goals from each of the extensions. The idea to use the goals from the skeleton to drive the composition algorithm came directly from the theory found in [KSJar]. The algorithm composes the extensions by processing the clauses in the skeleton sequentially. For each clause in the skeleton, take the clauses in each of the programs which extend that clause. Create the head of the clause by using a new predicate name, make one copy of each argument corresponding to the arguments in the skeleton, and add an extra argument for each extra argument in each extension . The body is created by aligning the goals in the extensions with the corresponding goal in the skeleton. If the goal has a di erent name than the head of the clause then copy it, else compose the goals as was done for the head of the clause. We give two examples here, the composition of union with intersect to yield a predicate union intersect, and the composition of length with sum to yield length sum. union_intersect([X|Xs],Ys,Us,Is):member(X,Ys), union_intersect(Xs,Ys,Us1,Is1), Us = Us1, Is = [X|Is1]. union_intersect([X|Xs],Ys,Us,Is):non_member(X,Ys), union_intersect(Xs,Ys,Us1,Is1), Us = [X|Us1], Is = Is1. union_intersect([ ],Ys,Us,Is):Us = Ys, Is = [ ].

length_sum([X|Xs],Len,Sum):length_sum(Xs,Len1,Sum1), Len is Len1 + 1, Sum is Sum1 + X. length_sum([ ],Len,Sum):Len is 0, Sum is 0.

27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

7

THE MODEL INFERENCE SYSTEM

Applying techniques to skeletons and then composing can greatly facilitate the construction of a complex program. The idea, called stepwise enhancement, is to continually transform a problem into smaller subproblems in the usual top-down style of programming until these smaller problems can be seen to be extensions of a single skeleton. These extensions can then be composed to produce the desired program. This method has the property of reducing the complexity for program development since each technique builds upon the same skeleton independently. Consequently, the rst extension does not interact with the application of later techniques. Finally, when we have nished creating all the extensions required for the problem, they are composed together in one step. The composition step is restricted to extensions of the same skeleton [Lak89b, SL88]. Stepwise enhancement is implicit in many of the programs in the text [SS86], for example the solution to the Dutch Flag problem presented in Chapter 15.

1.5 THE MODEL INFERENCE SYSTEM The Model Inference System (MIS) is an implementation of an incremental inductive inference algorithm. Given a set of examples and counterexamples of a new concept, MIS produces a set of Horn clauses to represent this concept. Whenever the current set of clauses prove a counterexample true, the proof tree is used to determine the faulty clause in the set which is then removed. If there exists an example not explained by the current set of clauses, a new clause is generated using a re nement operator. A major assumption of the system is that an oracle exists which knows the truth or falsity of any particular ground instance of the concept to be learned. The re nement operator determines the type of Prolog programs which can easily/not easily be learned through MIS. One re nement operator given in [Sha83] was specialized for generating clauses for de nite clause grammars whereas a second operator was presented as a more general operator. Each operator was designed for synthesizing a di erent type of program. In this paper, we use the generalized re nement operator for all comparisons with a new re nement operator based on skeletons and techniques. MIS needs to have access to certain knowledge to successfully synthesize a logic program. The following two types of knowledge are speci c to the intended target program and are supplied by the user. Declarations about the type and mode of each variable are used to determine how the variables will be instantiated. Information about `allowable' predicates guides clause creation. An added goal is related to the other goals in the clause through the instantiation of variables as speci ed by the type and mode . Other knowledge is included as part of the MIS database. For example, there is a list of instantiations for each type. A list variable can be instantiated to [ ] or [X j Xs]. MIS has specialized search strategies to determine if a clause generated by the re nement operator covers a particular goal. The clause A

0

B1 ;    ; B m

27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

8

APPLYING TECHNIQUES TO SKELETONS

The MIS Algorithm Given a possibly empty set of Horn clauses(background information), goals to be called by the target concept p, p false solutions = [], and p true solutions = []. repeat Read the next example/counterexample instance for p and add it to the corresponding list of false or true solutions. repeat If it is possible to derive a fact in p false solutions then nd a false clause and remove it from the set of Horn clauses representing the hypothesis. If it is impossible to derive a fact in p true solutions generate the re nements until a previously untried clause is generated to cover this fact. Add this clause to the set of Horn clauses. until neither of the If tests is entered Output the current set of Horn clauses. forever Figure 1.1

covers a goal A if there is a substitution  such that A = A : 0

[Sha83] describes three di erent search strategies for MIS. The strategy choice is important as to which kind of programs can be synthesized as can be seen with the well-known program append([ ],Ys,Ys). append([X|Xs],Ys,[X|Zs]):append(Xs,Ys,Zs).

Append can be synthesized with only one of the three possible strategies given for MIS. The complete MIS algorithm is given in gure 1.1. The repeat loop in gure 1.1 is bounded by the allowed depth of the proof tree. The default depth used is 25.

1.6 CLAUSE GENERATION USING SKELETONS AND TECHNIQUES In the following comparisons with MIS, we have restricted our attention to list data structures. The skeletons are generated by choosing one or more list arguments to 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

9

RESULTS OF MODIFYING MIS

recurse upon and by determining all the reasonable base cases. We have made the same assumption as MIS that there exists an all knowing oracle to answer the queries posed by the system. We also assume the presence of information detailing allowable predicates for clause creation. An interesting aspect of skeleton generation occurs when the target program uses other predicates for testing and updating arguments. Predicates like  and > require the comparison of two variables which, in all generality, may be any of the variables in the head of the clause or even worse it may be output variables from some other goal in the body of the clause. For example, here are a few of the reasonable possibilities for a skeleton predicate with one list, two element variables and which uses < and >. sk([X|Xs],Y,Z):X < Y, sk(Xs,Y,Z).

sk([X|Xs],Y,Z):X < Z, sk(Xs,Y,Z).

sk([X|Xs],Y,Z):Y > Z, sk(Xs,Y,Z).

sk([X|Xs],Y,Z):X > Y, sk(Xs,Y,Z).

Without using some meta-knowledge we will generate too many possibilities. An example of a poorly generated skeleton would be sk([X|Xs],Y,Z):X < Y, X > Y, sk(Xs,Y,Z).

Therefore, we have added some meta-knowledge to reduce the number of skeleton's produced. This knowledge includes 1. Mode of variables - unify input variables for the extra predicates only with the input variables for the head of the clause or with an output variable from another predicate. 2. Type of variables - only unify variables of the same type. 3. Incompatible predicates - a predicate exclusive(Pred1,Pred2,Type) is used to indicate if two predicates can only be used together under certain restrictions. For example, < and  cannot be used in the same clause if they have the same arguments in the same order. Another situation we would like to avoid would be having both X < Y and Y > X in the same clause. For binary predicates this can be accomplished by having a predicate opposite(Pred1,Pred2), which will tell if the two predicates produce the same results if the arguments are switched. A third category checks for symmetry. We do not want to produce one clause having X = 6 Y and another clause which is identical except it contains Y 6= X. 4. Last recursive call - every recursive skeletal clause has the recursive predicate as the last goal. The supplied information is used for creating clauses and for pruning redundant clauses.

1.7 RESULTS OF MODIFYING MIS The system is given a fact for the target Prolog program and creates all possible skeletons using the meta-knowledge mentioned above. These in turn are given to an 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

10

APPLYING TECHNIQUES TO SKELETONS

enhancement module to produce all possible enhancements to those clauses. The component of MIS which removes incorrect clauses when counterexamples are supplied is applied to the generated clauses to produce the nal program. Thus, the skeleton creation and the various techniques in the enhancement module determine the possible programs to be learned. Our system will synthesize programs having only lists and elements as variables and either has no output variables or the output variable is used for some type of collection. This last restriction is due to the fact that the only enhancement technique implemented at this point is build. Further research needs to be done to determine how slow the system will become as more techniques are added. Some of the programs used for comparison include: prefix (3.13), suffix (3.13), append (3.15), sublist (3.14), member (3.12), nonmember (7.5), select (3.19), and subset (7.7). The number in parentheses after each of the above predicate names refers to the program number used in The Art of Prolog [SS86]. We also used predicates union, difference, and intersection in our comparison. The code for difference is similar to the code for union. Unfortunately, due to the underlying structure of MIS, it is not possible for the system to remove redundant clauses. The program learned for prefix given below demonstrates this unwanted behavior. prefix(X,X). prefix([ ],[ ]). prefix([ ],X). prefix([X|Xs],[X|Ys]):prefix(Xs,Ys).

Removing redundant clauses is, in general, too computationally expensive to be practically implemented. One possible way of avoiding redundant clauses is to take a correct set of hypothesized clauses and form a new set of clauses by selecting a base clause plus all the recursive clauses and check if the examples can be proven by this new set of clauses. If not, repeat the above with a di erent base case. Of course, in general, a program might require two or more base cases and it is also possible that some of the recursive clauses will be redundant. Prefix, suffix, and append were easy for both systems to learn. Member, select and append were very easy for MIS to learn since the re nement operator gives a high priority to expanding and unifying elements on a list. Our modi ed system found those same programs to be nontrivial to learn due to the large number of clauses created by the re nement operator. Once these clauses have been generated, it is necessary to feed the system counterexamples to weed out the inappropriate clauses. It was also dicult to learn subset without select being learned rst because the rst program produced for select in conjunction with the one produced for subset will have an in nite loop in it. A non-terminating condition will be recognized but, due to the large default depth bound and the numerous clauses to be tested, this is a very slow process. Union has the same problems if nonmember and member are not synthesized rst. It took a lot of memory to complete the synthesis of union even when its called goals are synthesized rst. The code generated for subset is 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

11

CONCLUSION subset([ ],[ ]). subset([ ],X). subset(X,X). subset([X|Xs],Ys):select(X,Ys,Ys1), subset(Xs,Ys1). subset([X|Xs],[X|Ys]):subset(Xs,Ys). subset(Xs,[Y|Ys]):select(Y,Xs,Xs1), subset(Xs1,Ys). subset(X,[Y|Ys]):subset(X,Ys).

The reason why select was easy for MIS to learn, caused MIS to fail to learn both and union independent of the search strategy employed. Memory ran out. The re nement operator used for MIS gives priority to expanding the variables in contrast to adding goals to a clause. The variable [X j Xs] will be expanded to [X; Y j Zs] making it dicult to learn a program which calls numerous goals. Both subset and union make use of the predicates member and nonmember. A nice feature of our modi cation to MIS can be seen in the synthesis of the program for union. If nonmember and member are previously known to the system, the user does not interact with the system from the time the initial declarations are made until the list of possible clauses are generated. The ability to free the user from system queries during the clause generation stage will generalize for any target program that has all of its called goals previously synthesized. The weakness of our system is the volume of clauses produced. The removal of the duplicate clauses, before they are asserted as hypothesized clauses, is the most expensive operation in the system. After the duplicate clauses have been removed it is still necessary to feed the system counterexamples to weed out the inappropriate clauses. However, judicious selection of counterexamples will limit the number required by the system. A possible solution to this problem is to keep all the generated clauses in a list to be processed one at a time Due to the combinatorial explosion of clause generation, a restriction was made to not allow an expanded variable [X j Xs] to have both X and Xs in the same goal in the body of the clause. This restriction made it impossible to synthesize a program to remove repeated elements in a list. If the above restriction is removed, union will explode with generated clauses. A possible solution to this is to have di erent search strategies similar to what is found in MIS.

subset

1.8 CONCLUSION We claim that the language of skeletons and techniques simpli es program development. In particular, it provides a powerful framework for presenting useful topics in an introductory course in Prolog. Once the idea of skeletons and extensions has been accepted, new topics can be presented via skeletons with the details of the extensions 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

12

APPLYING TECHNIQUES TO SKELETONS

and compositions left for the students as a simple exercise. We have successfully introduced meta-programming via this methodology by using the well-known vanilla meta-interpreter [SS86] as a skeleton and extending it for di erent applications. A consequence of constructing Prolog programs by applying techniques to skeletons is that this imposes some standardization for Prolog programs. This could make Prolog a more inviting tool for software engineering projects since each module of code could start with an underlying skeleton which is extended and composed. This approach to program development is, in our experience, accessible both for the average and neophyte Prolog programmer. Another reason for our optimism is the great potential for making program development automatic or at least semi-automatic. With a given set of skeletons and techniques to work with, it is possible to automate the composition part of the process to produce the nal program. Therefore, the programmer would be responsible for only the problem solving i.e. nding the correct ow of the program and the technique which would best suit the given problem but not the details of putting it together. Work on automating this process has already begun. A prototype system has been developed at Case Western Reserve University [Lak89b, Lak89a] We believe the application of skeletons and techniques to MIS will have a greater impact upon learning when meta-knowledge is introduced to direct the generation of skeletons. This is truly the bottleneck in this process. We may need to add knowledge in the form of a relationship between the number of elements in lists, or which list is to be recursed upon, or something else to minimize the number of possible skeletons being generated. If we think of skeleton creation as the `getting started' process of learning, then the system's diculty is that it is does not know how to get started. This is a typical problem for learning systems. For our system, the knowledge required to determine which of all the possible skeletons are appropriate for a particular learning exercise is not currently captured in meta-knowledge. One possible approach to reduce the complexity of clause generation without requiring too much from the user would be to ask the user to give the position of the argument(s) to be recursed upon. For union, the number of clauses generated would be cut in half. Yves Deville in [Dev90] provides a promising source of insight for structuring skeleton creation. The knowledge included in his concept of logic speci cation overlaps with the knowledge added to MIS in this paper and also contains extra information, for example multiplicity. Deville's use of inductive schemes in the logic description of a skeleton can be interpreted as a shifting to a weaker bias as described in [Utg86]. The required heuristic methods for deciding exactly how to modify the skeleton creation process needs to be determined. We believe a di erent and interesting approach to machine learning of Prolog programs would be to formulate the problem so that we leave the arena of inductive learning into learning by chunks. With this approach we would require meta-metaknowledge to generate the appropriate meta-knowledge needed or guiding the skeleton creation. Once the skeleton has been created, we will apply techniques in an orderly fashion to create various Prolog programs. Each program can then be checked for correctness by having the user introduce counter-examples to the system. 27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

ACKNOWLEDGEMENTS

13

1.9 ACKNOWLEDGEMENTS This research was supported by NSF grant CCR 90-00036. Our thoughts on how to decompose Prolog programs into skeletons and techniques and how to represent techniques have evolved considerably over the past several years. It is hard to isolate all the speci c in uences on our work. But we would like to thank the attendees of the regular ProSE discussion group at Case Western Reserve University especially Charles Wells, Ashish Jain, Lee White, and U mit Yalcinalp. Also, we thank Arun Lakotia for his advocacy of stepwise enhancement as an important program development methodology. Its need for building blocks such as skeletons and techniques has been instrumental in shaping our ideas.

1.10 EXERCISES 1. The left di erence between the set A and the set B are all elements which are in set A but not in set B. Extend the skeleton traverse to create a Prolog program to compute the left di erence. 2. Write a Prolog program that computes the number of leaves and the sum of the values of the leaves on a binary tree. The tree is to be traversed only once. 3. Write a Prolog program to solve Dijkstra's Dutch Flag problem. The description here is taken from [SS86]. The problem reads: `Given a list of elements colored red, white, and blue, reorder the list so that all the red elements appear rst, then all the while elements, followed by the blue elements. This reordering should preserve the original relative order of elements of the same color.'

REFERENCES [Dev90] Yves Deville. Logic Programming: Systematic Program Development. AddisonWesley, Massachusetts, 1990. [Fri90] L. Fribourg. Extracting logic programs from proofs that use extended prolog execution and induction. In P. Szeredi and D. H. Waren, editors, Proceedings of the Seventh International Conference on Logic Programming, Cambridge, USA, November 1990. MIT Press. [KSJar] M. Kirschenbaum, L.S. Sterling, and A. Jain. Relating logic programs via program maps. Annals of Mathematics and Arti cial Intelligence, to appear. [Lak89a] A. Lakhotia. Incorporatng programming techniques into prolog programs. In Lusk and Overbeek, editors, Proceedings of the North American Conference on Logic Programming, pages 426{440, Cleveland, November 1989. MIT Press. [Lak89b] A. Lakhotia. A Workbench for Developing Logic Programs by Stepwise Enhancement. PhD thesis, Case Western Reserve University, July 1989. [LP90] K.K. Lau and S.D. Prestwich. Top-down synthesis of recursive logic procedures from rst-order logic speci cations. In D.H. Waren and P. Szeredi, editors, Proceedings of the Seventh International Conference on Logic Programming, pages 667{684, Cambridge, USA, November 1990. MIT Press. [O'K90] R.A. O'Keefe. The Craft of Prolog. MIT Press, Cambridge, USA, 1990. [PS87] F.C.N. Pereira and S.M. Shieber. Prolog and Natural-Language Analysis. Center For The Study Of Language And Information, 1987. [SB89] L.S. Sterling and R.D. Beer. Meta-programming for expert systems. Journal of Logic Programming, 6(1):163{178, 1989.

27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech

14

APPLYING TECHNIQUES TO SKELETONS

[Sha83] E.Y. Shapiro. Algorithmic Program Debugging. MIT Press, Cambridge, USA, 1983. [SL88] L.S. Sterling and A. Lakhotia. Composing prolog meta-interpreters. In Bowen and Kowalski, editors, Proceedings in the Fifth International Conference and Symposium on Logic Programming, pages 386{403. MIT Press, 1988. [SS86] L.S. Sterling and E.Y. Shapiro. The Art of Prolog: Advanced Programming Techniques. MIT Press, Cambridge, USA, 1986. [Utg86] P.E. Utgo . Maching Learning, volume II, pages 107{148. Morgan Kaufmann Publishers, Inc., 1986. [Wir71] N. Wirth. Program development by stepwise re nement. Communications of the ACM, 14(4):221{227, 1971.

27/3/1995 14:15|PAGE PROOFS for John Wiley & Sons Ltd (using jwcbmc02, Vers 31.08 AUGUST 1992)|Apply_Skl_Tech