91 |
91 |
92 val weakening_thm = @{lemma "[| P; Q |] ==> Q" by auto}; |
92 val weakening_thm = @{lemma "[| P; Q |] ==> Q" by auto}; |
93 |
93 |
94 val cnftac_eq_imp = @{lemma "[| P = Q; P |] ==> Q" by auto}; |
94 val cnftac_eq_imp = @{lemma "[| P = Q; P |] ==> Q" by auto}; |
95 |
95 |
96 fun is_atom (Const ("False", _)) = false |
96 fun is_atom (Const (@{const_name "False"}, _)) = false |
97 | is_atom (Const ("True", _)) = false |
97 | is_atom (Const (@{const_name "True"}, _)) = false |
98 | is_atom (Const ("op &", _) $ _ $ _) = false |
98 | is_atom (Const (@{const_name "op &"}, _) $ _ $ _) = false |
99 | is_atom (Const ("op |", _) $ _ $ _) = false |
99 | is_atom (Const (@{const_name "op |"}, _) $ _ $ _) = false |
100 | is_atom (Const ("op -->", _) $ _ $ _) = false |
100 | is_atom (Const (@{const_name "op -->"}, _) $ _ $ _) = false |
101 | is_atom (Const ("op =", Type ("fun", Type ("bool", []) :: _)) $ _ $ _) = false |
101 | is_atom (Const (@{const_name "op ="}, Type ("fun", Type ("bool", []) :: _)) $ _ $ _) = false |
102 | is_atom (Const ("Not", _) $ _) = false |
102 | is_atom (Const (@{const_name "Not"}, _) $ _) = false |
103 | is_atom _ = true; |
103 | is_atom _ = true; |
104 |
104 |
105 fun is_literal (Const ("Not", _) $ x) = is_atom x |
105 fun is_literal (Const (@{const_name "Not"}, _) $ x) = is_atom x |
106 | is_literal x = is_atom x; |
106 | is_literal x = is_atom x; |
107 |
107 |
108 fun is_clause (Const ("op |", _) $ x $ y) = is_clause x andalso is_clause y |
108 fun is_clause (Const (@{const_name "op |"}, _) $ x $ y) = is_clause x andalso is_clause y |
109 | is_clause x = is_literal x; |
109 | is_clause x = is_literal x; |
110 |
110 |
111 (* ------------------------------------------------------------------------- *) |
111 (* ------------------------------------------------------------------------- *) |
112 (* clause_is_trivial: a clause is trivially true if it contains both an atom *) |
112 (* clause_is_trivial: a clause is trivially true if it contains both an atom *) |
113 (* and the atom's negation *) |
113 (* and the atom's negation *) |
182 (* eliminated (possibly causing an exponential blowup) *) |
182 (* eliminated (possibly causing an exponential blowup) *) |
183 (* ------------------------------------------------------------------------- *) |
183 (* ------------------------------------------------------------------------- *) |
184 |
184 |
185 (* Theory.theory -> Term.term -> Thm.thm *) |
185 (* Theory.theory -> Term.term -> Thm.thm *) |
186 |
186 |
187 fun make_nnf_thm thy (Const ("op &", _) $ x $ y) = |
187 fun make_nnf_thm thy (Const (@{const_name "op &"}, _) $ x $ y) = |
188 let |
188 let |
189 val thm1 = make_nnf_thm thy x |
189 val thm1 = make_nnf_thm thy x |
190 val thm2 = make_nnf_thm thy y |
190 val thm2 = make_nnf_thm thy y |
191 in |
191 in |
192 conj_cong OF [thm1, thm2] |
192 conj_cong OF [thm1, thm2] |
193 end |
193 end |
194 | make_nnf_thm thy (Const ("op |", _) $ x $ y) = |
194 | make_nnf_thm thy (Const (@{const_name "op |"}, _) $ x $ y) = |
195 let |
195 let |
196 val thm1 = make_nnf_thm thy x |
196 val thm1 = make_nnf_thm thy x |
197 val thm2 = make_nnf_thm thy y |
197 val thm2 = make_nnf_thm thy y |
198 in |
198 in |
199 disj_cong OF [thm1, thm2] |
199 disj_cong OF [thm1, thm2] |
200 end |
200 end |
201 | make_nnf_thm thy (Const ("op -->", _) $ x $ y) = |
201 | make_nnf_thm thy (Const (@{const_name "op -->"}, _) $ x $ y) = |
202 let |
202 let |
203 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
203 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
204 val thm2 = make_nnf_thm thy y |
204 val thm2 = make_nnf_thm thy y |
205 in |
205 in |
206 make_nnf_imp OF [thm1, thm2] |
206 make_nnf_imp OF [thm1, thm2] |
207 end |
207 end |
208 | make_nnf_thm thy (Const ("op =", Type ("fun", Type ("bool", []) :: _)) $ x $ y) = |
208 | make_nnf_thm thy (Const (@{const_name "op ="}, Type ("fun", Type ("bool", []) :: _)) $ x $ y) = |
209 let |
209 let |
210 val thm1 = make_nnf_thm thy x |
210 val thm1 = make_nnf_thm thy x |
211 val thm2 = make_nnf_thm thy (HOLogic.Not $ x) |
211 val thm2 = make_nnf_thm thy (HOLogic.Not $ x) |
212 val thm3 = make_nnf_thm thy y |
212 val thm3 = make_nnf_thm thy y |
213 val thm4 = make_nnf_thm thy (HOLogic.Not $ y) |
213 val thm4 = make_nnf_thm thy (HOLogic.Not $ y) |
214 in |
214 in |
215 make_nnf_iff OF [thm1, thm2, thm3, thm4] |
215 make_nnf_iff OF [thm1, thm2, thm3, thm4] |
216 end |
216 end |
217 | make_nnf_thm thy (Const ("Not", _) $ Const ("False", _)) = |
217 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ Const (@{const_name "False"}, _)) = |
218 make_nnf_not_false |
218 make_nnf_not_false |
219 | make_nnf_thm thy (Const ("Not", _) $ Const ("True", _)) = |
219 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ Const (@{const_name "True"}, _)) = |
220 make_nnf_not_true |
220 make_nnf_not_true |
221 | make_nnf_thm thy (Const ("Not", _) $ (Const ("op &", _) $ x $ y)) = |
221 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ (Const (@{const_name "op &"}, _) $ x $ y)) = |
222 let |
222 let |
223 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
223 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
224 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
224 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
225 in |
225 in |
226 make_nnf_not_conj OF [thm1, thm2] |
226 make_nnf_not_conj OF [thm1, thm2] |
227 end |
227 end |
228 | make_nnf_thm thy (Const ("Not", _) $ (Const ("op |", _) $ x $ y)) = |
228 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ (Const (@{const_name "op |"}, _) $ x $ y)) = |
229 let |
229 let |
230 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
230 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
231 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
231 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
232 in |
232 in |
233 make_nnf_not_disj OF [thm1, thm2] |
233 make_nnf_not_disj OF [thm1, thm2] |
234 end |
234 end |
235 | make_nnf_thm thy (Const ("Not", _) $ (Const ("op -->", _) $ x $ y)) = |
235 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ (Const (@{const_name "op -->"}, _) $ x $ y)) = |
236 let |
236 let |
237 val thm1 = make_nnf_thm thy x |
237 val thm1 = make_nnf_thm thy x |
238 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
238 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
239 in |
239 in |
240 make_nnf_not_imp OF [thm1, thm2] |
240 make_nnf_not_imp OF [thm1, thm2] |
241 end |
241 end |
242 | make_nnf_thm thy (Const ("Not", _) $ (Const ("op =", Type ("fun", Type ("bool", []) :: _)) $ x $ y)) = |
242 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ (Const (@{const_name "op ="}, Type ("fun", Type ("bool", []) :: _)) $ x $ y)) = |
243 let |
243 let |
244 val thm1 = make_nnf_thm thy x |
244 val thm1 = make_nnf_thm thy x |
245 val thm2 = make_nnf_thm thy (HOLogic.Not $ x) |
245 val thm2 = make_nnf_thm thy (HOLogic.Not $ x) |
246 val thm3 = make_nnf_thm thy y |
246 val thm3 = make_nnf_thm thy y |
247 val thm4 = make_nnf_thm thy (HOLogic.Not $ y) |
247 val thm4 = make_nnf_thm thy (HOLogic.Not $ y) |
248 in |
248 in |
249 make_nnf_not_iff OF [thm1, thm2, thm3, thm4] |
249 make_nnf_not_iff OF [thm1, thm2, thm3, thm4] |
250 end |
250 end |
251 | make_nnf_thm thy (Const ("Not", _) $ (Const ("Not", _) $ x)) = |
251 | make_nnf_thm thy (Const (@{const_name "Not"}, _) $ (Const (@{const_name "Not"}, _) $ x)) = |
252 let |
252 let |
253 val thm1 = make_nnf_thm thy x |
253 val thm1 = make_nnf_thm thy x |
254 in |
254 in |
255 make_nnf_not_not OF [thm1] |
255 make_nnf_not_not OF [thm1] |
256 end |
256 end |
332 (* Theory.theory -> Term.term -> Thm.thm *) |
332 (* Theory.theory -> Term.term -> Thm.thm *) |
333 |
333 |
334 fun make_cnf_thm thy t = |
334 fun make_cnf_thm thy t = |
335 let |
335 let |
336 (* Term.term -> Thm.thm *) |
336 (* Term.term -> Thm.thm *) |
337 fun make_cnf_thm_from_nnf (Const ("op &", _) $ x $ y) = |
337 fun make_cnf_thm_from_nnf (Const (@{const_name "op &"}, _) $ x $ y) = |
338 let |
338 let |
339 val thm1 = make_cnf_thm_from_nnf x |
339 val thm1 = make_cnf_thm_from_nnf x |
340 val thm2 = make_cnf_thm_from_nnf y |
340 val thm2 = make_cnf_thm_from_nnf y |
341 in |
341 in |
342 conj_cong OF [thm1, thm2] |
342 conj_cong OF [thm1, thm2] |
343 end |
343 end |
344 | make_cnf_thm_from_nnf (Const ("op |", _) $ x $ y) = |
344 | make_cnf_thm_from_nnf (Const (@{const_name "op |"}, _) $ x $ y) = |
345 let |
345 let |
346 (* produces a theorem "(x' | y') = t'", where x', y', and t' are in CNF *) |
346 (* produces a theorem "(x' | y') = t'", where x', y', and t' are in CNF *) |
347 fun make_cnf_disj_thm (Const ("op &", _) $ x1 $ x2) y' = |
347 fun make_cnf_disj_thm (Const (@{const_name "op &"}, _) $ x1 $ x2) y' = |
348 let |
348 let |
349 val thm1 = make_cnf_disj_thm x1 y' |
349 val thm1 = make_cnf_disj_thm x1 y' |
350 val thm2 = make_cnf_disj_thm x2 y' |
350 val thm2 = make_cnf_disj_thm x2 y' |
351 in |
351 in |
352 make_cnf_disj_conj_l OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
352 make_cnf_disj_conj_l OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
353 end |
353 end |
354 | make_cnf_disj_thm x' (Const ("op &", _) $ y1 $ y2) = |
354 | make_cnf_disj_thm x' (Const (@{const_name "op &"}, _) $ y1 $ y2) = |
355 let |
355 let |
356 val thm1 = make_cnf_disj_thm x' y1 |
356 val thm1 = make_cnf_disj_thm x' y1 |
357 val thm2 = make_cnf_disj_thm x' y2 |
357 val thm2 = make_cnf_disj_thm x' y2 |
358 in |
358 in |
359 make_cnf_disj_conj_r OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
359 make_cnf_disj_conj_r OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
401 fun make_cnfx_thm thy t = |
401 fun make_cnfx_thm thy t = |
402 let |
402 let |
403 val var_id = Unsynchronized.ref 0 (* properly initialized below *) |
403 val var_id = Unsynchronized.ref 0 (* properly initialized below *) |
404 fun new_free () = |
404 fun new_free () = |
405 Free ("cnfx_" ^ string_of_int (Unsynchronized.inc var_id), HOLogic.boolT) |
405 Free ("cnfx_" ^ string_of_int (Unsynchronized.inc var_id), HOLogic.boolT) |
406 fun make_cnfx_thm_from_nnf (Const ("op &", _) $ x $ y) : thm = |
406 fun make_cnfx_thm_from_nnf (Const (@{const_name "op &"}, _) $ x $ y) : thm = |
407 let |
407 let |
408 val thm1 = make_cnfx_thm_from_nnf x |
408 val thm1 = make_cnfx_thm_from_nnf x |
409 val thm2 = make_cnfx_thm_from_nnf y |
409 val thm2 = make_cnfx_thm_from_nnf y |
410 in |
410 in |
411 conj_cong OF [thm1, thm2] |
411 conj_cong OF [thm1, thm2] |
412 end |
412 end |
413 | make_cnfx_thm_from_nnf (Const ("op |", _) $ x $ y) = |
413 | make_cnfx_thm_from_nnf (Const (@{const_name "op |"}, _) $ x $ y) = |
414 if is_clause x andalso is_clause y then |
414 if is_clause x andalso is_clause y then |
415 inst_thm thy [HOLogic.mk_disj (x, y)] iff_refl |
415 inst_thm thy [HOLogic.mk_disj (x, y)] iff_refl |
416 else if is_literal y orelse is_literal x then let |
416 else if is_literal y orelse is_literal x then let |
417 (* produces a theorem "(x' | y') = t'", where x', y', and t' are *) |
417 (* produces a theorem "(x' | y') = t'", where x', y', and t' are *) |
418 (* almost in CNF, and x' or y' is a literal *) |
418 (* almost in CNF, and x' or y' is a literal *) |
419 fun make_cnfx_disj_thm (Const ("op &", _) $ x1 $ x2) y' = |
419 fun make_cnfx_disj_thm (Const (@{const_name "op &"}, _) $ x1 $ x2) y' = |
420 let |
420 let |
421 val thm1 = make_cnfx_disj_thm x1 y' |
421 val thm1 = make_cnfx_disj_thm x1 y' |
422 val thm2 = make_cnfx_disj_thm x2 y' |
422 val thm2 = make_cnfx_disj_thm x2 y' |
423 in |
423 in |
424 make_cnf_disj_conj_l OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
424 make_cnf_disj_conj_l OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
425 end |
425 end |
426 | make_cnfx_disj_thm x' (Const ("op &", _) $ y1 $ y2) = |
426 | make_cnfx_disj_thm x' (Const (@{const_name "op &"}, _) $ y1 $ y2) = |
427 let |
427 let |
428 val thm1 = make_cnfx_disj_thm x' y1 |
428 val thm1 = make_cnfx_disj_thm x' y1 |
429 val thm2 = make_cnfx_disj_thm x' y2 |
429 val thm2 = make_cnfx_disj_thm x' y2 |
430 in |
430 in |
431 make_cnf_disj_conj_r OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
431 make_cnf_disj_conj_r OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
432 end |
432 end |
433 | make_cnfx_disj_thm (Const ("Ex", _) $ x') y' = |
433 | make_cnfx_disj_thm (Const (@{const_name "Ex"}, _) $ x') y' = |
434 let |
434 let |
435 val thm1 = inst_thm thy [x', y'] make_cnfx_disj_ex_l (* ((Ex x') | y') = (Ex (x' | y')) *) |
435 val thm1 = inst_thm thy [x', y'] make_cnfx_disj_ex_l (* ((Ex x') | y') = (Ex (x' | y')) *) |
436 val var = new_free () |
436 val var = new_free () |
437 val thm2 = make_cnfx_disj_thm (betapply (x', var)) y' (* (x' | y') = body' *) |
437 val thm2 = make_cnfx_disj_thm (betapply (x', var)) y' (* (x' | y') = body' *) |
438 val thm3 = Thm.forall_intr (cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |
438 val thm3 = Thm.forall_intr (cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |
439 val thm4 = Thm.strip_shyps (thm3 COMP allI) (* ALL v. (x' | y') = body' *) |
439 val thm4 = Thm.strip_shyps (thm3 COMP allI) (* ALL v. (x' | y') = body' *) |
440 val thm5 = Thm.strip_shyps (thm4 RS make_cnfx_ex_cong) (* (EX v. (x' | y')) = (EX v. body') *) |
440 val thm5 = Thm.strip_shyps (thm4 RS make_cnfx_ex_cong) (* (EX v. (x' | y')) = (EX v. body') *) |
441 in |
441 in |
442 iff_trans OF [thm1, thm5] (* ((Ex x') | y') = (Ex v. body') *) |
442 iff_trans OF [thm1, thm5] (* ((Ex x') | y') = (Ex v. body') *) |
443 end |
443 end |
444 | make_cnfx_disj_thm x' (Const ("Ex", _) $ y') = |
444 | make_cnfx_disj_thm x' (Const (@{const_name "Ex"}, _) $ y') = |
445 let |
445 let |
446 val thm1 = inst_thm thy [x', y'] make_cnfx_disj_ex_r (* (x' | (Ex y')) = (Ex (x' | y')) *) |
446 val thm1 = inst_thm thy [x', y'] make_cnfx_disj_ex_r (* (x' | (Ex y')) = (Ex (x' | y')) *) |
447 val var = new_free () |
447 val var = new_free () |
448 val thm2 = make_cnfx_disj_thm x' (betapply (y', var)) (* (x' | y') = body' *) |
448 val thm2 = make_cnfx_disj_thm x' (betapply (y', var)) (* (x' | y') = body' *) |
449 val thm3 = Thm.forall_intr (cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |
449 val thm3 = Thm.forall_intr (cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |