21 |
21 |
22 For the purpose of SAT proof reconstruction, we also make use of another |
22 For the purpose of SAT proof reconstruction, we also make use of another |
23 representation of clauses, which we call the "raw clauses". |
23 representation of clauses, which we call the "raw clauses". |
24 Raw clauses are of the form |
24 Raw clauses are of the form |
25 |
25 |
26 x1', x2', ..., xn', ~ (x1 | x2 | ... | xn) ==> False |- False , |
26 [..., x1', x2', ..., xn'] |- False , |
27 |
27 |
28 where each xi is a literal, and each xi' is the negation normal form of ~xi. |
28 where each xi is a literal, and each xi' is the negation normal form of ~xi. |
29 |
29 |
30 Raw clauses may contain further hyps of the form "~ clause ==> False". |
|
31 Literals are successively removed from the hyps of raw clauses by resolution |
30 Literals are successively removed from the hyps of raw clauses by resolution |
32 during SAT proof reconstruction. |
31 during SAT proof reconstruction. |
33 *) |
32 *) |
34 |
33 |
35 signature CNF = |
34 signature CNF = |
138 has_duals (collect_literals c []) |
135 has_duals (collect_literals c []) |
139 end; |
136 end; |
140 |
137 |
141 (* ------------------------------------------------------------------------- *) |
138 (* ------------------------------------------------------------------------- *) |
142 (* clause2raw_thm: translates a clause into a raw clause, i.e. *) |
139 (* clause2raw_thm: translates a clause into a raw clause, i.e. *) |
143 (* ... |- x1 | ... | xn *) |
140 (* [...] |- x1 | ... | xn *) |
144 (* (where each xi is a literal) is translated to *) |
141 (* (where each xi is a literal) is translated to *) |
145 (* ~(x1 | ... | xn) ==> False, x1', ..., xn' |- False , *) |
142 (* [..., x1', ..., xn'] |- False , *) |
146 (* where each xi' is the negation normal form of ~xi. *) |
143 (* where each xi' is the negation normal form of ~xi *) |
147 (* ------------------------------------------------------------------------- *) |
144 (* ------------------------------------------------------------------------- *) |
148 |
145 |
149 (* Thm.thm -> Thm.thm *) |
146 (* Thm.thm -> Thm.thm *) |
150 |
147 |
151 fun clause2raw_thm c = |
148 fun clause2raw_thm clause = |
152 let |
149 let |
153 val disj = HOLogic.dest_Trueprop (prop_of c) |
|
154 val not_disj_imp_false = Logic.mk_implies (HOLogic.mk_Trueprop (HOLogic.mk_not disj), HOLogic.mk_Trueprop HOLogic.false_const) |
|
155 val thm1 = Thm.assume (cterm_of (theory_of_thm c) not_disj_imp_false) (* ~(x1 | ... | xn) ==> False |- ~(x1 | ... | xn) ==> False *) |
|
156 (* eliminates negated disjunctions from the i-th premise, possibly *) |
150 (* eliminates negated disjunctions from the i-th premise, possibly *) |
157 (* adding new premises, then continues with the (i+1)-th premise *) |
151 (* adding new premises, then continues with the (i+1)-th premise *) |
158 (* Thm.thm -> int -> Thm.thm *) |
152 (* int -> Thm.thm -> Thm.thm *) |
159 fun not_disj_to_prem thm i = |
153 fun not_disj_to_prem i thm = |
160 if i > nprems_of thm then |
154 if i > nprems_of thm then |
161 thm |
155 thm |
162 else |
156 else |
163 not_disj_to_prem (Seq.hd (REPEAT_DETERM (rtac clause2raw_not_disj i) thm)) (i+1) |
157 not_disj_to_prem (i+1) (Seq.hd (REPEAT_DETERM (rtac clause2raw_not_disj i) thm)) |
164 val thm2 = not_disj_to_prem thm1 1 (* ~(x1 | ... | xn) ==> False |- ~x1 ==> ... ==> ~xn ==> False *) |
158 (* moves all premises to hyps, i.e. "[...] |- A1 ==> ... ==> An ==> B" *) |
165 val thm3 = Seq.hd (TRYALL (rtac clause2raw_not_not) thm2) (* ~(x1 | ... | xn) ==> False |- x1' ==> ... ==> xn' ==> False *) |
159 (* becomes "[..., A1, ..., An] |- B" *) |
166 val thy3 = theory_of_thm thm3 |
160 (* Thm.thm -> Thm.thm *) |
167 val thm4 = fold (fn prem => fn thm => Thm.implies_elim thm (Thm.assume (cterm_of thy3 prem))) (prems_of thm3) thm3 (* ~(x1 | ... | xn) ==> False, x1', ..., xn' |- False *) |
161 fun prems_to_hyps thm = |
|
162 fold (fn cprem => fn thm' => |
|
163 Thm.implies_elim thm' (Thm.assume cprem)) (cprems_of thm) thm |
168 in |
164 in |
169 thm4 |
165 (* [...] |- ~(x1 | ... | xn) ==> False *) |
|
166 (clause2raw_notE OF [clause]) |
|
167 (* [...] |- ~x1 ==> ... ==> ~xn ==> False *) |
|
168 |> not_disj_to_prem 1 |
|
169 (* [...] |- x1' ==> ... ==> xn' ==> False *) |
|
170 |> Seq.hd o TRYALL (rtac clause2raw_not_not) |
|
171 (* [..., x1', ..., xn'] |- False *) |
|
172 |> prems_to_hyps |
170 end; |
173 end; |
171 |
|
172 (* ------------------------------------------------------------------------- *) |
|
173 (* rawhyps2clausehyps_thm: translates all hyps of the form "~P ==> False" to *) |
|
174 (* hyps of the form "P" *) |
|
175 (* ------------------------------------------------------------------------- *) |
|
176 |
|
177 (* Thm.thm -> Thm.thm *) |
|
178 |
|
179 fun rawhyps2clausehyps_thm c = |
|
180 fold (fn hyp => fn thm => |
|
181 case hyp of Const ("==>", _) $ (Const ("Trueprop", _) $ (Const ("Not", _) $ P)) $ (Const ("Trueprop", _) $ Const ("False", _)) => |
|
182 let |
|
183 val cterm = cterm_of (theory_of_thm thm) |
|
184 val thm1 = Thm.implies_intr (cterm hyp) thm (* hyps |- (~P ==> False) ==> goal *) |
|
185 val varP = Var (("P", 0), HOLogic.boolT) |
|
186 val notE = Thm.instantiate ([], [(cterm varP, cterm P)]) clause2raw_notE (* P ==> ~P ==> False *) |
|
187 val notE' = Thm.implies_elim notE (Thm.assume (cterm (HOLogic.mk_Trueprop P))) (* P |- ~P ==> False *) |
|
188 val thm2 = Thm.implies_elim thm1 notE' (* hyps, P |- goal *) |
|
189 in |
|
190 thm2 |
|
191 end |
|
192 | _ => |
|
193 thm) (#hyps (rep_thm c)) c; |
|
194 |
174 |
195 (* ------------------------------------------------------------------------- *) |
175 (* ------------------------------------------------------------------------- *) |
196 (* inst_thm: instantiates a theorem with a list of terms *) |
176 (* inst_thm: instantiates a theorem with a list of terms *) |
197 (* ------------------------------------------------------------------------- *) |
177 (* ------------------------------------------------------------------------- *) |
198 |
178 |