96
|
1 |
package G4ip;
|
|
2 |
|
|
3 |
|
|
4 |
import pizza.util.Hashtable;
|
|
5 |
import java.util.Vector;
|
|
6 |
import G4ip.Form.*;
|
|
7 |
import G4ip.ProofDisplay.*;
|
|
8 |
import G4ip.Sequent.*;
|
|
9 |
|
|
10 |
|
|
11 |
/** The Gi4p prover.<p>
|
|
12 |
* The prover is a thread in order to suspend the proof search
|
|
13 |
* after one proof is found and to let the user make a choice
|
|
14 |
* of whether to stop or to continue with the proof search.
|
|
15 |
* @author Christian Urban
|
|
16 |
*/
|
|
17 |
public class Prover extends Thread
|
|
18 |
{ ProverApplet parent; // the parent of the prover;
|
|
19 |
boolean once; // if true then at least one proof was found
|
|
20 |
Sequent sequ; // the root sequent to be proved
|
|
21 |
Vector frames; // to record all frames which have been opened
|
|
22 |
int index ;
|
|
23 |
Hashtable<int,Sequent> proof; // keeps a record of the proof
|
|
24 |
|
|
25 |
|
|
26 |
/** The constructor creates a prover which proves a specific sequent.<p>
|
|
27 |
* The parameter parent is for access to the applet buttons.
|
|
28 |
*/
|
|
29 |
public Prover(Sequent init_sequ, ProverApplet init_parent) {
|
|
30 |
super("Prover");
|
|
31 |
parent = init_parent;
|
|
32 |
once = false;
|
|
33 |
sequ = new Sequent(init_sequ);
|
|
34 |
frames = new Vector();
|
|
35 |
index = 1;
|
|
36 |
proof = new Hashtable();
|
|
37 |
}
|
|
38 |
|
|
39 |
/** Starts the thread; calls prove and stops the thread when
|
|
40 |
* the proof search is finished.
|
|
41 |
*/
|
|
42 |
public void run()
|
|
43 |
{ prove(1,sequ,initial_sc);
|
|
44 |
if (once == true) {
|
|
45 |
parent.messages.setText("No more proofs.");
|
|
46 |
parent.messages.repaint();
|
|
47 |
parent.repaint();
|
|
48 |
}
|
|
49 |
else {
|
|
50 |
parent.messages.setText("Not provable.");
|
|
51 |
parent.messages.repaint();
|
|
52 |
parent.repaint();
|
|
53 |
}
|
|
54 |
parent.switch_into_input_mode();
|
|
55 |
this.stop(); // everything is done, stop the thread
|
|
56 |
}
|
|
57 |
|
|
58 |
/** Closes all frames which have been opened.
|
|
59 |
*/
|
|
60 |
public void finalize() {
|
|
61 |
for (int i=0; i<frames.size();i++) {
|
|
62 |
if (frames.elementAt != null)
|
|
63 |
{ ((ProofDisplay)frames.elementAt(i)).dispose(); }
|
|
64 |
}
|
|
65 |
}
|
|
66 |
|
|
67 |
/** The tactic of the proof search.<p>
|
|
68 |
* Method prove first enumerates all formulae on the LHS
|
|
69 |
* as being the principal formula and attempts to apply left-rules,
|
|
70 |
* subsequently it analyses the goal formula.
|
|
71 |
*/
|
|
72 |
public void prove(int index, Sequent is,(() -> void) sc) {
|
|
73 |
Form principal;
|
|
74 |
proof.put(index,new Sequent(is)); // add sequence to proof
|
|
75 |
rightrules(index,is,sc);
|
|
76 |
for (int i=0;i<is.Gamma.size();i++) {
|
|
77 |
principal = (Form)is.Gamma.elementAt(i);
|
|
78 |
is.Gamma.removeElement(principal); // Gamma minus principal formula
|
|
79 |
leftrules(index,principal,is,sc);
|
|
80 |
is.Gamma.insertElementAt(principal,i); // put principal formula
|
|
81 |
} // back into Gamma
|
|
82 |
//rightrules(index,is,sc);
|
|
83 |
proof.remove(index); // remove sequence from proof
|
|
84 |
}
|
|
85 |
|
|
86 |
/** Analyses the goal formula.
|
|
87 |
*/
|
|
88 |
public void rightrules(int index, Sequent sequ,(() -> void) sc) {
|
|
89 |
Context Gamma = sequ.Gamma;
|
|
90 |
switch(sequ.G) {
|
|
91 |
/** And-R
|
|
92 |
* Gamma => A Gamma => B
|
|
93 |
* --------------------------
|
|
94 |
* Gamma => A and B
|
|
95 |
*/
|
|
96 |
case And(Form A,Form B):
|
|
97 |
prove(2*index,new Sequent(Gamma,A),
|
|
98 |
fun() -> void { prove(2*index+1,new Sequent(Gamma,B),sc); } );
|
|
99 |
break;
|
|
100 |
|
|
101 |
/** Imp-R
|
|
102 |
* Gamma,A => B
|
|
103 |
* -----------------
|
|
104 |
* Gamma => A imp B
|
|
105 |
*/
|
|
106 |
case Imp(Form A,Form B):
|
|
107 |
prove(2*index,new Sequent(Gamma.add(A),B),sc); break;
|
|
108 |
|
|
109 |
/** Or-R
|
|
110 |
* Gamma => A Gamma => B
|
|
111 |
* ----------------- or -----------------
|
|
112 |
* Gamma => A or B Gamma => A or B
|
|
113 |
*/
|
|
114 |
case Or(Form A,Form B):
|
|
115 |
prove(2*index,new Sequent(Gamma,A),sc);
|
|
116 |
prove(2*index,new Sequent(Gamma,B),sc); break;
|
|
117 |
|
|
118 |
/** Equ-R
|
|
119 |
* Gamma => A -> B Gamma => B -> A
|
|
120 |
* --------------------------------
|
|
121 |
* Gamma => A <-> B
|
|
122 |
*/
|
|
123 |
}
|
|
124 |
}
|
|
125 |
|
|
126 |
/** Analyses the principal formula on the LHS.
|
|
127 |
*/
|
|
128 |
public void leftrules(int index,Form principal,Sequent sequ,(() -> void) sc){
|
|
129 |
Context Gamma = sequ.Gamma;
|
|
130 |
Form G = sequ.G;
|
|
131 |
switch(principal) {
|
|
132 |
/** false-L
|
|
133 |
* --------------------
|
|
134 |
* false, Gamma => G
|
|
135 |
*/
|
|
136 |
case False(): sc(); break;
|
|
137 |
|
|
138 |
/** Axiom
|
|
139 |
* ---------------
|
|
140 |
* Gamma, G => G G being atomic
|
|
141 |
*/
|
|
142 |
case Atm(String c):
|
|
143 |
if (G instanceof Atm) {
|
|
144 |
if (((Atm)G).c.compareTo(c) == 0) { sc(); }
|
|
145 |
}
|
|
146 |
break;
|
|
147 |
|
|
148 |
/** And-L
|
|
149 |
* Gamma, A, B => G
|
|
150 |
* --------------------
|
|
151 |
* Gamma, A and B => G
|
|
152 |
*/
|
|
153 |
|
|
154 |
case And(Form A, Form B):
|
|
155 |
prove(2*index,new Sequent(Gamma.add(A,B),G),sc); break;
|
|
156 |
|
|
157 |
/** Or-R
|
|
158 |
* Gamma, A => G Gamma, B => G
|
|
159 |
* -------------------------------
|
|
160 |
* Gamma, A or B => G
|
|
161 |
*/
|
|
162 |
case Or(Form A, Form B):
|
|
163 |
prove(2*index,new Sequent(Gamma.add(A),G),
|
|
164 |
fun() -> void {prove(2*index+1,new Sequent(Gamma.add(B),G),sc);});
|
|
165 |
break;
|
|
166 |
|
|
167 |
/** Imp-L 2
|
|
168 |
* Gamma, A imp (B imp C) => G
|
|
169 |
* ------------------------------
|
|
170 |
* Gamma, (A and B) imp C => G
|
|
171 |
*/
|
|
172 |
case Imp(And(Form A, Form B), Form C):
|
|
173 |
prove(2*index,new Sequent(Gamma.add(Imp(A,Imp(B,C))),G),sc); break;
|
|
174 |
|
|
175 |
|
|
176 |
/** Imp-L 3
|
|
177 |
* Gamma, (A imp C), (B imp C) => G
|
|
178 |
* ----------------------------------
|
|
179 |
* Gamma, (A or B) imp C => G
|
|
180 |
*/
|
|
181 |
case Imp(Or(Form A, Form B), Form C):
|
|
182 |
prove(2*index,new Sequent(Gamma.add(Imp(A,C),Imp(B,C)),G),sc); break;
|
|
183 |
|
|
184 |
/** Imp-L 4
|
|
185 |
* Gamma, (B imp C) => (A imp B) Gamma, C => G
|
|
186 |
* ------------------------------------------------
|
|
187 |
* Gamma, (A imp B) imp C => G
|
|
188 |
*/
|
|
189 |
case Imp(Imp(Form A, Form B), Form C):
|
|
190 |
prove(2*index,new Sequent(Gamma.add(Imp(B,C)),Imp(A,B)),
|
|
191 |
fun() -> void { prove(2*index+1,new Sequent(Gamma.add(C),G),sc);});
|
|
192 |
break;
|
|
193 |
/** Imp-L 1
|
|
194 |
* Gamma(A), B => G A being atomic
|
|
195 |
* ------------------------ Gamma(A) means:
|
|
196 |
* Gamma(A), A imp B => G Gamma contains A
|
|
197 |
*/
|
|
198 |
case Imp(Form A, Form B):
|
|
199 |
if (A instanceof Atm) {
|
|
200 |
if (Gamma.includes(A)) {
|
|
201 |
{ prove(2*index,new Sequent(Gamma.add(B),G),sc); }
|
|
202 |
}
|
|
203 |
}
|
|
204 |
break;
|
|
205 |
}
|
|
206 |
|
|
207 |
}
|
|
208 |
|
|
209 |
|
|
210 |
/** The initial success continuation.
|
|
211 |
* Suspends the thread when a proof is found.
|
|
212 |
*/
|
|
213 |
public void initial_sc() {
|
|
214 |
once = true;
|
|
215 |
ProofDisplay p = new ProofDisplay(proof);
|
|
216 |
frames.addElement(p); // keep a record for later disposal
|
|
217 |
try { // suspend the proof search,
|
|
218 |
suspend(); } // it might be resumed later on by the user
|
|
219 |
catch(SecurityException sec_exc)
|
|
220 |
{ /* this catch is neccessary for Netscape 3.0 (Linux) */ }
|
|
221 |
}
|
|
222 |
|
|
223 |
}
|