98 fun first_order_resolve ctxt thA thB = |
98 fun first_order_resolve ctxt thA thB = |
99 (case |
99 (case |
100 try (fn () => |
100 try (fn () => |
101 let val thy = Proof_Context.theory_of ctxt |
101 let val thy = Proof_Context.theory_of ctxt |
102 val tmA = Thm.concl_of thA |
102 val tmA = Thm.concl_of thA |
103 val Const(@{const_name Pure.imp},_) $ tmB $ _ = Thm.prop_of thB |
103 val Const(\<^const_name>\<open>Pure.imp\<close>,_) $ tmB $ _ = Thm.prop_of thB |
104 val tenv = |
104 val tenv = |
105 Pattern.first_order_match thy (tmB, tmA) |
105 Pattern.first_order_match thy (tmB, tmA) |
106 (Vartab.empty, Vartab.empty) |> snd |
106 (Vartab.empty, Vartab.empty) |> snd |
107 val insts = Vartab.fold (fn (xi, (_, t)) => cons (xi, Thm.cterm_of ctxt t)) tenv []; |
107 val insts = Vartab.fold (fn (xi, (_, t)) => cons (xi, Thm.cterm_of ctxt t)) tenv []; |
108 in thA RS (infer_instantiate ctxt insts thB) end) () of |
108 in thA RS (infer_instantiate ctxt insts thB) end) () of |
119 Abs (protect_prefix ^ s, T, protect_bound_var_names t') |
119 Abs (protect_prefix ^ s, T, protect_bound_var_names t') |
120 | protect_bound_var_names t = t |
120 | protect_bound_var_names t = t |
121 |
121 |
122 fun fix_bound_var_names old_t new_t = |
122 fun fix_bound_var_names old_t new_t = |
123 let |
123 let |
124 fun quant_of @{const_name All} = SOME true |
124 fun quant_of \<^const_name>\<open>All\<close> = SOME true |
125 | quant_of @{const_name Ball} = SOME true |
125 | quant_of \<^const_name>\<open>Ball\<close> = SOME true |
126 | quant_of @{const_name Ex} = SOME false |
126 | quant_of \<^const_name>\<open>Ex\<close> = SOME false |
127 | quant_of @{const_name Bex} = SOME false |
127 | quant_of \<^const_name>\<open>Bex\<close> = SOME false |
128 | quant_of _ = NONE |
128 | quant_of _ = NONE |
129 val flip_quant = Option.map not |
129 val flip_quant = Option.map not |
130 fun some_eq (SOME x) (SOME y) = x = y |
130 fun some_eq (SOME x) (SOME y) = x = y |
131 | some_eq _ _ = false |
131 | some_eq _ _ = false |
132 fun add_names quant (Const (quant_s, _) $ Abs (s, _, t')) = |
132 fun add_names quant (Const (quant_s, _) $ Abs (s, _, t')) = |
133 add_names quant t' #> some_eq quant (quant_of quant_s) ? cons s |
133 add_names quant t' #> some_eq quant (quant_of quant_s) ? cons s |
134 | add_names quant (@{const Not} $ t) = add_names (flip_quant quant) t |
134 | add_names quant (\<^const>\<open>Not\<close> $ t) = add_names (flip_quant quant) t |
135 | add_names quant (@{const implies} $ t1 $ t2) = |
135 | add_names quant (\<^const>\<open>implies\<close> $ t1 $ t2) = |
136 add_names (flip_quant quant) t1 #> add_names quant t2 |
136 add_names (flip_quant quant) t1 #> add_names quant t2 |
137 | add_names quant (t1 $ t2) = fold (add_names quant) [t1, t2] |
137 | add_names quant (t1 $ t2) = fold (add_names quant) [t1, t2] |
138 | add_names _ _ = I |
138 | add_names _ _ = I |
139 fun lost_names quant = |
139 fun lost_names quant = |
140 subtract (op =) (add_names quant new_t []) (add_names quant old_t []) |
140 subtract (op =) (add_names quant new_t []) (add_names quant old_t []) |
167 property of the form "... c ... c ... c ..." will lead to a huge unification |
167 property of the form "... c ... c ... c ..." will lead to a huge unification |
168 problem, due to the (spurious) choices between projection and imitation. The |
168 problem, due to the (spurious) choices between projection and imitation. The |
169 workaround is to instantiate "?P := (%c. ... c ... c ... c ...)" manually. *) |
169 workaround is to instantiate "?P := (%c. ... c ... c ... c ...)" manually. *) |
170 fun quant_resolve_tac ctxt th i st = |
170 fun quant_resolve_tac ctxt th i st = |
171 case (Thm.concl_of st, Thm.prop_of th) of |
171 case (Thm.concl_of st, Thm.prop_of th) of |
172 (@{const Trueprop} $ (Var _ $ (c as Free _)), @{const Trueprop} $ _) => |
172 (\<^const>\<open>Trueprop\<close> $ (Var _ $ (c as Free _)), \<^const>\<open>Trueprop\<close> $ _) => |
173 let |
173 let |
174 val cc = Thm.cterm_of ctxt c |
174 val cc = Thm.cterm_of ctxt c |
175 val ct = Thm.dest_arg (Thm.cprop_of th) |
175 val ct = Thm.dest_arg (Thm.cprop_of th) |
176 in resolve_tac ctxt [th] i (Thm.instantiate' [] [SOME (Thm.lambda cc ct)] st) end |
176 in resolve_tac ctxt [th] i (Thm.instantiate' [] [SOME (Thm.lambda cc ct)] st) end |
177 | _ => resolve_tac ctxt [th] i st |
177 | _ => resolve_tac ctxt [th] i st |
195 end; |
195 end; |
196 |
196 |
197 (*Are any of the logical connectives in "bs" present in the term?*) |
197 (*Are any of the logical connectives in "bs" present in the term?*) |
198 fun has_conns bs = |
198 fun has_conns bs = |
199 let fun has (Const _) = false |
199 let fun has (Const _) = false |
200 | has (Const(@{const_name Trueprop},_) $ p) = has p |
200 | has (Const(\<^const_name>\<open>Trueprop\<close>,_) $ p) = has p |
201 | has (Const(@{const_name Not},_) $ p) = has p |
201 | has (Const(\<^const_name>\<open>Not\<close>,_) $ p) = has p |
202 | has (Const(@{const_name HOL.disj},_) $ p $ q) = member (op =) bs @{const_name HOL.disj} orelse has p orelse has q |
202 | has (Const(\<^const_name>\<open>HOL.disj\<close>,_) $ p $ q) = member (op =) bs \<^const_name>\<open>HOL.disj\<close> orelse has p orelse has q |
203 | has (Const(@{const_name HOL.conj},_) $ p $ q) = member (op =) bs @{const_name HOL.conj} orelse has p orelse has q |
203 | has (Const(\<^const_name>\<open>HOL.conj\<close>,_) $ p $ q) = member (op =) bs \<^const_name>\<open>HOL.conj\<close> orelse has p orelse has q |
204 | has (Const(@{const_name All},_) $ Abs(_,_,p)) = member (op =) bs @{const_name All} orelse has p |
204 | has (Const(\<^const_name>\<open>All\<close>,_) $ Abs(_,_,p)) = member (op =) bs \<^const_name>\<open>All\<close> orelse has p |
205 | has (Const(@{const_name Ex},_) $ Abs(_,_,p)) = member (op =) bs @{const_name Ex} orelse has p |
205 | has (Const(\<^const_name>\<open>Ex\<close>,_) $ Abs(_,_,p)) = member (op =) bs \<^const_name>\<open>Ex\<close> orelse has p |
206 | has _ = false |
206 | has _ = false |
207 in has end; |
207 in has end; |
208 |
208 |
209 |
209 |
210 (**** Clause handling ****) |
210 (**** Clause handling ****) |
211 |
211 |
212 fun literals (Const(@{const_name Trueprop},_) $ P) = literals P |
212 fun literals (Const(\<^const_name>\<open>Trueprop\<close>,_) $ P) = literals P |
213 | literals (Const(@{const_name HOL.disj},_) $ P $ Q) = literals P @ literals Q |
213 | literals (Const(\<^const_name>\<open>HOL.disj\<close>,_) $ P $ Q) = literals P @ literals Q |
214 | literals (Const(@{const_name Not},_) $ P) = [(false,P)] |
214 | literals (Const(\<^const_name>\<open>Not\<close>,_) $ P) = [(false,P)] |
215 | literals P = [(true,P)]; |
215 | literals P = [(true,P)]; |
216 |
216 |
217 (*number of literals in a term*) |
217 (*number of literals in a term*) |
218 val nliterals = length o literals; |
218 val nliterals = length o literals; |
219 |
219 |
220 |
220 |
221 (*** Tautology Checking ***) |
221 (*** Tautology Checking ***) |
222 |
222 |
223 fun signed_lits_aux (Const (@{const_name HOL.disj}, _) $ P $ Q) (poslits, neglits) = |
223 fun signed_lits_aux (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ P $ Q) (poslits, neglits) = |
224 signed_lits_aux Q (signed_lits_aux P (poslits, neglits)) |
224 signed_lits_aux Q (signed_lits_aux P (poslits, neglits)) |
225 | signed_lits_aux (Const(@{const_name Not},_) $ P) (poslits, neglits) = (poslits, P::neglits) |
225 | signed_lits_aux (Const(\<^const_name>\<open>Not\<close>,_) $ P) (poslits, neglits) = (poslits, P::neglits) |
226 | signed_lits_aux P (poslits, neglits) = (P::poslits, neglits); |
226 | signed_lits_aux P (poslits, neglits) = (P::poslits, neglits); |
227 |
227 |
228 fun signed_lits th = signed_lits_aux (HOLogic.dest_Trueprop (Thm.concl_of th)) ([],[]); |
228 fun signed_lits th = signed_lits_aux (HOLogic.dest_Trueprop (Thm.concl_of th)) ([],[]); |
229 |
229 |
230 (*Literals like X=X are tautologous*) |
230 (*Literals like X=X are tautologous*) |
231 fun taut_poslit (Const(@{const_name HOL.eq},_) $ t $ u) = t aconv u |
231 fun taut_poslit (Const(\<^const_name>\<open>HOL.eq\<close>,_) $ t $ u) = t aconv u |
232 | taut_poslit (Const(@{const_name True},_)) = true |
232 | taut_poslit (Const(\<^const_name>\<open>True\<close>,_)) = true |
233 | taut_poslit _ = false; |
233 | taut_poslit _ = false; |
234 |
234 |
235 fun is_taut th = |
235 fun is_taut th = |
236 let val (poslits,neglits) = signed_lits th |
236 let val (poslits,neglits) = signed_lits th |
237 in exists taut_poslit poslits |
237 in exists taut_poslit poslits |
238 orelse |
238 orelse |
239 exists (member (op aconv) neglits) (@{term False} :: poslits) |
239 exists (member (op aconv) neglits) (\<^term>\<open>False\<close> :: poslits) |
240 end |
240 end |
241 handle TERM _ => false; (*probably dest_Trueprop on a weird theorem*) |
241 handle TERM _ => false; (*probably dest_Trueprop on a weird theorem*) |
242 |
242 |
243 |
243 |
244 (*** To remove trivial negated equality literals from clauses ***) |
244 (*** To remove trivial negated equality literals from clauses ***) |
254 | eliminable _ = false; |
254 | eliminable _ = false; |
255 |
255 |
256 fun refl_clause_aux 0 th = th |
256 fun refl_clause_aux 0 th = th |
257 | refl_clause_aux n th = |
257 | refl_clause_aux n th = |
258 case HOLogic.dest_Trueprop (Thm.concl_of th) of |
258 case HOLogic.dest_Trueprop (Thm.concl_of th) of |
259 (Const (@{const_name HOL.disj}, _) $ (Const (@{const_name HOL.disj}, _) $ _ $ _) $ _) => |
259 (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ _ $ _) $ _) => |
260 refl_clause_aux n (th RS disj_assoc) (*isolate an atom as first disjunct*) |
260 refl_clause_aux n (th RS disj_assoc) (*isolate an atom as first disjunct*) |
261 | (Const (@{const_name HOL.disj}, _) $ (Const(@{const_name Not},_) $ (Const(@{const_name HOL.eq},_) $ t $ u)) $ _) => |
261 | (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ (Const(\<^const_name>\<open>Not\<close>,_) $ (Const(\<^const_name>\<open>HOL.eq\<close>,_) $ t $ u)) $ _) => |
262 if eliminable(t,u) |
262 if eliminable(t,u) |
263 then refl_clause_aux (n-1) (th RS not_refl_disj_D) (*Var inequation: delete*) |
263 then refl_clause_aux (n-1) (th RS not_refl_disj_D) (*Var inequation: delete*) |
264 else refl_clause_aux (n-1) (th RS disj_comm) (*not between Vars: ignore*) |
264 else refl_clause_aux (n-1) (th RS disj_comm) (*not between Vars: ignore*) |
265 | (Const (@{const_name HOL.disj}, _) $ _ $ _) => refl_clause_aux n (th RS disj_comm) |
265 | (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ _ $ _) => refl_clause_aux n (th RS disj_comm) |
266 | _ => (*not a disjunction*) th; |
266 | _ => (*not a disjunction*) th; |
267 |
267 |
268 fun notequal_lits_count (Const (@{const_name HOL.disj}, _) $ P $ Q) = |
268 fun notequal_lits_count (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ P $ Q) = |
269 notequal_lits_count P + notequal_lits_count Q |
269 notequal_lits_count P + notequal_lits_count Q |
270 | notequal_lits_count (Const(@{const_name Not},_) $ (Const(@{const_name HOL.eq},_) $ _ $ _)) = 1 |
270 | notequal_lits_count (Const(\<^const_name>\<open>Not\<close>,_) $ (Const(\<^const_name>\<open>HOL.eq\<close>,_) $ _ $ _)) = 1 |
271 | notequal_lits_count _ = 0; |
271 | notequal_lits_count _ = 0; |
272 |
272 |
273 (*Simplify a clause by applying reflexivity to its negated equality literals*) |
273 (*Simplify a clause by applying reflexivity to its negated equality literals*) |
274 fun refl_clause th = |
274 fun refl_clause th = |
275 let val neqs = notequal_lits_count (HOLogic.dest_Trueprop (Thm.concl_of th)) |
275 let val neqs = notequal_lits_count (HOLogic.dest_Trueprop (Thm.concl_of th)) |
310 let |
310 let |
311 fun sum x y = if x < bound andalso y < bound then x+y else bound |
311 fun sum x y = if x < bound andalso y < bound then x+y else bound |
312 fun prod x y = if x < bound andalso y < bound then x*y else bound |
312 fun prod x y = if x < bound andalso y < bound then x*y else bound |
313 |
313 |
314 (*Estimate the number of clauses in order to detect infeasible theorems*) |
314 (*Estimate the number of clauses in order to detect infeasible theorems*) |
315 fun signed_nclauses b (Const(@{const_name Trueprop},_) $ t) = signed_nclauses b t |
315 fun signed_nclauses b (Const(\<^const_name>\<open>Trueprop\<close>,_) $ t) = signed_nclauses b t |
316 | signed_nclauses b (Const(@{const_name Not},_) $ t) = signed_nclauses (not b) t |
316 | signed_nclauses b (Const(\<^const_name>\<open>Not\<close>,_) $ t) = signed_nclauses (not b) t |
317 | signed_nclauses b (Const(@{const_name HOL.conj},_) $ t $ u) = |
317 | signed_nclauses b (Const(\<^const_name>\<open>HOL.conj\<close>,_) $ t $ u) = |
318 if b then sum (signed_nclauses b t) (signed_nclauses b u) |
318 if b then sum (signed_nclauses b t) (signed_nclauses b u) |
319 else prod (signed_nclauses b t) (signed_nclauses b u) |
319 else prod (signed_nclauses b t) (signed_nclauses b u) |
320 | signed_nclauses b (Const(@{const_name HOL.disj},_) $ t $ u) = |
320 | signed_nclauses b (Const(\<^const_name>\<open>HOL.disj\<close>,_) $ t $ u) = |
321 if b then prod (signed_nclauses b t) (signed_nclauses b u) |
321 if b then prod (signed_nclauses b t) (signed_nclauses b u) |
322 else sum (signed_nclauses b t) (signed_nclauses b u) |
322 else sum (signed_nclauses b t) (signed_nclauses b u) |
323 | signed_nclauses b (Const(@{const_name HOL.implies},_) $ t $ u) = |
323 | signed_nclauses b (Const(\<^const_name>\<open>HOL.implies\<close>,_) $ t $ u) = |
324 if b then prod (signed_nclauses (not b) t) (signed_nclauses b u) |
324 if b then prod (signed_nclauses (not b) t) (signed_nclauses b u) |
325 else sum (signed_nclauses (not b) t) (signed_nclauses b u) |
325 else sum (signed_nclauses (not b) t) (signed_nclauses b u) |
326 | signed_nclauses b (Const(@{const_name HOL.eq}, Type ("fun", [T, _])) $ t $ u) = |
326 | signed_nclauses b (Const(\<^const_name>\<open>HOL.eq\<close>, Type ("fun", [T, _])) $ t $ u) = |
327 if T = HOLogic.boolT then (*Boolean equality is if-and-only-if*) |
327 if T = HOLogic.boolT then (*Boolean equality is if-and-only-if*) |
328 if b then sum (prod (signed_nclauses (not b) t) (signed_nclauses b u)) |
328 if b then sum (prod (signed_nclauses (not b) t) (signed_nclauses b u)) |
329 (prod (signed_nclauses (not b) u) (signed_nclauses b t)) |
329 (prod (signed_nclauses (not b) u) (signed_nclauses b t)) |
330 else sum (prod (signed_nclauses b t) (signed_nclauses b u)) |
330 else sum (prod (signed_nclauses b t) (signed_nclauses b u)) |
331 (prod (signed_nclauses (not b) t) (signed_nclauses (not b) u)) |
331 (prod (signed_nclauses (not b) t) (signed_nclauses (not b) u)) |
332 else 1 |
332 else 1 |
333 | signed_nclauses b (Const(@{const_name Ex}, _) $ Abs (_,_,t)) = signed_nclauses b t |
333 | signed_nclauses b (Const(\<^const_name>\<open>Ex\<close>, _) $ Abs (_,_,t)) = signed_nclauses b t |
334 | signed_nclauses b (Const(@{const_name All},_) $ Abs (_,_,t)) = signed_nclauses b t |
334 | signed_nclauses b (Const(\<^const_name>\<open>All\<close>,_) $ Abs (_,_,t)) = signed_nclauses b t |
335 | signed_nclauses _ _ = 1; (* literal *) |
335 | signed_nclauses _ _ = 1; (* literal *) |
336 in signed_nclauses true t end |
336 in signed_nclauses true t end |
337 |
337 |
338 fun has_too_many_clauses ctxt t = |
338 fun has_too_many_clauses ctxt t = |
339 let val max_cl = Config.get ctxt max_clauses in |
339 let val max_cl = Config.get ctxt max_clauses in |
368 Eliminates existential quantifiers using Skolemization theorems. *) |
368 Eliminates existential quantifiers using Skolemization theorems. *) |
369 fun cnf old_skolem_ths ctxt (th, ths) = |
369 fun cnf old_skolem_ths ctxt (th, ths) = |
370 let val ctxt_ref = Unsynchronized.ref ctxt (* FIXME ??? *) |
370 let val ctxt_ref = Unsynchronized.ref ctxt (* FIXME ??? *) |
371 fun cnf_aux (th,ths) = |
371 fun cnf_aux (th,ths) = |
372 if not (can HOLogic.dest_Trueprop (Thm.prop_of th)) then ths (*meta-level: ignore*) |
372 if not (can HOLogic.dest_Trueprop (Thm.prop_of th)) then ths (*meta-level: ignore*) |
373 else if not (has_conns [@{const_name All}, @{const_name Ex}, @{const_name HOL.conj}] (Thm.prop_of th)) |
373 else if not (has_conns [\<^const_name>\<open>All\<close>, \<^const_name>\<open>Ex\<close>, \<^const_name>\<open>HOL.conj\<close>] (Thm.prop_of th)) |
374 then nodups ctxt th :: ths (*no work to do, terminate*) |
374 then nodups ctxt th :: ths (*no work to do, terminate*) |
375 else case head_of (HOLogic.dest_Trueprop (Thm.concl_of th)) of |
375 else case head_of (HOLogic.dest_Trueprop (Thm.concl_of th)) of |
376 Const (@{const_name HOL.conj}, _) => (*conjunction*) |
376 Const (\<^const_name>\<open>HOL.conj\<close>, _) => (*conjunction*) |
377 cnf_aux (th RS conjunct1, cnf_aux (th RS conjunct2, ths)) |
377 cnf_aux (th RS conjunct1, cnf_aux (th RS conjunct2, ths)) |
378 | Const (@{const_name All}, _) => (*universal quantifier*) |
378 | Const (\<^const_name>\<open>All\<close>, _) => (*universal quantifier*) |
379 let val (th', ctxt') = freeze_spec th (! ctxt_ref) |
379 let val (th', ctxt') = freeze_spec th (! ctxt_ref) |
380 in ctxt_ref := ctxt'; cnf_aux (th', ths) end |
380 in ctxt_ref := ctxt'; cnf_aux (th', ths) end |
381 | Const (@{const_name Ex}, _) => |
381 | Const (\<^const_name>\<open>Ex\<close>, _) => |
382 (*existential quantifier: Insert Skolem functions*) |
382 (*existential quantifier: Insert Skolem functions*) |
383 cnf_aux (apply_skolem_theorem (! ctxt_ref) (th, old_skolem_ths), ths) |
383 cnf_aux (apply_skolem_theorem (! ctxt_ref) (th, old_skolem_ths), ths) |
384 | Const (@{const_name HOL.disj}, _) => |
384 | Const (\<^const_name>\<open>HOL.disj\<close>, _) => |
385 (*Disjunction of P, Q: Create new goal of proving ?P | ?Q and solve it using |
385 (*Disjunction of P, Q: Create new goal of proving ?P | ?Q and solve it using |
386 all combinations of converting P, Q to CNF.*) |
386 all combinations of converting P, Q to CNF.*) |
387 (*There is one assumption, which gets bound to prem and then normalized via |
387 (*There is one assumption, which gets bound to prem and then normalized via |
388 cnf_nil. The normal form is given to resolve_tac, instantiate a Boolean |
388 cnf_nil. The normal form is given to resolve_tac, instantiate a Boolean |
389 variable created by resolution with disj_forward. Since (cnf_nil prem) |
389 variable created by resolution with disj_forward. Since (cnf_nil prem) |
429 make_goal (tryres(th, clause_rules)) |
429 make_goal (tryres(th, clause_rules)) |
430 handle THM _ => tryres(th, [make_neg_goal, make_pos_goal]); |
430 handle THM _ => tryres(th, [make_neg_goal, make_pos_goal]); |
431 |
431 |
432 fun rigid t = not (is_Var (head_of t)); |
432 fun rigid t = not (is_Var (head_of t)); |
433 |
433 |
434 fun ok4horn (Const (@{const_name Trueprop},_) $ (Const (@{const_name HOL.disj}, _) $ t $ _)) = rigid t |
434 fun ok4horn (Const (\<^const_name>\<open>Trueprop\<close>,_) $ (Const (\<^const_name>\<open>HOL.disj\<close>, _) $ t $ _)) = rigid t |
435 | ok4horn (Const (@{const_name Trueprop},_) $ t) = rigid t |
435 | ok4horn (Const (\<^const_name>\<open>Trueprop\<close>,_) $ t) = rigid t |
436 | ok4horn _ = false; |
436 | ok4horn _ = false; |
437 |
437 |
438 (*Create a meta-level Horn clause*) |
438 (*Create a meta-level Horn clause*) |
439 fun make_horn crules th = |
439 fun make_horn crules th = |
440 if ok4horn (Thm.concl_of th) |
440 if ok4horn (Thm.concl_of th) |
509 |
509 |
510 (*Negation Normal Form*) |
510 (*Negation Normal Form*) |
511 val nnf_rls = [imp_to_disjD, iff_to_disjD, not_conjD, not_disjD, |
511 val nnf_rls = [imp_to_disjD, iff_to_disjD, not_conjD, not_disjD, |
512 not_impD, not_iffD, not_allD, not_exD, not_notD]; |
512 not_impD, not_iffD, not_allD, not_exD, not_notD]; |
513 |
513 |
514 fun ok4nnf (Const (@{const_name Trueprop},_) $ (Const (@{const_name Not}, _) $ t)) = rigid t |
514 fun ok4nnf (Const (\<^const_name>\<open>Trueprop\<close>,_) $ (Const (\<^const_name>\<open>Not\<close>, _) $ t)) = rigid t |
515 | ok4nnf (Const (@{const_name Trueprop},_) $ t) = rigid t |
515 | ok4nnf (Const (\<^const_name>\<open>Trueprop\<close>,_) $ t) = rigid t |
516 | ok4nnf _ = false; |
516 | ok4nnf _ = false; |
517 |
517 |
518 fun make_nnf1 ctxt th = |
518 fun make_nnf1 ctxt th = |
519 if ok4nnf (Thm.concl_of th) |
519 if ok4nnf (Thm.concl_of th) |
520 then make_nnf1 ctxt (tryres(th, nnf_rls)) |
520 then make_nnf1 ctxt (tryres(th, nnf_rls)) |
535 (* FIXME: "let_simp" is probably redundant now that we also rewrite with |
535 (* FIXME: "let_simp" is probably redundant now that we also rewrite with |
536 "Let_def [abs_def]". *) |
536 "Let_def [abs_def]". *) |
537 val nnf_ss = |
537 val nnf_ss = |
538 simpset_of (put_simpset HOL_basic_ss @{context} |
538 simpset_of (put_simpset HOL_basic_ss @{context} |
539 addsimps nnf_extra_simps |
539 addsimps nnf_extra_simps |
540 addsimprocs [@{simproc defined_All}, @{simproc defined_Ex}, @{simproc neq}, |
540 addsimprocs [\<^simproc>\<open>defined_All\<close>, \<^simproc>\<open>defined_Ex\<close>, \<^simproc>\<open>neq\<close>, \<^simproc>\<open>let_simp\<close>]) |
541 @{simproc let_simp}]) |
|
542 |
541 |
543 val presimplified_consts = |
542 val presimplified_consts = |
544 [@{const_name simp_implies}, @{const_name False}, @{const_name True}, |
543 [\<^const_name>\<open>simp_implies\<close>, \<^const_name>\<open>False\<close>, \<^const_name>\<open>True\<close>, |
545 @{const_name Ex1}, @{const_name Ball}, @{const_name Bex}, @{const_name If}, |
544 \<^const_name>\<open>Ex1\<close>, \<^const_name>\<open>Ball\<close>, \<^const_name>\<open>Bex\<close>, \<^const_name>\<open>If\<close>, |
546 @{const_name Let}] |
545 \<^const_name>\<open>Let\<close>] |
547 |
546 |
548 fun presimplify ctxt = |
547 fun presimplify ctxt = |
549 rewrite_rule ctxt (map safe_mk_meta_eq nnf_simps) |
548 rewrite_rule ctxt (map safe_mk_meta_eq nnf_simps) |
550 #> simplify (put_simpset nnf_ss ctxt) |
549 #> simplify (put_simpset nnf_ss ctxt) |
551 #> rewrite_rule ctxt @{thms Let_def [abs_def]} |
550 #> rewrite_rule ctxt @{thms Let_def [abs_def]} |
615 val ext_cong_neq = @{thm ext_cong_neq} |
614 val ext_cong_neq = @{thm ext_cong_neq} |
616 |
615 |
617 (* Strengthens "f g ~= f h" to "f g ~= f h & (EX x. g x ~= h x)". *) |
616 (* Strengthens "f g ~= f h" to "f g ~= f h & (EX x. g x ~= h x)". *) |
618 fun cong_extensionalize_thm ctxt th = |
617 fun cong_extensionalize_thm ctxt th = |
619 (case Thm.concl_of th of |
618 (case Thm.concl_of th of |
620 @{const Trueprop} $ (@{const Not} |
619 \<^const>\<open>Trueprop\<close> $ (\<^const>\<open>Not\<close> |
621 $ (Const (@{const_name HOL.eq}, Type (_, [T, _])) |
620 $ (Const (\<^const_name>\<open>HOL.eq\<close>, Type (_, [T, _])) |
622 $ (t as _ $ _) $ (u as _ $ _))) => |
621 $ (t as _ $ _) $ (u as _ $ _))) => |
623 (case get_F_pattern T t u of |
622 (case get_F_pattern T t u of |
624 SOME p => th RS infer_instantiate ctxt [(("F", 0), Thm.cterm_of ctxt p)] ext_cong_neq |
623 SOME p => th RS infer_instantiate ctxt [(("F", 0), Thm.cterm_of ctxt p)] ext_cong_neq |
625 | NONE => th) |
624 | NONE => th) |
626 | _ => th) |
625 | _ => th) |
628 (* Removes the lambdas from an equation of the form "t = (%x1 ... xn. u)". It |
627 (* Removes the lambdas from an equation of the form "t = (%x1 ... xn. u)". It |
629 would be desirable to do this symmetrically but there's at least one existing |
628 would be desirable to do this symmetrically but there's at least one existing |
630 proof in "Tarski" that relies on the current behavior. *) |
629 proof in "Tarski" that relies on the current behavior. *) |
631 fun abs_extensionalize_conv ctxt ct = |
630 fun abs_extensionalize_conv ctxt ct = |
632 (case Thm.term_of ct of |
631 (case Thm.term_of ct of |
633 Const (@{const_name HOL.eq}, _) $ _ $ Abs _ => |
632 Const (\<^const_name>\<open>HOL.eq\<close>, _) $ _ $ Abs _ => |
634 ct |> (Conv.rewr_conv @{thm fun_eq_iff [THEN eq_reflection]} |
633 ct |> (Conv.rewr_conv @{thm fun_eq_iff [THEN eq_reflection]} |
635 then_conv abs_extensionalize_conv ctxt) |
634 then_conv abs_extensionalize_conv ctxt) |
636 | _ $ _ => Conv.comb_conv (abs_extensionalize_conv ctxt) ct |
635 | _ $ _ => Conv.comb_conv (abs_extensionalize_conv ctxt) ct |
637 | Abs _ => Conv.abs_conv (abs_extensionalize_conv o snd) ctxt ct |
636 | Abs _ => Conv.abs_conv (abs_extensionalize_conv o snd) ctxt ct |
638 | _ => Conv.all_conv ct) |
637 | _ => Conv.all_conv ct) |