|
1 <HTML> |
|
2 <HEAD> |
|
3 <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> |
|
4 <TITLE>G4ip</TITLE> |
|
5 </HEAD> |
|
6 <BODY TEXT="#000000" BGCOLOR="#C7C3C7" LINK="#0000EF" VLINK="#51188E" ALINK="#FF0000"> |
|
7 |
|
8 <H2>An Implementation of G4ip in Pizza</H2> |
|
9 |
|
10 <FONT COLOR="#800000"><B>Warning:</B></FONT> |
|
11 This page is now rather old! While you might still be interested |
|
12 in the algorithms, Robert Macdonald reported that Pizza and the current Java |
|
13 implementation (version 1.3.0) do not work together. This means you need to |
|
14 install an older Java version if you want to recompile the files given below. |
|
15 I am happy to answer all question concerning the prover, but be aware that |
|
16 currently for any kind of Java stuff I am using MLJ, which as of writing |
|
17 this note has not yet been made available for the general audience (maybe |
|
18 in the future also its OCaml equivalent). So I am not very fluent in Pizza |
|
19 anymore. <B>Update</B> Pizza development is continued and starting from version |
|
20 <A HREF="http://pizzacompiler.sourceforge.net/">0.40</A> it should work |
|
21 with recent Java implementations.<P> |
|
22 |
|
23 |
|
24 Jump to the <A HREF="#Implementation">implementation.</a> |
|
25 |
|
26 |
|
27 <H4>Introduction</H4> |
|
28 |
|
29 |
|
30 A convenient representation of intuitionistic logic is Getzen's |
|
31 sequent calculus LJ (also G1i). A sequent of LJ can be proved |
|
32 by applying inference rules until one reaches axioms, or can make no further |
|
33 progress in which case one must backtrack or even abandon the search. |
|
34 Unfortunately an interpreter for LJ using this depth-first strategy cannot |
|
35 guarantee termination of the proof search. Several modifications can be |
|
36 made to LJ's inference rules without loss of soundness and completeness. |
|
37 As result an efficient depth-first proof search can be designed for the |
|
38 propositional fragment of intuitionistic logic. The name G4ip has been |
|
39 assigned to the corresponding calculus in |
|
40 <A HREF="#TroelstraSchwichtenberg96">[Troelstra and Schwichtenberg, 1996]</a>. |
|
41 This calculus is also known as LJT which has been studied thoroughly |
|
42 in <A HREF="#Dyckhoff92">[Dyckhoff, 1992]</a>. The inference rules of |
|
43 G4ip are given <A HREF="G4ip.html">here</A>.<P> |
|
44 |
|
45 It is not very complicated to implement an interpreter for G4ip using a logic |
|
46 programming language (backtracking is directly supported within the language). |
|
47 Our first implementation is written in the logic programming language |
|
48 <A HREF="http://www.cis.upenn.edu/~dale/lProlog/terzo/index.html">Lambda Prolog</A> |
|
49 and can be found <A HREF="G4ip.mod">here</A>. Another implementation by |
|
50 Hodas and Miller written in <A HREF="http://www.cs.hmc.edu/~hodas/research/lolli/">Lolli</a> |
|
51 can be found <A HREF="ftp://ftp.cse.psu.edu/pub/dale/ic94-code/index.html">here</A> |
|
52 (see <A HREF="#HodasMiller94">[Hodas and Miller, 1994]</a>). These are simple and |
|
53 straightforward implementations of G4ip's rules. On the other hand it seems |
|
54 that imperative languages need a rather high overhead of code when implementing |
|
55 a logic calculus. For example choice points are usually implemented with stacks. |
|
56 We shall demonstrate the implementation technique of success |
|
57 continuations which provides an equally simple method for implementing logic calculi |
|
58 in imperative languages. This technique is not new: it has been introduced in |
|
59 <A HREF="#Carlsson84">[Carlsson, 1984]</a>. This paper presents a rather technical |
|
60 implementation of Prolog in LISP. Later an excellent paper, |
|
61 <A HREF="#ElliotPfenning91">[Elliot and Pfenning, 1991]</a>, appeared which |
|
62 describes a full-fledged implementation of Lambda Prolog in SML. |
|
63 We demonstrate the technique of success continuations for G4ip in |
|
64 <A HREF="http://www.cis.unisa.edu.au/~pizza/">Pizza</A>.<P> |
|
65 |
|
66 Pizza is an object-oriented programming language and an attractive extension of |
|
67 <A HREF="http://www.javasoft.com/">Java</A>. Although Pizza is a superset of |
|
68 Java, Pizza programs can be translated into Java or compiled into ordinary |
|
69 Java Byte Code (see <A HREF="#OderskyWadler97">[Odersky and Wadler, 1997]</a> |
|
70 for a technical introduction to Pizza). We make use of the following two new |
|
71 features of Pizza: |
|
72 <UL> |
|
73 <LI> higher-order functions, i.e. functions may be passed as parameters or returned |
|
74 from methods, |
|
75 <LI> class cases and pattern matching: this allows much simpler and more readable code. |
|
76 </UL> |
|
77 |
|
78 These features are not directly present in Java, but Pizza makes them accessible by |
|
79 translating them into Java. Pizza provides the programmer with the same |
|
80 extensive libraries for graphic and network applications as Java. The higher-order |
|
81 functions are essential for the technique of success continuations. The success |
|
82 continuations are functions passed as parameters or returned as values.<BR> |
|
83 |
|
84 |
|
85 <H4>The Representation of Formulae and Sequents</H4> |
|
86 |
|
87 Amongst the new language features of Pizza are class cases and pattern |
|
88 matching, which provide a very pleasant syntax for algebraic data types. The |
|
89 formulae of G4ip are specified by the following grammar:<P> |
|
90 |
|
91 <CODE>F ::= false | A | F & F | F v F | F -> F</CODE><P> |
|
92 |
|
93 |
|
94 The class cases allow a straightforward implementation of this specification; |
|
95 it is analogous to the SML implementation of |
|
96 <A HREF="http://www.cis.upenn.edu/~dale/lProlog/terzo/index.html">Lambda Prolog's</A> |
|
97 formulae in <A HREF="#ElliotPfenning91">[Elliot and Pfenning, 1991]</A>. The class |
|
98 of formulae for G4ip is given below:<P> |
|
99 |
|
100 <TT> |
|
101 <DL> |
|
102 <DD>public class Form { </DD> |
|
103 <DD> case False(); </DD> |
|
104 <DD> case Atm(String c); </DD> |
|
105 <DD> case And(Form c1,Form c2); </DD> |
|
106 <DD> case Or(Form c1,Form c2); </DD> |
|
107 <DD> case Imp(Form c1,Form c2); </DD> |
|
108 <DD>} </DD> |
|
109 </DL> |
|
110 </TT> |
|
111 |
|
112 Two examples that illustrate the use of the representation are as follows:<P> |
|
113 |
|
114 |
|
115 <CODE> p -> p </CODE> |
|
116 is represented as <CODE> Imp(Atm("p"),Atm("p"))</CODE><BR> |
|
117 <CODE>a v (a -> false) </CODE> is represented as <CODE> Or(Atm("a"),Imp(Atm("a"),False()))</CODE><P> |
|
118 |
|
119 The class cases of Pizza also support an implementation of formulae specified |
|
120 by a mutually recursive grammar. This is required, for example, when |
|
121 implementing hereditary Harrop formulae.<P> |
|
122 |
|
123 The sequents of G4ip, which have the form <CODE>Gamma=>G</CODE>, are represented |
|
124 by means of the class below. The left-hand side of each sequent is specified by a multiset |
|
125 of formulae. Therefore, we do not need to worry about the order in which the |
|
126 formulae occur.<P> |
|
127 |
|
128 <TT> |
|
129 <DL> |
|
130 <DD>public class Sequent { </DD> |
|
131 <DD> Form G; </DD> |
|
132 <DD> Context Gamma; </DD> |
|
133 <DD> public Sequent(Context _Gamma, Form _G) {...};</DD> |
|
134 <DD>} </DD> |
|
135 </DL> |
|
136 </TT> |
|
137 |
|
138 We have a constructor for generating new sequents during proof search. |
|
139 <CODE>Context</CODE> is a class which represents multisets; it is a simple |
|
140 extension of the class <CODe>Vector</CODE> available in the Java libraries. |
|
141 This class provides methods for adding elements to a multiset (<CODE>add</CODE>), |
|
142 taking out elements from a multiset (<CODE>removeElement</CODE>) and testing |
|
143 the membership of an element in a multiset (<CODE>includes</CODE>). |
|
144 |
|
145 |
|
146 <H4>The Technique of Success Continuations</H4> |
|
147 |
|
148 We have to distinguish between the concepts of proof obligations (which must |
|
149 be proved) and choice points (which can be tried out to construct a proof). |
|
150 The first argument of the method <CODE>prove</CODE> is the sequent being |
|
151 proved; the second argument is an anonymous function. The function <CODE>prove</CODE> is now |
|
152 of the form <CODE>prove(sequent,sc)</CODE>. Somewhat simplified the |
|
153 first argument is the leftmost premise and the second argument <CODE>sc</CODE>, |
|
154 the success continuation, represents the other proof obligations. In case we |
|
155 succeed in proving the first premise we then can attempt to prove the other |
|
156 premises. The technique of success continuations will be explained using the following |
|
157 proof (each sequent is marked with a number):<P> |
|
158 |
|
159 <UL><img src="proof.gif" width=337 height=112></UL> |
|
160 <BR><P> |
|
161 |
|
162 The inference rules fall into three groups: |
|
163 |
|
164 <UL> |
|
165 <LI> inference rules with a single premise (e.g. ->_R, &_L), |
|
166 <LI> inference rules with two premises (e.g. v_L) and |
|
167 <LI> inference rules without premises (e.g. Axiom). |
|
168 </UL> |
|
169 |
|
170 The following picture shows the order in which the sequents are being proved. |
|
171 |
|
172 <UL><img src="execution.gif" width=358 height=191></UL> |
|
173 <BR><P> |
|
174 |
|
175 Suppose we have called <CODE>prove</CODE> with a sequent <B>s</B> and a |
|
176 success continuation <B>is</B>. The inference rules of the first |
|
177 group manipulate <B>s</B> obtaining <B>s'</B> and call <CODE>prove</CODE> |
|
178 again with the new sequent <B>s'</B> and the current success continuation |
|
179 (Steps 1-2, 3-4 and 5-6). The inference rules |
|
180 of the second group have two premises, <B>s1</B> and <B>s2</B>. |
|
181 These rules call <CODE>prove</CODE> with <B>s1</B> and a new success |
|
182 continuation <CODE>prove(s2,is)</CODE> (Step 2-3). |
|
183 The third group of inference rules only invoke the success continuation |
|
184 if the rule was applicable (Steps 4-5 and 6-7).<P> |
|
185 |
|
186 |
|
187 We are going to give a detailed description of the code for the rules: &_L, |
|
188 ->_R, v_Ri, v_L and Axiom. The function <CODE>prove</CODE> receives as arguments |
|
189 a sequent <CODE>Sequent(Gamma,G)</CODE> and a success continuation |
|
190 <CODE>sc</CODE>. It enumerates all formulae as being principal and |
|
191 two switch statements select a corresponding case depending on the form |
|
192 and the occurrence of the principal formula.<P> |
|
193 |
|
194 The &_L rule is in the first group; it modifies the sequent being proved and calls |
|
195 <CODE>prove</CODE> again with the current success continuation sc. The code is as |
|
196 follows (<CODE>Gamma</CODE> stands for the set of formulae on the left-hand |
|
197 side of a sequent excluding the principal formula; <CODE>G</CODE> stands |
|
198 for the goal formula of a sequent; <CODE>B</CODE> and <CODE>C</CODE> stand |
|
199 for the two components of the principal formula).<P> |
|
200 |
|
201 <TT> |
|
202 <DL> |
|
203 <DD>case And(Form B, Form C):</DD> |
|
204 <DD> prove(new Sequent(Gamma.add(B,C),G),sc); break;</DD> |
|
205 </DL> |
|
206 </TT> |
|
207 |
|
208 The code for the ->_R rule is similar:<P> |
|
209 |
|
210 <TT> |
|
211 <DL> |
|
212 <DD>case Imp(Form B, Form C):</DD> |
|
213 <DD> prove(new Sequent(Gamma.add(A),B),sc); break;</DD> |
|
214 </DL> |
|
215 </TT> |
|
216 |
|
217 The v_Ri rule is an exception in the first group. It breaks up a goal |
|
218 formula of the form <CODE>B1 v B2</CODE> and proceeds with one of its component. |
|
219 Since we do not know in advance which component leads to a successful proof we have |
|
220 to try both. Therefore this rule acts as a choice point, which is encoded by a |
|
221 recursive call of <CODE>prove</CODE> for each case. |
|
222 |
|
223 <TT> |
|
224 <DL> |
|
225 <DD>case Or(Form B1,Form B2):</DD> |
|
226 <DD> prove(new Sequent(Gamma,B1),sc);</DD> |
|
227 <DD> prove(new Sequent(Gamma,B2),sc); break;</DD> |
|
228 </DL> |
|
229 </TT> |
|
230 |
|
231 The v_L rule falls into the second group where the current success |
|
232 continuation, sc, is modified. It calls <CODE>prove</CODE> with the first premise, |
|
233 <CODE>B,Gamma=>G</CODE>, and wraps up the success continuation with the |
|
234 new proof obligation, <CODE>C,Gamma=>G</CODE>. The construction |
|
235 <CODE>fun()->void {...}</CODE> defines an anonymous function: the new |
|
236 success continuation. In case the sequent <CODE>B,Gamma=>G</CODE> can be |
|
237 proved, this function is invoked. |
|
238 |
|
239 <TT> |
|
240 <DL> |
|
241 <DD>case Or(Form B,Form C):</DD> |
|
242 <DD> prove(new Sequent(Gamma.add(B),G),</DD> |
|
243 <DD> |
|
244 fun()->void {prove(new Sequent(Gamma.add(C),G),sc);}</DD> |
|
245 <DD> ); break</DD> |
|
246 </DL> |
|
247 </TT> |
|
248 |
|
249 The Axiom rule falls into the third group. It first checks if the |
|
250 principal formula (which is an atom) matches with the goal formula and |
|
251 then invokes the success continuation sc in order to prove all remaining |
|
252 proof obligations. |
|
253 |
|
254 <TT> |
|
255 <DL> |
|
256 <DD>case Atm(String c):</DD> |
|
257 <DD> if (G instanceof Atm) { </DD> |
|
258 <DD> if (G.c.compareTo(c) == 0) { sc(); }</DD> |
|
259 <DD> } break;</DD> |
|
260 </DL> |
|
261 </TT> |
|
262 |
|
263 The proof search is started with an initial success continuation <B>is</B>. |
|
264 This initial success continuation is invoked when a proof has been found. |
|
265 In this case we want to give some response to the user, an |
|
266 example for the initial success continuation could be as follows: |
|
267 |
|
268 <TT> |
|
269 <DL> |
|
270 <DD> public void initial_sc() { System.out.println("Provable!"); } </DD> |
|
271 </DL> |
|
272 </TT> |
|
273 |
|
274 |
|
275 Suppose we attempt to start the proof search with <CODE>prove(p,p => p,is)</CODE>. |
|
276 We would find that the prover responds twice with <CODE>"Provable!"</CODE>, because |
|
277 it finds two proofs. In our implementation this problem is avoided by encoding |
|
278 the proof search as a thread. Whenever a proof is found, the initial success |
|
279 continuation displays the proof and suspends the thread. The user can |
|
280 decide to resume with the proof search or abandon the search. |
|
281 |
|
282 |
|
283 <H4>Conclusion</H4> |
|
284 |
|
285 The implementation cannot be considered as optimal in terms of speed. |
|
286 A much more efficient algorithm for G4ip (but less clear) has been |
|
287 implemented by Dyckhoff in Prolog. Similar ideas can be encoded in our |
|
288 Pizza implementation; but our point was not the efficiency but the clarity |
|
289 of the implementation using success continuations. |
|
290 The technique is applicable elsewhere whenever backtracking is required. We |
|
291 compared the code of our implementation with an implementation in |
|
292 <A HREF="http://www.cis.upenn.edu/~dale/lProlog/terzo/index.html">Lambda Prolog</A>: |
|
293 the ratio of code is approximately 2 to 1. |
|
294 (see <A HREF="G4ip.mod">LambdaProlog code</A> and |
|
295 <A HREF="minimal/MinProver.pizza">Pizza code</A>). |
|
296 This result is partly due to the fact that we had to implement a class for |
|
297 multisets. In a future version of Java, we could have accessed a package |
|
298 in the library. The technique of success continuation can also be applied |
|
299 to a first-order calculus as shown in <A HREF="#ElliotPfenning91">[Elliot and Pfenning, 1991]</a>, |
|
300 but the required mechanism of substitution needs to be implemented separately. |
|
301 However, we think the technique of success continuations provides a remarkable |
|
302 simple implementation for logic calculi.<P> |
|
303 |
|
304 We had to make some compromises in order to support as many platforms |
|
305 as possible. This should change with the release of new browsers and a stable |
|
306 Java-specification (resp. Pizza-specification).<P> |
|
307 |
|
308 A paper about the implementation appeared in the LNAI series No 1397, |
|
309 Automated Reasoning with Analytic Tableaux and Related Methods, |
|
310 ed. Harry de Swart, International Conference Tableaux'98 in Oisterwijk, |
|
311 The Netherlands. The title is: Implementation of Proof Search in |
|
312 the Imperative Programming Language Pizza (pp. 313-319). The paper can be |
|
313 found here: <A HREF="Tableaux98.dvi.gz">DVI</A>, <A HREF="Tableaux98.ps.gz">Postscript</A> |
|
314 (© Springer-Verlag <A HREF="http://www.springer.de/comp/lncs/index.html">LNCS</A>).<P> |
|
315 |
|
316 |
|
317 <B>Acknowledgements:</B> I am very grateful for Dr Roy Dyckhoff's constant |
|
318 encouragement and many comments on my work. I thank Dr Gavin Bierman who |
|
319 helped me to test the prover applet. |
|
320 |
|
321 <HR> |
|
322 <A NAME="Implementation"></A><H4>Implementation</H4> |
|
323 |
|
324 <A HREF="README">Readme</A><p> |
|
325 |
|
326 <A HREF="ProverApplet.html"><B>Prover Applet</B></A><BR> |
|
327 <A HREF="ProverAppletJar.html"><B>Jar Version</B></A> |
|
328 (slightly faster, but requires Netscape 4 or MS Explorer 4).<P> |
|
329 |
|
330 |
|
331 <HR> |
|
332 <B>References</B> |
|
333 <UL> |
|
334 <LI> <A NAME="Carlsson84"></A> |
|
335 [Carlsson, 1984]<BR> |
|
336 M. Carlsson, On Implementing Prolog in Functional Programming, |
|
337 New Generation Computing, pp 347-359. |
|
338 <LI> <A NAME="Dyckhoff92"></A> |
|
339 [Dyckhoff, 1992]<BR> |
|
340 <A HREF="http://www-theory.dcs.st-and.ac.uk/~rd/">R. Dyckhoff</A>, |
|
341 Contraction-Free Sequent Calculi for Intuitionistic Logic, |
|
342 Journal of Symbolic Logic 57(3), pp 795-807. |
|
343 <LI> <A NAME="ElliotPfenning91"></A> |
|
344 [Elliot and Pfenning, 1991]<BR> |
|
345 C. Elliot, |
|
346 <A HREF="http://foxnet.cs.cmu.edu/people/fp/homepage.html">F. Pfenning</A>, |
|
347 A Semi-Functional Implementation of a Higher-Order Programming Language, |
|
348 In Peter Lee, editor, Topics in Advanced Language Implementation, MIT Press, |
|
349 pp 289-352. |
|
350 <A HREF="http://www.cs.cmu.edu/~fp/papers/elpsml-paper.tar.gz">Available electronically</a>. |
|
351 <LI> <A NAME="HodasMiller94"></A> |
|
352 [Hodas and Miller, 1994]<BR> |
|
353 <A HREF="http://www.cs.hmc.edu/~hodas/">J. Hodas</A>, |
|
354 <A HREF="http://www.cse.psu.edu/~dale/">D. Miller</A>, |
|
355 Logic Programming in a Fragment of Intuitionistic Linear Logic, |
|
356 Information and Computation 110(2), pp 327-365. |
|
357 <A HREF="ftp://ftp.cse.psu.edu/pub/dale/ic94.ps.Z">Available electronically</a>. |
|
358 <LI> <A NAME="OderskyWadler97"></A> |
|
359 [Odersky and Wadler, 1997]<BR> |
|
360 <A HREF="http://www.cis.unisa.edu.au/~cismxo">M. Odersky</A>, |
|
361 <A HREF="http://cm.bell-labs.com/cm/cs/who/wadler/">P. Wadler</A>, |
|
362 Pizza into Java: Translating Theory into Practice, |
|
363 In Proceedings of the 24th ACM Symposium on Principles of Programming Languages. |
|
364 <A HREF="http://www.cis.unisa.edu.au/~cismxo/papers/popl97.dvi.gz">Available electronically</a>. |
|
365 <LI> <A NAME="TroelstraSchwichtenberg96"></A> |
|
366 [Troelstra and Schwichtenberg, 1996]<BR> |
|
367 <A HREF="http://turing.wins.uva.nl/~anne/">A. Troelstra</A>, |
|
368 <A HREF="http://www.mathematik.uni-muenchen.de/~gadmin6/professoren/schwichtenberg">H. Schwichtenberg</A>, |
|
369 Basic Proof Theory, Cambridge Tracts in Theoretical Computer Science, |
|
370 Cambridge University Press. |
|
371 </UL> |
|
372 |
|
373 |
|
374 <HR> |
|
375 <ADDRESS> |
|
376 <A HREF="mailto:Christian.Urban@cl.cam.ac.uk">Christian Urban</A></ADDRESS> |
|
377 |
|
378 |
|
379 <P><!-- Created: Tue Mar 4 00:23:25 GMT 1997 --> |
|
380 <!-- hhmts start --> |
|
381 Last modified: Sun Sep 23 12:04:47 BST 2001 |
|
382 <!-- hhmts end --> |
|
383 </BODY> |
|
384 </HTML> |