52 end; |
52 end; |
53 |
53 |
54 structure CNF : CNF = |
54 structure CNF : CNF = |
55 struct |
55 struct |
56 |
56 |
57 fun is_atom (Const (\<^const_name>\<open>False\<close>, _)) = false |
57 fun is_atom \<^Const_>\<open>False\<close> = false |
58 | is_atom (Const (\<^const_name>\<open>True\<close>, _)) = false |
58 | is_atom \<^Const_>\<open>True\<close> = false |
59 | is_atom (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ _ $ _) = false |
59 | is_atom \<^Const_>\<open>conj for _ _\<close> = false |
60 | is_atom (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ _ $ _) = false |
60 | is_atom \<^Const_>\<open>disj for _ _\<close> = false |
61 | is_atom (Const (\<^const_name>\<open>HOL.implies\<close>, _) $ _ $ _) = false |
61 | is_atom \<^Const_>\<open>implies for _ _\<close> = false |
62 | is_atom (Const (\<^const_name>\<open>HOL.eq\<close>, Type ("fun", \<^typ>\<open>bool\<close> :: _)) $ _ $ _) = false |
62 | is_atom \<^Const_>\<open>HOL.eq \<^Type>\<open>bool\<close> for _ _\<close> = false |
63 | is_atom (Const (\<^const_name>\<open>Not\<close>, _) $ _) = false |
63 | is_atom \<^Const_>\<open>Not for _\<close> = false |
64 | is_atom _ = true; |
64 | is_atom _ = true; |
65 |
65 |
66 fun is_literal (Const (\<^const_name>\<open>Not\<close>, _) $ x) = is_atom x |
66 fun is_literal \<^Const_>\<open>Not for x\<close> = is_atom x |
67 | is_literal x = is_atom x; |
67 | is_literal x = is_atom x; |
68 |
68 |
69 fun is_clause (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ x $ y) = is_clause x andalso is_clause y |
69 fun is_clause \<^Const_>\<open>disj for x y\<close> = is_clause x andalso is_clause y |
70 | is_clause x = is_literal x; |
70 | is_clause x = is_literal x; |
71 |
71 |
72 (* ------------------------------------------------------------------------- *) |
72 (* ------------------------------------------------------------------------- *) |
73 (* clause_is_trivial: a clause is trivially true if it contains both an atom *) |
73 (* clause_is_trivial: a clause is trivially true if it contains both an atom *) |
74 (* and the atom's negation *) |
74 (* and the atom's negation *) |
75 (* ------------------------------------------------------------------------- *) |
75 (* ------------------------------------------------------------------------- *) |
76 |
76 |
77 fun clause_is_trivial c = |
77 fun clause_is_trivial c = |
78 let |
78 let |
79 fun dual (Const (\<^const_name>\<open>Not\<close>, _) $ x) = x |
79 fun dual \<^Const_>\<open>Not for x\<close> = x |
80 | dual x = HOLogic.Not $ x |
80 | dual x = \<^Const>\<open>Not for x\<close> |
81 fun has_duals [] = false |
81 fun has_duals [] = false |
82 | has_duals (x::xs) = member (op =) xs (dual x) orelse has_duals xs |
82 | has_duals (x::xs) = member (op =) xs (dual x) orelse has_duals xs |
83 in |
83 in |
84 has_duals (HOLogic.disjuncts c) |
84 has_duals (HOLogic.disjuncts c) |
85 end; |
85 end; |
134 (* negation normal form (i.e. negation only occurs in front of atoms) *) |
134 (* negation normal form (i.e. negation only occurs in front of atoms) *) |
135 (* of t; implications ("-->") and equivalences ("=" on bool) are *) |
135 (* of t; implications ("-->") and equivalences ("=" on bool) are *) |
136 (* eliminated (possibly causing an exponential blowup) *) |
136 (* eliminated (possibly causing an exponential blowup) *) |
137 (* ------------------------------------------------------------------------- *) |
137 (* ------------------------------------------------------------------------- *) |
138 |
138 |
139 fun make_nnf_thm thy (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x $ y) = |
139 fun make_nnf_thm thy \<^Const_>\<open>conj for x y\<close> = |
140 let |
140 let |
141 val thm1 = make_nnf_thm thy x |
141 val thm1 = make_nnf_thm thy x |
142 val thm2 = make_nnf_thm thy y |
142 val thm2 = make_nnf_thm thy y |
143 in |
143 in |
144 @{thm cnf.conj_cong} OF [thm1, thm2] |
144 @{thm cnf.conj_cong} OF [thm1, thm2] |
145 end |
145 end |
146 | make_nnf_thm thy (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ x $ y) = |
146 | make_nnf_thm thy \<^Const_>\<open>disj for x y\<close> = |
147 let |
147 let |
148 val thm1 = make_nnf_thm thy x |
148 val thm1 = make_nnf_thm thy x |
149 val thm2 = make_nnf_thm thy y |
149 val thm2 = make_nnf_thm thy y |
150 in |
150 in |
151 @{thm cnf.disj_cong} OF [thm1, thm2] |
151 @{thm cnf.disj_cong} OF [thm1, thm2] |
152 end |
152 end |
153 | make_nnf_thm thy (Const (\<^const_name>\<open>HOL.implies\<close>, _) $ x $ y) = |
153 | make_nnf_thm thy \<^Const_>\<open>implies for x y\<close> = |
154 let |
154 let |
155 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
155 val thm1 = make_nnf_thm thy \<^Const>\<open>Not for x\<close> |
156 val thm2 = make_nnf_thm thy y |
156 val thm2 = make_nnf_thm thy y |
157 in |
157 in |
158 @{thm cnf.make_nnf_imp} OF [thm1, thm2] |
158 @{thm cnf.make_nnf_imp} OF [thm1, thm2] |
159 end |
159 end |
160 | make_nnf_thm thy (Const (\<^const_name>\<open>HOL.eq\<close>, Type ("fun", \<^typ>\<open>bool\<close> :: _)) $ x $ y) = |
160 | make_nnf_thm thy \<^Const_>\<open>HOL.eq \<^Type>\<open>bool\<close> for x y\<close> = |
161 let |
161 let |
162 val thm1 = make_nnf_thm thy x |
162 val thm1 = make_nnf_thm thy x |
163 val thm2 = make_nnf_thm thy (HOLogic.Not $ x) |
163 val thm2 = make_nnf_thm thy \<^Const>\<open>Not for x\<close> |
164 val thm3 = make_nnf_thm thy y |
164 val thm3 = make_nnf_thm thy y |
165 val thm4 = make_nnf_thm thy (HOLogic.Not $ y) |
165 val thm4 = make_nnf_thm thy \<^Const>\<open>Not for y\<close> |
166 in |
166 in |
167 @{thm cnf.make_nnf_iff} OF [thm1, thm2, thm3, thm4] |
167 @{thm cnf.make_nnf_iff} OF [thm1, thm2, thm3, thm4] |
168 end |
168 end |
169 | make_nnf_thm _ (Const (\<^const_name>\<open>Not\<close>, _) $ Const (\<^const_name>\<open>False\<close>, _)) = |
169 | make_nnf_thm _ \<^Const_>\<open>Not for \<^Const_>\<open>False\<close>\<close> = |
170 @{thm cnf.make_nnf_not_false} |
170 @{thm cnf.make_nnf_not_false} |
171 | make_nnf_thm _ (Const (\<^const_name>\<open>Not\<close>, _) $ Const (\<^const_name>\<open>True\<close>, _)) = |
171 | make_nnf_thm _ \<^Const_>\<open>Not for \<^Const_>\<open>True\<close>\<close> = |
172 @{thm cnf.make_nnf_not_true} |
172 @{thm cnf.make_nnf_not_true} |
173 | make_nnf_thm thy (Const (\<^const_name>\<open>Not\<close>, _) $ (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x $ y)) = |
173 | make_nnf_thm thy \<^Const_>\<open>Not for \<^Const_>\<open>conj for x y\<close>\<close> = |
174 let |
174 let |
175 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
175 val thm1 = make_nnf_thm thy \<^Const>\<open>Not for x\<close> |
176 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
176 val thm2 = make_nnf_thm thy \<^Const>\<open>Not for y\<close> |
177 in |
177 in |
178 @{thm cnf.make_nnf_not_conj} OF [thm1, thm2] |
178 @{thm cnf.make_nnf_not_conj} OF [thm1, thm2] |
179 end |
179 end |
180 | make_nnf_thm thy (Const (\<^const_name>\<open>Not\<close>, _) $ (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ x $ y)) = |
180 | make_nnf_thm thy \<^Const_>\<open>Not for \<^Const_>\<open>disj for x y\<close>\<close> = |
181 let |
181 let |
182 val thm1 = make_nnf_thm thy (HOLogic.Not $ x) |
182 val thm1 = make_nnf_thm thy \<^Const>\<open>Not for x\<close> |
183 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
183 val thm2 = make_nnf_thm thy \<^Const>\<open>Not for y\<close> |
184 in |
184 in |
185 @{thm cnf.make_nnf_not_disj} OF [thm1, thm2] |
185 @{thm cnf.make_nnf_not_disj} OF [thm1, thm2] |
186 end |
186 end |
187 | make_nnf_thm thy |
187 | make_nnf_thm thy \<^Const_>\<open>Not for \<^Const_>\<open>implies for x y\<close>\<close> = |
188 (Const (\<^const_name>\<open>Not\<close>, _) $ (Const (\<^const_name>\<open>HOL.implies\<close>, _) $ x $ y)) = |
|
189 let |
188 let |
190 val thm1 = make_nnf_thm thy x |
189 val thm1 = make_nnf_thm thy x |
191 val thm2 = make_nnf_thm thy (HOLogic.Not $ y) |
190 val thm2 = make_nnf_thm thy \<^Const>\<open>Not for y\<close> |
192 in |
191 in |
193 @{thm cnf.make_nnf_not_imp} OF [thm1, thm2] |
192 @{thm cnf.make_nnf_not_imp} OF [thm1, thm2] |
194 end |
193 end |
195 | make_nnf_thm thy |
194 | make_nnf_thm thy \<^Const_>\<open>Not for \<^Const_>\<open>HOL.eq \<^Type>\<open>bool\<close> for x y\<close>\<close> = |
196 (Const (\<^const_name>\<open>Not\<close>, _) $ |
|
197 (Const (\<^const_name>\<open>HOL.eq\<close>, Type ("fun", \<^typ>\<open>bool\<close> :: _)) $ x $ y)) = |
|
198 let |
195 let |
199 val thm1 = make_nnf_thm thy x |
196 val thm1 = make_nnf_thm thy x |
200 val thm2 = make_nnf_thm thy (HOLogic.Not $ x) |
197 val thm2 = make_nnf_thm thy \<^Const>\<open>Not for x\<close> |
201 val thm3 = make_nnf_thm thy y |
198 val thm3 = make_nnf_thm thy y |
202 val thm4 = make_nnf_thm thy (HOLogic.Not $ y) |
199 val thm4 = make_nnf_thm thy \<^Const>\<open>Not for y\<close> |
203 in |
200 in |
204 @{thm cnf.make_nnf_not_iff} OF [thm1, thm2, thm3, thm4] |
201 @{thm cnf.make_nnf_not_iff} OF [thm1, thm2, thm3, thm4] |
205 end |
202 end |
206 | make_nnf_thm thy (Const (\<^const_name>\<open>Not\<close>, _) $ (Const (\<^const_name>\<open>Not\<close>, _) $ x)) = |
203 | make_nnf_thm thy \<^Const_>\<open>Not for \<^Const_>\<open>Not for x\<close>\<close> = |
207 let |
204 let |
208 val thm1 = make_nnf_thm thy x |
205 val thm1 = make_nnf_thm thy x |
209 in |
206 in |
210 @{thm cnf.make_nnf_not_not} OF [thm1] |
207 @{thm cnf.make_nnf_not_not} OF [thm1] |
211 end |
208 end |
239 (* Optimization: The right-hand side of a conjunction (disjunction) is *) |
236 (* Optimization: The right-hand side of a conjunction (disjunction) is *) |
240 (* simplified only if the left-hand side does not simplify to False *) |
237 (* simplified only if the left-hand side does not simplify to False *) |
241 (* (True, respectively). *) |
238 (* (True, respectively). *) |
242 (* ------------------------------------------------------------------------- *) |
239 (* ------------------------------------------------------------------------- *) |
243 |
240 |
244 fun simp_True_False_thm thy (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x $ y) = |
241 fun simp_True_False_thm thy \<^Const_>\<open>conj for x y\<close> = |
245 let |
242 let |
246 val thm1 = simp_True_False_thm thy x |
243 val thm1 = simp_True_False_thm thy x |
247 val x'= (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm1 |
244 val x'= (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm1 |
248 in |
245 in |
249 if x' = \<^term>\<open>False\<close> then |
246 if x' = \<^Const>\<open>False\<close> then |
250 @{thm cnf.simp_TF_conj_False_l} OF [thm1] (* (x & y) = False *) |
247 @{thm cnf.simp_TF_conj_False_l} OF [thm1] (* (x & y) = False *) |
251 else |
248 else |
252 let |
249 let |
253 val thm2 = simp_True_False_thm thy y |
250 val thm2 = simp_True_False_thm thy y |
254 val y' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm2 |
251 val y' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm2 |
255 in |
252 in |
256 if x' = \<^term>\<open>True\<close> then |
253 if x' = \<^Const>\<open>True\<close> then |
257 @{thm cnf.simp_TF_conj_True_l} OF [thm1, thm2] (* (x & y) = y' *) |
254 @{thm cnf.simp_TF_conj_True_l} OF [thm1, thm2] (* (x & y) = y' *) |
258 else if y' = \<^term>\<open>False\<close> then |
255 else if y' = \<^Const>\<open>False\<close> then |
259 @{thm cnf.simp_TF_conj_False_r} OF [thm2] (* (x & y) = False *) |
256 @{thm cnf.simp_TF_conj_False_r} OF [thm2] (* (x & y) = False *) |
260 else if y' = \<^term>\<open>True\<close> then |
257 else if y' = \<^Const>\<open>True\<close> then |
261 @{thm cnf.simp_TF_conj_True_r} OF [thm1, thm2] (* (x & y) = x' *) |
258 @{thm cnf.simp_TF_conj_True_r} OF [thm1, thm2] (* (x & y) = x' *) |
262 else |
259 else |
263 @{thm cnf.conj_cong} OF [thm1, thm2] (* (x & y) = (x' & y') *) |
260 @{thm cnf.conj_cong} OF [thm1, thm2] (* (x & y) = (x' & y') *) |
264 end |
261 end |
265 end |
262 end |
266 | simp_True_False_thm thy (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ x $ y) = |
263 | simp_True_False_thm thy \<^Const_>\<open>disj for x y\<close> = |
267 let |
264 let |
268 val thm1 = simp_True_False_thm thy x |
265 val thm1 = simp_True_False_thm thy x |
269 val x' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm1 |
266 val x' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm1 |
270 in |
267 in |
271 if x' = \<^term>\<open>True\<close> then |
268 if x' = \<^Const>\<open>True\<close> then |
272 @{thm cnf.simp_TF_disj_True_l} OF [thm1] (* (x | y) = True *) |
269 @{thm cnf.simp_TF_disj_True_l} OF [thm1] (* (x | y) = True *) |
273 else |
270 else |
274 let |
271 let |
275 val thm2 = simp_True_False_thm thy y |
272 val thm2 = simp_True_False_thm thy y |
276 val y' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm2 |
273 val y' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm2 |
277 in |
274 in |
278 if x' = \<^term>\<open>False\<close> then |
275 if x' = \<^Const>\<open>False\<close> then |
279 @{thm cnf.simp_TF_disj_False_l} OF [thm1, thm2] (* (x | y) = y' *) |
276 @{thm cnf.simp_TF_disj_False_l} OF [thm1, thm2] (* (x | y) = y' *) |
280 else if y' = \<^term>\<open>True\<close> then |
277 else if y' = \<^Const>\<open>True\<close> then |
281 @{thm cnf.simp_TF_disj_True_r} OF [thm2] (* (x | y) = True *) |
278 @{thm cnf.simp_TF_disj_True_r} OF [thm2] (* (x | y) = True *) |
282 else if y' = \<^term>\<open>False\<close> then |
279 else if y' = \<^Const>\<open>False\<close> then |
283 @{thm cnf.simp_TF_disj_False_r} OF [thm1, thm2] (* (x | y) = x' *) |
280 @{thm cnf.simp_TF_disj_False_r} OF [thm1, thm2] (* (x | y) = x' *) |
284 else |
281 else |
285 @{thm cnf.disj_cong} OF [thm1, thm2] (* (x | y) = (x' | y') *) |
282 @{thm cnf.disj_cong} OF [thm1, thm2] (* (x | y) = (x' | y') *) |
286 end |
283 end |
287 end |
284 end |
294 (* ------------------------------------------------------------------------- *) |
291 (* ------------------------------------------------------------------------- *) |
295 |
292 |
296 fun make_cnf_thm ctxt t = |
293 fun make_cnf_thm ctxt t = |
297 let |
294 let |
298 val thy = Proof_Context.theory_of ctxt |
295 val thy = Proof_Context.theory_of ctxt |
299 fun make_cnf_thm_from_nnf (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x $ y) = |
296 fun make_cnf_thm_from_nnf \<^Const_>\<open>conj for x y\<close> = |
300 let |
297 let |
301 val thm1 = make_cnf_thm_from_nnf x |
298 val thm1 = make_cnf_thm_from_nnf x |
302 val thm2 = make_cnf_thm_from_nnf y |
299 val thm2 = make_cnf_thm_from_nnf y |
303 in |
300 in |
304 @{thm cnf.conj_cong} OF [thm1, thm2] |
301 @{thm cnf.conj_cong} OF [thm1, thm2] |
305 end |
302 end |
306 | make_cnf_thm_from_nnf (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ x $ y) = |
303 | make_cnf_thm_from_nnf \<^Const_>\<open>disj for x y\<close> = |
307 let |
304 let |
308 (* produces a theorem "(x' | y') = t'", where x', y', and t' are in CNF *) |
305 (* produces a theorem "(x' | y') = t'", where x', y', and t' are in CNF *) |
309 fun make_cnf_disj_thm (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x1 $ x2) y' = |
306 fun make_cnf_disj_thm \<^Const_>\<open>conj for x1 x2\<close> y' = |
310 let |
307 let |
311 val thm1 = make_cnf_disj_thm x1 y' |
308 val thm1 = make_cnf_disj_thm x1 y' |
312 val thm2 = make_cnf_disj_thm x2 y' |
309 val thm2 = make_cnf_disj_thm x2 y' |
313 in |
310 in |
314 @{thm cnf.make_cnf_disj_conj_l} OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
311 @{thm cnf.make_cnf_disj_conj_l} OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
315 end |
312 end |
316 | make_cnf_disj_thm x' (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ y1 $ y2) = |
313 | make_cnf_disj_thm x' \<^Const_>\<open>conj for y1 y2\<close> = |
317 let |
314 let |
318 val thm1 = make_cnf_disj_thm x' y1 |
315 val thm1 = make_cnf_disj_thm x' y1 |
319 val thm2 = make_cnf_disj_thm x' y2 |
316 val thm2 = make_cnf_disj_thm x' y2 |
320 in |
317 in |
321 @{thm cnf.make_cnf_disj_conj_r} OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
318 @{thm cnf.make_cnf_disj_conj_r} OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
322 end |
319 end |
323 | make_cnf_disj_thm x' y' = |
320 | make_cnf_disj_thm x' y' = |
324 inst_thm thy [HOLogic.mk_disj (x', y')] @{thm cnf.iff_refl} (* (x' | y') = (x' | y') *) |
321 inst_thm thy [\<^Const>\<open>disj for x' y'\<close>] @{thm cnf.iff_refl} (* (x' | y') = (x' | y') *) |
325 val thm1 = make_cnf_thm_from_nnf x |
322 val thm1 = make_cnf_thm_from_nnf x |
326 val thm2 = make_cnf_thm_from_nnf y |
323 val thm2 = make_cnf_thm_from_nnf y |
327 val x' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm1 |
324 val x' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm1 |
328 val y' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm2 |
325 val y' = (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o Thm.prop_of) thm2 |
329 val disj_thm = @{thm cnf.disj_cong} OF [thm1, thm2] (* (x | y) = (x' | y') *) |
326 val disj_thm = @{thm cnf.disj_cong} OF [thm1, thm2] (* (x | y) = (x' | y') *) |
366 fun make_cnfx_thm ctxt t = |
363 fun make_cnfx_thm ctxt t = |
367 let |
364 let |
368 val thy = Proof_Context.theory_of ctxt |
365 val thy = Proof_Context.theory_of ctxt |
369 val var_id = Unsynchronized.ref 0 (* properly initialized below *) |
366 val var_id = Unsynchronized.ref 0 (* properly initialized below *) |
370 fun new_free () = |
367 fun new_free () = |
371 Free ("cnfx_" ^ string_of_int (Unsynchronized.inc var_id), HOLogic.boolT) |
368 Free ("cnfx_" ^ string_of_int (Unsynchronized.inc var_id), \<^Type>\<open>bool\<close>) |
372 fun make_cnfx_thm_from_nnf (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x $ y) : thm = |
369 fun make_cnfx_thm_from_nnf \<^Const_>\<open>conj for x y\<close> = |
373 let |
370 let |
374 val thm1 = make_cnfx_thm_from_nnf x |
371 val thm1 = make_cnfx_thm_from_nnf x |
375 val thm2 = make_cnfx_thm_from_nnf y |
372 val thm2 = make_cnfx_thm_from_nnf y |
376 in |
373 in |
377 @{thm cnf.conj_cong} OF [thm1, thm2] |
374 @{thm cnf.conj_cong} OF [thm1, thm2] |
378 end |
375 end |
379 | make_cnfx_thm_from_nnf (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ x $ y) = |
376 | make_cnfx_thm_from_nnf \<^Const_>\<open>disj for x y\<close> = |
380 if is_clause x andalso is_clause y then |
377 if is_clause x andalso is_clause y then |
381 inst_thm thy [HOLogic.mk_disj (x, y)] @{thm cnf.iff_refl} |
378 inst_thm thy [\<^Const>\<open>disj for x y\<close>] @{thm cnf.iff_refl} |
382 else if is_literal y orelse is_literal x then |
379 else if is_literal y orelse is_literal x then |
383 let |
380 let |
384 (* produces a theorem "(x' | y') = t'", where x', y', and t' are *) |
381 (* produces a theorem "(x' | y') = t'", where x', y', and t' are *) |
385 (* almost in CNF, and x' or y' is a literal *) |
382 (* almost in CNF, and x' or y' is a literal *) |
386 fun make_cnfx_disj_thm (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ x1 $ x2) y' = |
383 fun make_cnfx_disj_thm \<^Const_>\<open>conj for x1 x2\<close> y' = |
387 let |
384 let |
388 val thm1 = make_cnfx_disj_thm x1 y' |
385 val thm1 = make_cnfx_disj_thm x1 y' |
389 val thm2 = make_cnfx_disj_thm x2 y' |
386 val thm2 = make_cnfx_disj_thm x2 y' |
390 in |
387 in |
391 @{thm cnf.make_cnf_disj_conj_l} OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
388 @{thm cnf.make_cnf_disj_conj_l} OF [thm1, thm2] (* ((x1 & x2) | y') = ((x1 | y')' & (x2 | y')') *) |
392 end |
389 end |
393 | make_cnfx_disj_thm x' (Const (\<^const_name>\<open>HOL.conj\<close>, _) $ y1 $ y2) = |
390 | make_cnfx_disj_thm x' \<^Const_>\<open>conj for y1 y2\<close> = |
394 let |
391 let |
395 val thm1 = make_cnfx_disj_thm x' y1 |
392 val thm1 = make_cnfx_disj_thm x' y1 |
396 val thm2 = make_cnfx_disj_thm x' y2 |
393 val thm2 = make_cnfx_disj_thm x' y2 |
397 in |
394 in |
398 @{thm cnf.make_cnf_disj_conj_r} OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
395 @{thm cnf.make_cnf_disj_conj_r} OF [thm1, thm2] (* (x' | (y1 & y2)) = ((x' | y1)' & (x' | y2)') *) |
399 end |
396 end |
400 | make_cnfx_disj_thm (\<^term>\<open>Ex :: (bool \<Rightarrow> bool) \<Rightarrow> bool\<close> $ x') y' = |
397 | make_cnfx_disj_thm \<^Const_>\<open>Ex \<^Type>\<open>bool\<close> for x'\<close> y' = |
401 let |
398 let |
402 val thm1 = inst_thm thy [x', y'] @{thm cnf.make_cnfx_disj_ex_l} (* ((Ex x') | y') = (Ex (x' | y')) *) |
399 val thm1 = inst_thm thy [x', y'] @{thm cnf.make_cnfx_disj_ex_l} (* ((Ex x') | y') = (Ex (x' | y')) *) |
403 val var = new_free () |
400 val var = new_free () |
404 val thm2 = make_cnfx_disj_thm (betapply (x', var)) y' (* (x' | y') = body' *) |
401 val thm2 = make_cnfx_disj_thm (betapply (x', var)) y' (* (x' | y') = body' *) |
405 val thm3 = Thm.forall_intr (Thm.global_cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |
402 val thm3 = Thm.forall_intr (Thm.global_cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |
406 val thm4 = Thm.strip_shyps (thm3 COMP allI) (* ALL v. (x' | y') = body' *) |
403 val thm4 = Thm.strip_shyps (thm3 COMP allI) (* ALL v. (x' | y') = body' *) |
407 val thm5 = Thm.strip_shyps (thm4 RS @{thm cnf.make_cnfx_ex_cong}) (* (EX v. (x' | y')) = (EX v. body') *) |
404 val thm5 = Thm.strip_shyps (thm4 RS @{thm cnf.make_cnfx_ex_cong}) (* (EX v. (x' | y')) = (EX v. body') *) |
408 in |
405 in |
409 @{thm cnf.iff_trans} OF [thm1, thm5] (* ((Ex x') | y') = (Ex v. body') *) |
406 @{thm cnf.iff_trans} OF [thm1, thm5] (* ((Ex x') | y') = (Ex v. body') *) |
410 end |
407 end |
411 | make_cnfx_disj_thm x' (\<^term>\<open>Ex :: (bool \<Rightarrow> bool) \<Rightarrow> bool\<close> $ y') = |
408 | make_cnfx_disj_thm x' \<^Const_>\<open>Ex \<^Type>\<open>bool\<close> for y'\<close> = |
412 let |
409 let |
413 val thm1 = inst_thm thy [x', y'] @{thm cnf.make_cnfx_disj_ex_r} (* (x' | (Ex y')) = (Ex (x' | y')) *) |
410 val thm1 = inst_thm thy [x', y'] @{thm cnf.make_cnfx_disj_ex_r} (* (x' | (Ex y')) = (Ex (x' | y')) *) |
414 val var = new_free () |
411 val var = new_free () |
415 val thm2 = make_cnfx_disj_thm x' (betapply (y', var)) (* (x' | y') = body' *) |
412 val thm2 = make_cnfx_disj_thm x' (betapply (y', var)) (* (x' | y') = body' *) |
416 val thm3 = Thm.forall_intr (Thm.global_cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |
413 val thm3 = Thm.forall_intr (Thm.global_cterm_of thy var) thm2 (* !!v. (x' | y') = body' *) |