Prover/index.html
changeset 96 907b1fff5637
equal deleted inserted replaced
95:345dd18f020e 96:907b1fff5637
       
     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>&nbsp;&nbsp;    case False();              </DD>    
       
   104 <DD>&nbsp;&nbsp;    case Atm(String c);        </DD>  
       
   105 <DD>&nbsp;&nbsp;    case And(Form c1,Form c2); </DD>
       
   106 <DD>&nbsp;&nbsp;    case Or(Form c1,Form c2);  </DD>
       
   107 <DD>&nbsp;&nbsp;    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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p -> p &nbsp;</CODE> 
       
   116 is represented as   <CODE> &nbsp; Imp(Atm("p"),Atm("p"))</CODE><BR>
       
   117 <CODE>a v (a -> false) &nbsp;</CODE> is represented as  <CODE> &nbsp; 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>&nbsp;&nbsp; Form  G;                                      </DD>         
       
   132 <DD>&nbsp;&nbsp; Context Gamma;                                </DD>
       
   133 <DD>&nbsp;&nbsp; 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>&nbsp;&nbsp; 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>&nbsp;&nbsp; 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>&nbsp;&nbsp; prove(new Sequent(Gamma,B1),sc);</DD>
       
   227 <DD>&nbsp;&nbsp; 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>&nbsp;&nbsp; prove(new Sequent(Gamma.add(B),G),</DD>
       
   243 <DD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
       
   244       fun()->void {prove(new Sequent(Gamma.add(C),G),sc);}</DD>
       
   245 <DD>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ); 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>&nbsp;&nbsp; if (G instanceof Atm) { </DD>
       
   258 <DD>&nbsp;&nbsp; &nbsp;&nbsp; if (G.c.compareTo(c) == 0) { sc(); }</DD>
       
   259 <DD>&nbsp;&nbsp; } 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>