package G4ip; import pizza.util.Hashtable; import java.util.Vector; import G4ip.Form.*; import G4ip.ProofDisplay.*; import G4ip.Sequent.*; /** The Gi4p prover.

* The prover is a thread in order to suspend the proof search * after one proof is found and to let the user make a choice * of whether to stop or to continue with the proof search. * @author Christian Urban */ public class Prover extends Thread { ProverApplet parent; // the parent of the prover; boolean once; // if true then at least one proof was found Sequent sequ; // the root sequent to be proved Vector frames; // to record all frames which have been opened int index ; Hashtable proof; // keeps a record of the proof /** The constructor creates a prover which proves a specific sequent.

* The parameter parent is for access to the applet buttons. */ public Prover(Sequent init_sequ, ProverApplet init_parent) { super("Prover"); parent = init_parent; once = false; sequ = new Sequent(init_sequ); frames = new Vector(); index = 1; proof = new Hashtable(); } /** Starts the thread; calls prove and stops the thread when * the proof search is finished. */ public void run() { prove(1,sequ,initial_sc); if (once == true) { parent.messages.setText("No more proofs."); parent.messages.repaint(); parent.repaint(); } else { parent.messages.setText("Not provable."); parent.messages.repaint(); parent.repaint(); } parent.switch_into_input_mode(); this.stop(); // everything is done, stop the thread } /** Closes all frames which have been opened. */ public void finalize() { for (int i=0; i * Method prove first enumerates all formulae on the LHS * as being the principal formula and attempts to apply left-rules, * subsequently it analyses the goal formula. */ public void prove(int index, Sequent is,(() -> void) sc) { Form principal; proof.put(index,new Sequent(is)); // add sequence to proof rightrules(index,is,sc); for (int i=0;i void) sc) { Context Gamma = sequ.Gamma; switch(sequ.G) { /** And-R * Gamma => A Gamma => B * -------------------------- * Gamma => A and B */ case And(Form A,Form B): prove(2*index,new Sequent(Gamma,A), fun() -> void { prove(2*index+1,new Sequent(Gamma,B),sc); } ); break; /** Imp-R * Gamma,A => B * ----------------- * Gamma => A imp B */ case Imp(Form A,Form B): prove(2*index,new Sequent(Gamma.add(A),B),sc); break; /** Or-R * Gamma => A Gamma => B * ----------------- or ----------------- * Gamma => A or B Gamma => A or B */ case Or(Form A,Form B): prove(2*index,new Sequent(Gamma,A),sc); prove(2*index,new Sequent(Gamma,B),sc); break; /** Equ-R * Gamma => A -> B Gamma => B -> A * -------------------------------- * Gamma => A <-> B */ } } /** Analyses the principal formula on the LHS. */ public void leftrules(int index,Form principal,Sequent sequ,(() -> void) sc){ Context Gamma = sequ.Gamma; Form G = sequ.G; switch(principal) { /** false-L * -------------------- * false, Gamma => G */ case False(): sc(); break; /** Axiom * --------------- * Gamma, G => G G being atomic */ case Atm(String c): if (G instanceof Atm) { if (((Atm)G).c.compareTo(c) == 0) { sc(); } } break; /** And-L * Gamma, A, B => G * -------------------- * Gamma, A and B => G */ case And(Form A, Form B): prove(2*index,new Sequent(Gamma.add(A,B),G),sc); break; /** Or-R * Gamma, A => G Gamma, B => G * ------------------------------- * Gamma, A or B => G */ case Or(Form A, Form B): prove(2*index,new Sequent(Gamma.add(A),G), fun() -> void {prove(2*index+1,new Sequent(Gamma.add(B),G),sc);}); break; /** Imp-L 2 * Gamma, A imp (B imp C) => G * ------------------------------ * Gamma, (A and B) imp C => G */ case Imp(And(Form A, Form B), Form C): prove(2*index,new Sequent(Gamma.add(Imp(A,Imp(B,C))),G),sc); break; /** Imp-L 3 * Gamma, (A imp C), (B imp C) => G * ---------------------------------- * Gamma, (A or B) imp C => G */ case Imp(Or(Form A, Form B), Form C): prove(2*index,new Sequent(Gamma.add(Imp(A,C),Imp(B,C)),G),sc); break; /** Imp-L 4 * Gamma, (B imp C) => (A imp B) Gamma, C => G * ------------------------------------------------ * Gamma, (A imp B) imp C => G */ case Imp(Imp(Form A, Form B), Form C): prove(2*index,new Sequent(Gamma.add(Imp(B,C)),Imp(A,B)), fun() -> void { prove(2*index+1,new Sequent(Gamma.add(C),G),sc);}); break; /** Imp-L 1 * Gamma(A), B => G A being atomic * ------------------------ Gamma(A) means: * Gamma(A), A imp B => G Gamma contains A */ case Imp(Form A, Form B): if (A instanceof Atm) { if (Gamma.includes(A)) { { prove(2*index,new Sequent(Gamma.add(B),G),sc); } } } break; } } /** The initial success continuation. * Suspends the thread when a proof is found. */ public void initial_sc() { once = true; ProofDisplay p = new ProofDisplay(proof); frames.addElement(p); // keep a record for later disposal try { // suspend the proof search, suspend(); } // it might be resumed later on by the user catch(SecurityException sec_exc) { /* this catch is neccessary for Netscape 3.0 (Linux) */ } } }