type theory, as implemented in the Oyster system Bundy et al., 1990], a con- structive type theory, derived from Constable's Nuprl Constable et al., 1986].
Automating the synthesis of functional programs Alan Smaill
Ian Green
Abstract The task of constructing programs can be treated as a task of nding proofs in an appropriate logic. For recursive programs, the corresponding logic includes appropriate induction principles. We describe a system that automates program synthesis via theorem proving in this way, building on control strategies developed for veri cation proofs using proof plans. This involves some extensions to the planning system. The resultant system automates an approach to programming where program development and correctness proof proceed hand in hand, as advocated by Gries.
1 Introduction Our interest is in the automation of program synthesis. We work in constructive type theory, as implemented in the Oyster system [Bundy et al., 1990], a constructive type theory, derived from Constable's Nuprl [Constable et al., 1986]. In this setting program synthesis is achieved by proving a speci cation statement of the form input output spec(input; output) where input is a vector of arguments (each possibly of dierent type) and output is a result, and spec is a proposition describing the required relation between them. A program meeting this speci cation can be extracted from its proof via the formulae-as-types principle [Howard, 1980]. This style of program synthesis is widely advocated [Nordstrom and Smith, 1990, Paulin-Mohring, 1989], and supported in a number of interactive implementations (Nuprl, Oyster, Alf [Nordstrom, 1993]). Recursive programs correspond here to proofs by induction. By a veri cation problem for a recursively de ned procedure, we understand a proof goal which is purely universally quanti ed | its proof will use some induction principle. To synthesise such a procedure, we prove by induction a statement of the form above, with some existential quanti cation. 8
9
1
Automating the synthesis of functional programs
2
For automation of these proofs we exploit Bundy's proof-planning paradigm [Bundy, 1988, Bundy et al., 1993]. A proof-plan is an outline of a family of proofs sharing some common structure which can be used to guide search for proofs in that family. In this paper we report on our success in adopting this paradigm as a means of automating program synthesis. Extensions and generalisations of the basic plan were required. We implemented middle-out reasoning (MOR) in order to address a key diculty in proving existential theorems. The basic idea is to represent unknown quantities (`eureka' values) with meta-variables; these variables are gradually re ned as subsequent proof-planning takes place (see 3). Control of this re nement is the crucial factor in the success of such an approach, and it is here the search control oered by proof-planning becomes important. We liken our approach to that advocated by Gries who wrote [Gries, 1981, pg. 5]: \More importantly, the study of program correctness proofs has led to the discovery and elucidation of methods of developing programs. Basically, one attempts to develop a program and its proof hand-in-hand, with the proof ideas leading the way!". The framework of proof-planning enables us to express declaratively such methods for program synthesis (our formalism is quite dierent from Gries's however), and reason with them. MOR is a natural way to develop a program and its correctness `hand-in-hand' in the context of the formulae-as-types principle. The activity of synthesis of course diers greatly from that of veri cation. In searching for a veri cation proof, the subgoals generated typically can be solved independently. In synthesis proofs, however there is often dependency between subgoals. A classic example of this is when solving one subgoal upsets another which has already been solved. This is dierent from the veri cation case. Waldinger wrote[Waldinger, 1977] \In program synthesis, such `simultaneous goal' problems are rampant." In this paper we illustrate such rampant behaviour and describe our solution which is a proof-plan transformation (rather like the use of a goalregression rule). We believe the approach has a number of technical, as well as practical, advantages over the many other approaches to automatic program synthesis (we consider some of them in 5). x
x
Overview of Paper In section 2 we introduce the necessary background concepts from type theory and proof plans. In section 3 we present our approach to synthesis and explain how it extends the application of inductive proof plans, with examples in section 4. In sections 5 and 6 we relate our work to other work in the area, and comment on the promise of this approach.
Automating the synthesis of functional programs
3
2 Background 2.1 Functional programming and type theory The development of type theory as a framework for the speci cation and re nement of functional programs is due to Howard [Howard, 1980] and MartinLof [Martin-Lof, 1979]. In this approach, functional programs are regarded as terms of the type theory, and their types are associated with speci cations of their behaviour. Logical connectives in a speci cation correspond to type constructors in the type theory; we will use the more familiar logical syntax in this paper. The rules for showing type membership work as inference rules in the logic of the type theory, which turns out to be a constructive logic. In addition to logical rules, there are rules dealing with datatypes, for example induction rules for each inductive datatype. We follow the style of proof construction presented in [Constable et al., 1986]; in developing a proof, we build up a term of the type of the top-level speci cation, i.e. a functional program that satis es the speci cation. This term is hidden during proof construction, but is computed automatically from the completed proof. The technical problem of computationally redundant parts of such terms have been dealt with using the subset type (as in [Nordstrom and Smith, 1990]).
2.2 Proof plans and Rippling A proof plan consists of a tactic (in the sense of LCF [Gordon et al., 1979]) together with a method. The method is a partial tactic speci cation consisting of preconditions which describe conditions under which the tactic is applicable, and eects which describe the eect of the tactic. These are written in a metalogic. Clam is a planner which reasons with methods to compose them and build a special-purpose proof plan tailored to a particular theorem. If a particular proof plan attempt for a certain goal fails for whatever reason, Clam will automatically backtrack and try other proof plan alternatives. When a plan is found, the tactic side of it is executed in the normal way to produce an object-level proof. Since we are concerned with the automation of inductive synthesis proofs, we use the proof-plan for induction as the basis of our synthesis approach. A key part of the induction proof plan is the ripple proof plan. This plan manipulates (for example, by rewriting) the goal of an inductive proof in such a way that it is possible to appeal to the induction hypothesis (so called `fertilisation ') to nish the proof. Rippling and fertilisation are used in the step-cases of inductive proofs. Searching for a proof plan is easier than searching for a proof in the underlying type theory because proof at the planning level is highly constrained. (Of course we cannot plan all theorems of the type theory.) Furthermore, methods take for granted basic (meta-level) operations (e.g., rewriting) which may require non-
Automating the synthesis of functional programs
4
trivial object-level justi cation when the corresponding tactic is executed.
2.3 A Simple Example We illustrate Clam's proof-plan by example: a proof based on the associativity of +. (We stress that this is only an illustration, and does not show many aspects of rippling.) We work in a sequent calculus presentation, with the sequent symbol \ ". On the left of the sequent there are formulae, and also declarations of variables with associated types (eg x : nat). For a given sequent, the set of such declarations constitutes the context at that point. Given the operation + described by the equations `
0+X = X s(X ) + Y = s(X + Y )
(1) (2)
we conjecture (in the context with x : nat; y : nat; z : nat):
w : nat x + w = (x + y) + z
` 9
(3)
The existential method simply supplies a meta-variable to stand for a witness, hoping that it will be instantiated in subesequent planning. `
x + W = (x + y) + z
(4)
The induction method preconditions carry out rippling analysis [Stevens, 1988] (cf. Boyer and Moore's recursion analysis [Boyer and Moore, 1988]) to choose an appropriate induction scheme1 and variable(s) upon which to induce. Rippling analysis suggests primitive recursive induction on x. The base-case of the proof is `
0 + W = (0 + y) + z
(5)
which is reduced by symbolic evaluation using (1) twice to W = y + z, and solved by instantiating W to y + z. This has the side eect of instantiating W in the step goal as well. Note that this behaviour (a single witness that works for both base and step cases) is not always what we want, and dierent behaviour is shown in section 3.3. However, when we can show that the same witness is correct for bothe base and step bases, this means that the resultant program is not recursive, and so to be preferred on eciency grounds. 1
from a library of veri ed schemes
Automating the synthesis of functional programs
5
The induction method postconditions annotate the step-case goal in such a way as to make explicit the dierences between it and the induction hypothesis (shown here with W instantiated): W
z }| {
"
W
z }| {
"
(6) x + (y + z) = (x + y) + z s(x) + (y + z) = ( s(x) + y) + z Some terminology: the boxes are meant to hide structure, while the underlines allow structure to be visible within a box. The \visible" part of a formula is called its skeleton. Unannotated terms are their own skeleton. Please see [Basin and Walsh, 1994a] for details. Notice then that the skeleton of the conclusion is identical to the hypothesis. The dierences between the hypothesis and the conclusion (e.g., s( )) are called wave-fronts. The step-case method is highly goal directed and constrained: it attempts to remove the wave-fronts (dierences) from the conclusion in order that fertilisation may take place. The removal of wave-fronts is via rewriting with the proviso that the skeleton of the goal is unchanged. The rewrite rules having this property of skeleton preservation are called wave-rules. Wave-rules are automatically constructed from equations, and (bi-)implications. Wave-rules derived from (2) and the substitution rule are s(X ) + Y s(X + Y ) (7) s(X ) = s(Y ) X=Y (8) Approximately, rewriting with wave-rules is as normal rewriting with the proviso that annotation of the term to be rewritten matches annotation on the rule LHS. We call this rewriting rippling. Rippling guarantees skeleton preservation. Termination of rippling in the absence of meta-variables follows from the fact that there is a well-founded measure on annotated terms, and all wave-rules decrease this measure (please see [Basin and Walsh, 1994b]). Applying 7 repeatedly on 6 gives (9) x + (y + z) = (x + y) + z s(x + (y + z)) = s((x + y) + z) to which 8 applies: x + (y + z) = (x + y) + z x + (y + z) = (x + y) + z (10) at which point all the dierences between the conclusion and the hypothesis have been removed, and fertilisation can immediately complete the proof. In this example, the corresponding algorithm simply returns the value y + z, and is not recursive (the induction in the proof treats the correctness of the answer, and not its computation). In the sequel we are also interested in cases of recursive algorithms, where induction is needed both to construct the output, and show its correctness. `
)
)
`
`
Automating the synthesis of functional programs
6
3 System Design The proof-plan for induction described in [Bundy et al., 1993] has only limited facilities to deal with existential proofs. In developing a plan for existential inductive theorems we have extended the basic inductive plan in a number of ways, which we describe in this section after listing the methods from the basic inductive plan. Name Base Case Step Case Generalise
Description Symbolic evaluation, and simple propositional reasoning; Applies wave rules, and uses induction hypothesis if possible Use a more general goal; only generalises a multiply occurring term to a variable Existential Replace existentially quanti ed object variable with (unquanti ed) meta-variable Induction Use ripple analysis to select a suitable induction scheme and variable on which to apply induction rule Figure 1: Methods of basic inductive plan Figure 1 shows the methods we based this experiment on. The planner searches in a depth- rst way using the methods in the order given. This means, for example, that a plan using induction is investigated only if no non-inductive plan is found.
3.1 Use of Metavariables and Constraints The problem of existential witnesses is central to synthesis proofs. Once a witness has been introduced, subsequent proof is a veri cation that this witness has the required properties. Rather that automate the choice of this `eureka' witness, we introduce a metavariable to stand for the witnessing term. Subsequent planning re nes the metavariable into, eventually, an object-level term. We call this simultaneous synthesis and veri cation middle-out reasoning (MOR). MOR is potentially very explosive since the instantiation of a metavariable is very weakly constrained. However, not all these instantiations correspond with proofs in the family described by our proof plan. It is this restriction which forces metavariables to be instantiated in a controlled and well-understood way. MOR allows us to treat synthesis uniformly in much the same way as veri cation; as a result our synthesis proof plan does not require (at least so far) any special-purpose heuristics designed to guess witnesses.
Automating the synthesis of functional programs
7
Existential introduction is the source of metavariables: ? z : P (z) existential(Z : ) ? P (Z ) ` 9
`
We show here the eect of a method application, schematic in P , with Z as a fresh metavariable. The input goal is above the line, in sequent notation, and the subgoal below. For the proof (as opposed to the proof-plan) be sound, Z must be instantiated to an object-level term typable in context ?. This is a constraint on the values that Z can take. For example, consider the goal z y z = y. This goal is not provable, and so planning should fail here; such goals are unlikely in top-level speci cations, but do arise in the planning process in branches that we then want to fail quickly. The existential method yields the subgoal y Z = y. Instantiating Z to y gives a satis able goal, which is clearly undesirable. This instantiation fails the constraint of being well-formed in the context where the existential method was applied, and is thus rejected. It is not necessary to wait until Z is ground: we detect ill-typed re nements as soon as possible by incrementally validating the constraint. ` 9
8
` 8
3.2 Induction method for existential goals The standard induction method is adequate for synthesis examples like the one given in section 2. For the synthesis of recursive functions, an extension is needed. This does the same recursion analysis as before, but replaces the existentially quanti ed induction hypothesis with an unquanti ed instance, and introduces a fresh metavariable for the witness in the conclusion. As above, this generates a constraint that the witness must be well formed in the current context. Appropriate annotations are supplied. The intuition is that the witness for the conclusion is likely to be expressed in terms of a witness for the induction hypothesis, which has thus been made available as part of the context.
3.3 Casesplits beneath existentials In the proof-planning framework casesplits are motivated by the presence of conditional equations. But this motivation may only become evident below the point of an existential introduction. In a naive approach, we may not be able to nd a proof since the witnesses in the two branches of the case-split will be required to be identical. This is an example of the dependence between goals mentioned in section 1. However, with care we can under some circumstances use the casesplit so as to remove this dependency.
Automating the synthesis of functional programs
8
We turn to an example due to Waldinger [Waldinger, 1977] to illustrate the problem. Consider a simple program which inputs a two-element list (in fact, two integers) and outputs the sorted list according to the relation (we present this in a slightly unusual fashion to be consistent with other examples).
x : int; y : int
z : int list ( e : int (e = x e = y)
` 9
8
_
$
e z) ordered(z) 2
^
Here and ordered are de ned via: 2
ordered(nil) ordered(H 1 :: nil) ordered(H 1 :: H 2 :: T ) X nil X H :: T 2
2
$ $ $ $ $
true true H 1 H 2 ordered(H 2 :: T ) false X=H X T
(11) (12) (13) (14) (15)
^
_
2
Existential introduction gives the metavariable Z . We then symbolically evaluate ordered(Z ) by (13) partially instantiating Z to Z0 :: Z1 :: Z2. (We discuss the control of this instantiation process in section 3.4.) This gives us:
x : int; y : int
`
( e : int (e = x e = y) e Z0 :: Z1 :: nil) Z0 Z1 ordered(Z1 :: Z2) 8
_
$
2
^
^
then symbolic evaluation using (15) twice, (14) once, and (12) gives
x : int; y : int
`
( e : int (e = x e = y) (Z0 Z1 true) 8
_
e = Z0 e = Z1 false)
$
_
_
^
^
This proof can be nished easily if we have x y, and also if we have y x. This suggests the use of a case-split on x y y x.2 This gives two subgoals (as above, with extra hypothesis x y and y x respectively), with shared metavariables. We can solve the rst (substitution Z0 x; Z1 y ), but the second is then unsatis able; similarly we can solve the second, making the rst unsatis able. So whilst we can prove each of the subgoals independently, we are unable to achieve both of them simultaneously. The solution is to `regress' the case-split over the existential introduction. Thus the proof splits into the two branches before the existential witness is supplied, thus allowing distinct witnesses in the two branches. One possibility in these circumstances is to backtrack in the plan search to where the existential introduction was made, apply the case split instead, and continue the planning. However, this is wasteful of the planning already done.
_
f
2
It is not necessary for the cases to be exclusive.
7!
7!
g
Automating the synthesis of functional programs
9
An alternative is to consider a proof transformation, which takes the intermediate stages of the partial proof plan, and returns a proof plan with the desired branching structure. This has the eect of duplicating the existential introduction (one for each branch of the split), and so giving a fresh metavariable in each branch. We can depict this schematic proof transformation as in gure 2. In the gure, P Q _
z g0(z) z g0(z) i Q g0.(Z ) P z g0(z) i ... 0 P g. (Z1) Q ... 1 g (Z ) split P g(Z ) Q g(Z ) = P g(Z1 ) Q Figure 2: Proof transformation ` 9
` 9
9
`
9
`
`
`
`
`
)
z g0(z) split g.0(Z2) i ... 2 g(Z2 )
` 9
` 9
`
`
9
is the decision term, Z are the free metavariables appearing in any instantiation of Z , and Z1 and Z2 are uniform renamings of this set; 1 and 2 are as but similarly renamed. All branches below the i must be similarly transformed if they contain occurrences of Z . Our case-split method works as follows, for a given goal g and a given decision term d, with free object variables v. 9
1. We check to see that all the metavariables in d are introduced below some uppermost existential introduction; all variables in v appear above this point. 2. All metavariables appearing in d are renamed and the witnesses for each instantiated to an appropriate case term. 3. not sure about this one Any case terms appearing in other branches induce a case-split as described in the term. The immediate eect at the planning level is to allow planning to continue with renamed distinct meta-variables in the branches of the case. In the implementation, the transformation is not carried out during planning, but instead as a post-planning computation. Our new proof plan exploits the fact that the transformation can be postponed, maning that there is no need for backtracking either. We simply tag the witness for Z immediately before the split with a new meta-level term, case(za:a; zb:b) which expresses that in the resultant proof-plan a case-split is needed on a b and that the witnesses in these cases are za and zb respectively. This new method is added to the repertoire of methods. Once a plan has been obtained, a subsequent step computes the transformed plan which does not contain _
Automating the synthesis of functional programs
10
any case terms. The soundness of this process is guaranteed by the execution of the plan to obtain both proof and program.
3.4 Control and termination Rippling in the veri cation case is known to terminate (see [Basin and Walsh, 1994b]), thanks to the well-founded measure de ned over the meta-level annotated terms. Unfortunately this property is not enjoyed when metavariables are present; similarly, other normally terminating rewriting such as symbolic evaluation may not terminate. Non-terminating branches cause the proof-planning to diverge. The general solution to the problem is to impose a bound on some measure of the size of the existential witnesses in a given context, and fail (and possibly backtrack) if that bound is exceeded. For the moment, a small xed depth has been adequate for the problems considered, but a more exible approach will be needed for larger problems. In the current implementation, during search for an applicable method, methods which do not cause any instantiation of meta-variables are preferred over methods which do give instantiation; backtracking in the ripple method is allowed only in the latter case. This gives a \lazy" instantiation strategy, where the witnesses are only instantiated as far as is needed to allow the planning to continue. The checks on complexity of witnesses, and the well-formedness constraints, are dealt with by introducing a general constraint checking mechanism into the planning process. The goals held by the planner consist not only of schematic, annotated formulas, but also of a set of associated constraints. The formulae and the constraints are treated dierently, in that the methods have preconditions that look at local properties of the current goal; the constraints deal with non-local properties (any method may potentially instantiate a meta-variable, for example, so constraints on that instantiation are best dealt with outside individual methods). Finally, the ripple method for veri cation goals as described in [Bundy et al., 1993] does not backtrack | often several ripples are applicable, but backtracking over them typically gives no advantage, and is wasteful in time. This is dierent in the synthesis case, where dierent instantiations associated with dierent ripples yield genuinely dierent paths in the search space. Accordingly, we allow such backtracking in the cases where some instantiation has occurred. It is a tribute to the force of the inductive proof plan that having extended it in the ways described it is still suciently constrained to let us use depth- rst search in the examples we now describe.
Automating the synthesis of functional programs
11
4 Examples, Results Figure 3 shows some simple speci cations which demonstrate the approach. All were found automatically by our system. To take the simplest example, the following speci cation is satis ed by the cons operation (here written \::"); calling the planner, we obtain 8l:int
list 8a:int 9m:int list 8x:int (x=a _ x2l) ! x2m
PLAN: existential(m:int list,a::l) then base_case(sym_eval(...)then[elementary(...)])
Here the witness for m is a::l (the second argument to the existential tactic). This is the rst solution we obtain; forcing backtracking returns another plan for a dierent program: induction([v0::v1,a::v0::v1:int list],[l:int list]) then[base_case([...]) then existential(m:int list,a::nil) then base_case([...]), step_case([...])]
Executing the plans allows us to obtain programs. The type theory program in the second case corresponds to the ML function fun f [] a | f (h::t) a
= [a] = a::h::t
Further solutions are also found. The ordering of solutions depends on the order of the methods as processed by the planner, and no claim is made about the eciency of the programs synthesised. However the ordering chosen, based on that for veri cation proofs, tends to nd simple proofs before more complex ones, and so simple programs (rather than ecient ones) before more complicated programs. Ideally a critic mechanism would be used to trigger casesplits, as in [Ireland, 1992], but this has not been integrated in our system. Figure 3 shows some examples our system deals with. De nitions used are in the style of section 3.3. Examples \half", \even" are taken from [Nordstrom and Smith, 1990], where an elegant derivation of \even" from \half" is given. Instead, we synthesise independent proofs, using a non-structural induction principle, proved interactively but generally applicable. Though the examples are simple, we believe these results are encouraging. Search is sucently constrained that, for example, in the cases where recursive procedures are needed, the search for a non-recursive solution fails fairly quickly, even though we work depth rst.
Automating the synthesis of functional programs
12
Name Statement
l : int list a : int m : int list x : int (x = a x l) x m x : int list y : int list z : int list e : int (e x e y) e z x : int list y : int list z : int list e : int (e x e y) e z x : int y : int z : int list e : int (e = x e = y) e z x : nat y : nat z : nat w : nat x + w = (x + y) + z x : int y : int z : int list ( e : int (e = x e = y) e z) ordered(z)
cons
8
app
8
syn4 pair asps pair2
8
8
9
_
2
8
8
2
8
2
8
_
2
!
^
2
!
8
8
8
8
8 8
8
8
2
2
9
2
9
_
8
!
9
8
!
2
9
9
_
$
2
^
Figure 3: Some goals successfully planned
5 Related work We have already mentioned various systems that make use of the ideas of proofsas-programs (for example [Nordstrom, 1993, Paulin-Mohring, 1989]); as they stand these systems have only a small amount of automation. Such systems support to varying degrees Gries's desire to see programming and proof intertwined. The use of metavariables in place of existential witnesses is a standard technique (dating back as far as resolution-based synthesis [Green, 1969, Waldinger and Lee, 1969]). Automatic program synthesis and theorem proving diverged somewhat as many inductive provers (notably Nqthm) did not support existential quanti ers and so were not well suited for synthesis. Synthesis systems went the way of dedicated program construction calculi. Manna and Waldinger reunited the two [Manna and Waldinger, 1980] with their interactive deductive tableaux approach. LOPS [Bibel and Hornig, 1984] uses a collection of special-purpose heuristics to deduce functional programs from rstorder speci cations. The INKA system [Biundo et al., 1986] skolemizes speci cations and uses heuristics to construct a partial proof tree [Biundo, 1988]. A subset of leaves of the partial proof form the de nition of the Skolem function: the remainder of the proof is completed (veri ed) with respect to this de nition. Work on the choice of inductions in this context can be found in [Hutter, 1994]. We believe that type theory provides a rmer mathematical foundation than is found in these systems, and also a better base for structuring larger software development, though we do not pursue that topic here. 89
898
Automating the synthesis of functional programs
13
Closer to our work is that of Kraan who has used proof planning in the synthesis of logic programs [Kraan et al., 1993]. Her approach uses middle-out reasoning to construct predicate de nitions from universally quanti ed speci cations. [Wiggins, 1992] adopts a related approach closer to the \proofs-as-programs" idea. Basin [Basin, 1994] uses middle-out reasoning in a manner similar to us, but likewise does not rely on a constructive logic; instead the instantiation of metavariables is constrained by uni cation. That is, instantiation of programs is limited to a executable subset of the logic: this subset is speci ed manually. For example, given a program P and the \if then else" introduction rule, P becomes instantiated to if C then P1 else P2; this program fragment is computable if C, P1 and P2 are computable. In contrast, we lean on the type theory to deal with questions of scope and binding, for which it is well suited. Notice that the witnesses we compute via uni cation are rst-order terms of an appropriate, non-functional, type, even though the resultant programs may be higher order. This means that the uni cation involved in the search is relatively simple.
6 Conclusions, Future Work We have presented an initial exploration of the possibility of automating the synthesis of functional programs in a constructive type theory. The key to the idea is to use proof-planning to control the required inductive proofs, and middle-out reasoning to allow existential witnesses to be developed hand-in-hand with the proof. We deal with non-linearity of proof-plans (casesplits) in the presence of existentials with an ecient proof-plan transformation. We have implemented a prototype based on these techniques atop the Oyster/Clam theorem prover, and explored some small examples. The transformation to deal with casesplits is new; while the various other techniques are already reported, the design of a system to combine them eectively as we have done is not easy. All the examples shown were carried out automatically. Though the examples are small, the approach shows promise. We have explored the possibility of automation here, not because we believe that full automation of sizable examples is a feasible medium-term goal, but because we hope to learn from the attempt how to achieve exible control. In building the declarative methods that are needed, we also pave the way for higher-level interaction with a synthesis proof system, along the lines of [Lowe, 1993]. Increased levels of automation are needed in systems designed as integrated programming and proving environments. As presented here, this approach ts into the context of bottom-up development of software, where the components of a desired procedure are available and have to be assembled in an appropriate (recursive) program. While this is desirable, it
Automating the synthesis of functional programs
14
does not address the dicult issues of top-down problem decomposition. The next stages in this investigation are to look at more and larger examples in the same style; to look at dierent search strategies for the planner; and to reduce the current redundancy in the planner so that search becomes more ecient, without losing current solutions.
Acknowledgements Alan Bundy originated the idea of proof-planning, rippling and middle-out reasoning in the context of proof-planning. Thanks to EPSRC grant number GR/J/80702 for funding.
References [Basin and Walsh, 1994a] David Basin and Toby Walsh. A calculus for rippling. In Proceedings of CTRS-94, 1994. [Basin and Walsh, 1994b] David Basin and Toby Walsh. Termination orders for rippling. In Bundy [1994], pages 466{83. [Basin, 1994] D. Basin. Logic frameworks for logic programs. In F. Turini and L. Fribourg, editors, Proceedings of the Fourth International Workshops on Logic Program Synthesis and Transformation and Meta-Programming in Logic, LNCS. Springer-Verlag, 1994. [Bibel and Hornig, 1984] W. Bibel and K.M. Hornig. LOPS | a system based on a strategical approach to program synthesis. In A. Biermann, G. Guiho, and Y. Kodrato, editors, Automatic Program Construction Techniques, pages 69{90. MacMillan, 1984. [Biundo et al., 1986] S. Biundo, B. Hummel, D. Hutter, and C. Walther. The Karlsruhe induction theorem proving system. In Joerg Siekmann, editor, 8th Conference on Automated Deduction, pages 672{674. Springer-Verlag, 1986. Springer Lecture Notes in Computer Science No. 230. [Biundo, 1988] S. Biundo. Automated synthesis of recursive algorithms as a theorem proving tool. In Y. Kodrato, editor, Eighth European Conference on Arti cial Intelligence, pages 553{8. Pitman, 1988. [Boyer and Moore, 1988] R.S. Boyer and J.S. Moore. A Computational Logic Handbook. Academic Press, 1988. Perspectives in Computing, Vol 23. [Bundy et al., 1990] A. Bundy, F. van Harmelen, C. Horn, and A. Smaill. The Oyster-Clam system. In M.E. Stickel, editor, 10th International Conference on Automated Deduction, pages 647{648. Springer-Verlag, 1990. Lecture Notes in
Automating the synthesis of functional programs
15
Arti cial Intelligence No. 449. Also available from Edinburgh as DAI Research Paper 507. [Bundy et al., 1993] A. Bundy, A. Stevens, F. van Harmelen, A. Ireland, and A. Smaill. Rippling: A heuristic for guiding inductive proofs. Arti cial Intelligence, 62:185{253, 1993. Also available from Edinburgh as DAI Research Paper No. 567. [Bundy, 1988] A. Bundy. The use of explicit plans to guide inductive proofs. In R. Lusk and R. Overbeek, editors, 9th Conference on Automated Deduction, pages 111{120. Springer-Verlag, 1988. Longer version available from Edinburgh as DAI Research Paper No. 349. [Bundy, 1994] Alan Bundy, editor. 12th Conference on Automated Deduction, Lecture Notes in Arti cial Intelligence, Vol. 814, Nancy, France, 1994. SpringerVerlag. [Constable et al., 1986] R.L. Constable, S.F. Allen, H.M. Bromley, et al. Implementing Mathematics with the Nuprl Proof Development System. Prentice Hall, 1986. [Gordon et al., 1979] Michael J. C. Gordon, Robin Milner, and Christopher P. Wadsworth. Edinburgh LCF, volume 18 of Lecture Notes in Computer Science. Springer-Verlag, Berlin, Germany, 1979. [Green, 1969] Cordell Green. Application of theorem proving to problem solving. In IJCAI-69 [1969], pages 219{239. [Gries, 1981] David Gries. The Science of Programming. Springer-Verlag, 1981. [Howard, 1980] W. A. Howard. The formulae-as-types notion of construction. In Jonathan P. Seldin and J. Roger Hindley, editors, To H. B. Curry: Essays on Combinatory Logic, Lambda Calculus and Formalism, pages 479{490. Academic Press, 1980. [Hutter, 1994] D. Hutter. Synthesis of induction orderings for synthesis proofs. In Bundy [1994], pages 29{41. [IJCAI-69, 1969] Proceedings of the 1st International Joint Conference on Arti cial Intelligence, Washington, D. C., U. S. A., 1969. [Ireland, 1992] A. Ireland. The Use of Planning Critics in Mechanizing Inductive Proofs. In A. Voronkov, editor, International Conference on Logic Programming and Automated Reasoning { LPAR 92, St. Petersburg, Lecture Notes in Arti cial Intelligence No. 624, pages 178{189. Springer-Verlag, 1992. Also available from Edinburgh as DAI Research Paper 592.
Automating the synthesis of functional programs
16
[Kraan et al., 1993] I. Kraan, D. Basin, and A. Bundy. Logic program synthesis via proof planning. In K.K. Lau and T. Clement, editors, Logic Program Synthesis and Transformation, pages 1{14. Springer-Verlag, 1993. Also available as Max-Planck-Institut fur Informatik Report MPI-I-92-244 and Edinburgh DAI Research Report 603. [Lowe, 1993] Helen Lowe. Anatomy of a Theorem Prover: an explanation mechanism for CLAM. Research Paper (forthcoming), Dept. of Arti cial Intelligence, Edinburgh, 1993. [Manna and Waldinger, 1980] Zohar Manna and Richard J. Waldinger. A deductive approach to program synthesis. ACM Transactions on Programming Languages and Systems, 2(1), 1980. [Martin-Lof, 1979] Per Martin-Lof. Constructive mathematics and computer programming. In 6th International Congress for Logic, Methodology and Philosophy of Science, pages 153{175, Hanover, August 1979. Published by North Holland, Amsterdam. 1982. [Nordstrom and Smith, 1990] K. Nordstrom, B. Petersson and J. Smith. Programming in Martin-Lof Type Theory. Oxford University Press, 1990. [Nordstrom, 1993] B. Nordstrom. The ALF proof editor. In Informal Proceedings of the Nijmegen Workshop on Types for Proofs and Programs, 1993. [Paulin-Mohring, 1989] C. Paulin-Mohring. Extracting F! 's programs from proofs in the calculus of constructions. ACM Proc. POPL, 1989. [Stevens, 1988] A. Stevens. A rational reconstruction of Boyer and Moore's technique for constructing induction formulas. In Y. Kodrato, editor, The Proceedings of ECAI-88, pages 565{570. European Conference on Arti cial Intelligence, 1988. Also available from Edinburgh as DAI Research Paper No. 360. [Waldinger and Lee, 1969] Richard J. Waldinger and Richard C. T. Lee. PROW: A step toward automatic program writing. In IJCAI-69 [1969], pages 241{252. [Waldinger, 1977] R. Waldinger. Achieving Several Goals Simultaneously, volume 8 of Machine Intelligence, chapter 6, pages 94{138. Halstead and Wiley, New York, 1977. [Wiggins, 1992] G. A. Wiggins. Synthesis and transformation of logic programs in the Whelk proof development system. In K. R. Apt, editor, Proceedings of JICSLP-92, pages 351{368. M.I.T. Press, Cambridge, MA, 1992.