5 Transformation of axiom rules (elim/intro/etc) into CNF forms. |
5 Transformation of axiom rules (elim/intro/etc) into CNF forms. |
6 *) |
6 *) |
7 |
7 |
8 signature RES_AXIOMS = |
8 signature RES_AXIOMS = |
9 sig |
9 sig |
10 val cnf_axiom : string * thm -> thm list |
10 val cnf_axiom: thm -> thm list |
11 val cnf_name : string -> thm list |
11 val meta_cnf_axiom: thm -> thm list |
12 val meta_cnf_axiom : thm -> thm list |
12 val pairname: thm -> string * thm |
13 val pairname : thm -> string * thm |
13 val skolem_thm: thm -> thm list |
14 val skolem_thm : thm -> thm list |
14 val cnf_rules_pairs: (string * thm) list -> (thm * (string * int)) list |
15 val cnf_rules_pairs : (string * thm) list -> (thm * (string * int)) list |
15 val cnf_rules_of_ths: thm list -> thm list |
16 val meson_method_setup : theory -> theory |
16 val neg_clausify: thm list -> thm list |
17 val setup : theory -> theory |
17 val expand_defs_tac: thm -> tactic |
18 val clause_cache_setup : theory -> theory |
|
19 val assume_abstract_list: string -> thm list -> thm list |
18 val assume_abstract_list: string -> thm list -> thm list |
20 val neg_conjecture_clauses: thm -> int -> thm list * (string * typ) list |
19 val neg_conjecture_clauses: thm -> int -> thm list * (string * typ) list |
21 val claset_rules_of: Proof.context -> (string * thm) list (*FIXME DELETE*) |
20 val claset_rules_of: Proof.context -> (string * thm) list (*FIXME DELETE*) |
22 val simpset_rules_of: Proof.context -> (string * thm) list (*FIXME DELETE*) |
21 val simpset_rules_of: Proof.context -> (string * thm) list (*FIXME DELETE*) |
23 val atpset_rules_of: Proof.context -> (string * thm) list |
22 val atpset_rules_of: Proof.context -> (string * thm) list |
|
23 val meson_method_setup: theory -> theory |
|
24 val clause_cache_setup: theory -> theory |
|
25 val setup: theory -> theory |
24 end; |
26 end; |
25 |
27 |
26 structure ResAxioms = |
28 structure ResAxioms: RES_AXIOMS = |
27 struct |
29 struct |
28 |
30 |
29 (*For running the comparison between combinators and abstractions. |
31 (*For running the comparison between combinators and abstractions. |
30 CANNOT be a ref, as the setting is used while Isabelle is built. |
32 CANNOT be a ref, as the setting is used while Isabelle is built. |
31 Currently TRUE: the combinator code cannot be used with proof reconstruction |
33 Currently TRUE: the combinator code cannot be used with proof reconstruction |
47 (*Populate the abstraction cache with common combinators.*) |
49 (*Populate the abstraction cache with common combinators.*) |
48 fun seed th net = |
50 fun seed th net = |
49 let val (_,ct) = Thm.dest_abs NONE (Thm.rhs_of th) |
51 let val (_,ct) = Thm.dest_abs NONE (Thm.rhs_of th) |
50 val t = Logic.legacy_varify (term_of ct) |
52 val t = Logic.legacy_varify (term_of ct) |
51 in Net.insert_term Thm.eq_thm (t, th) net end; |
53 in Net.insert_term Thm.eq_thm (t, th) net end; |
52 |
54 |
53 val abstraction_cache = ref |
55 val abstraction_cache = ref |
54 (seed (thm"ATP_Linkup.I_simp") |
56 (seed (thm"ATP_Linkup.I_simp") |
55 (seed (thm"ATP_Linkup.B_simp") |
57 (seed (thm"ATP_Linkup.B_simp") |
56 (seed (thm"ATP_Linkup.K_simp") Net.empty))); |
58 (seed (thm"ATP_Linkup.K_simp") Net.empty))); |
57 |
59 |
58 |
60 |
59 (**** Transformation of Elimination Rules into First-Order Formulas****) |
61 (**** Transformation of Elimination Rules into First-Order Formulas****) |
60 |
62 |
61 val cfalse = cterm_of HOL.thy HOLogic.false_const; |
63 val cfalse = cterm_of HOL.thy HOLogic.false_const; |
64 (*Converts an elim-rule into an equivalent theorem that does not have the |
66 (*Converts an elim-rule into an equivalent theorem that does not have the |
65 predicate variable. Leaves other theorems unchanged. We simply instantiate the |
67 predicate variable. Leaves other theorems unchanged. We simply instantiate the |
66 conclusion variable to False.*) |
68 conclusion variable to False.*) |
67 fun transform_elim th = |
69 fun transform_elim th = |
68 case concl_of th of (*conclusion variable*) |
70 case concl_of th of (*conclusion variable*) |
69 Const("Trueprop",_) $ (v as Var(_,Type("bool",[]))) => |
71 Const("Trueprop",_) $ (v as Var(_,Type("bool",[]))) => |
70 Thm.instantiate ([], [(cterm_of HOL.thy v, cfalse)]) th |
72 Thm.instantiate ([], [(cterm_of HOL.thy v, cfalse)]) th |
71 | v as Var(_, Type("prop",[])) => |
73 | v as Var(_, Type("prop",[])) => |
72 Thm.instantiate ([], [(cterm_of HOL.thy v, ctp_false)]) th |
74 Thm.instantiate ([], [(cterm_of HOL.thy v, ctp_false)]) th |
73 | _ => th; |
75 | _ => th; |
74 |
76 |
75 (**** Transformation of Clasets and Simpsets into First-Order Axioms ****) |
77 (**** Transformation of Clasets and Simpsets into First-Order Axioms ****) |
76 |
78 |
165 end; |
167 end; |
166 |
168 |
167 (*Removes the lambdas from an equation of the form t = (%x. u). A non-negative n, |
169 (*Removes the lambdas from an equation of the form t = (%x. u). A non-negative n, |
168 serves as an upper bound on how many to remove.*) |
170 serves as an upper bound on how many to remove.*) |
169 fun strip_lambdas 0 th = th |
171 fun strip_lambdas 0 th = th |
170 | strip_lambdas n th = |
172 | strip_lambdas n th = |
171 case prop_of th of |
173 case prop_of th of |
172 _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) => |
174 _ $ (Const ("op =", _) $ _ $ Abs (x,_,_)) => |
173 strip_lambdas (n-1) (freeze_thm (th RS xfun_cong x)) |
175 strip_lambdas (n-1) (freeze_thm (th RS xfun_cong x)) |
174 | _ => th; |
176 | _ => th; |
175 |
177 |
176 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq, |
178 (*Convert meta- to object-equality. Fails for theorems like split_comp_eq, |
177 where some types have the empty sort.*) |
179 where some types have the empty sort.*) |
178 val meta_eq_to_obj_eq = thm "meta_eq_to_obj_eq"; |
180 val meta_eq_to_obj_eq = thm "meta_eq_to_obj_eq"; |
179 fun mk_object_eq th = th RS meta_eq_to_obj_eq |
181 fun mk_object_eq th = th RS meta_eq_to_obj_eq |
200 |
202 |
201 fun eq_absdef (th1, th2) = |
203 fun eq_absdef (th1, th2) = |
202 Context.joinable (theory_of_thm th1, theory_of_thm th2) andalso |
204 Context.joinable (theory_of_thm th1, theory_of_thm th2) andalso |
203 rhs_of th1 aconv rhs_of th2; |
205 rhs_of th1 aconv rhs_of th2; |
204 |
206 |
205 fun lambda_free (Abs _) = false |
207 val lambda_free = not o Term.has_abs; |
206 | lambda_free (t $ u) = lambda_free t andalso lambda_free u |
208 |
207 | lambda_free _ = true; |
209 val monomorphic = not o Term.exists_type (Term.exists_subtype Term.is_TVar); |
208 |
|
209 fun monomorphic t = |
|
210 Term.fold_types (Term.fold_atyps (fn TVar _ => K false | _ => I)) t true; |
|
211 |
210 |
212 fun dest_abs_list ct = |
211 fun dest_abs_list ct = |
213 let val (cv,ct') = Thm.dest_abs NONE ct |
212 let val (cv,ct') = Thm.dest_abs NONE ct |
214 val (cvs,cu) = dest_abs_list ct' |
213 val (cvs,cu) = dest_abs_list ct' |
215 in (cv::cvs, cu) end |
214 in (cv::cvs, cu) end |
216 handle CTERM _ => ([],ct); |
215 handle CTERM _ => ([],ct); |
217 |
216 |
218 fun lambda_list [] u = u |
|
219 | lambda_list (v::vs) u = lambda v (lambda_list vs u); |
|
220 |
|
221 fun abstract_rule_list [] [] th = th |
217 fun abstract_rule_list [] [] th = th |
222 | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th) |
218 | abstract_rule_list (v::vs) (ct::cts) th = abstract_rule v ct (abstract_rule_list vs cts th) |
223 | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]); |
219 | abstract_rule_list _ _ th = raise THM ("abstract_rule_list", 0, [th]); |
224 |
220 |
225 |
221 |
226 val Envir.Envir {asol = tenv0, iTs = tyenv0, ...} = Envir.empty 0 |
222 val Envir.Envir {asol = tenv0, iTs = tyenv0, ...} = Envir.empty 0 |
227 |
223 |
228 (*Does an existing abstraction definition have an RHS that matches the one we need now? |
224 (*Does an existing abstraction definition have an RHS that matches the one we need now? |
229 thy is the current theory, which must extend that of theorem th.*) |
225 thy is the current theory, which must extend that of theorem th.*) |
230 fun match_rhs thy t th = |
226 fun match_rhs thy t th = |
231 let val _ = Output.debug (fn()=> "match_rhs: " ^ string_of_cterm (cterm_of thy t) ^ |
227 let val _ = Output.debug (fn()=> "match_rhs: " ^ string_of_cterm (cterm_of thy t) ^ |
232 " against\n" ^ string_of_thm th); |
228 " against\n" ^ string_of_thm th); |
233 val (tyenv,tenv) = Pattern.first_order_match thy (rhs_of th, t) (tyenv0,tenv0) |
229 val (tyenv,tenv) = Pattern.first_order_match thy (rhs_of th, t) (tyenv0,tenv0) |
234 val term_insts = map Meson.term_pair_of (Vartab.dest tenv) |
230 val term_insts = map Meson.term_pair_of (Vartab.dest tenv) |
235 val ct_pairs = if subthy (theory_of_thm th, thy) andalso |
231 val ct_pairs = if subthy (theory_of_thm th, thy) andalso |
236 forall lambda_free (map #2 term_insts) |
232 forall lambda_free (map #2 term_insts) |
237 then map (pairself (cterm_of thy)) term_insts |
233 then map (pairself (cterm_of thy)) term_insts |
238 else raise Pattern.MATCH (*Cannot allow lambdas in the instantiation*) |
234 else raise Pattern.MATCH (*Cannot allow lambdas in the instantiation*) |
239 fun ctyp2 (ixn, (S, T)) = (ctyp_of thy (TVar (ixn, S)), ctyp_of thy T) |
235 fun ctyp2 (ixn, (S, T)) = (ctyp_of thy (TVar (ixn, S)), ctyp_of thy T) |
240 val th' = cterm_instantiate ct_pairs th |
236 val th' = cterm_instantiate ct_pairs th |
241 in SOME (th, instantiate (map ctyp2 (Vartab.dest tyenv), []) th') end |
237 in SOME (th, instantiate (map ctyp2 (Vartab.dest tyenv), []) th') end |
257 val _ = Output.debug (fn()=>"Nested lambda: " ^ string_of_cterm cta); |
253 val _ = Output.debug (fn()=>"Nested lambda: " ^ string_of_cterm cta); |
258 val (u'_th,defs) = abstract thy cta |
254 val (u'_th,defs) = abstract thy cta |
259 val _ = Output.debug (fn()=>"Returned " ^ string_of_thm u'_th); |
255 val _ = Output.debug (fn()=>"Returned " ^ string_of_thm u'_th); |
260 val cu' = Thm.rhs_of u'_th |
256 val cu' = Thm.rhs_of u'_th |
261 val u' = term_of cu' |
257 val u' = term_of cu' |
262 val abs_v_u = lambda_list (map term_of cvs) u' |
258 val abs_v_u = fold_rev (lambda o term_of) cvs u' |
263 (*get the formal parameters: ALL variables free in the term*) |
259 (*get the formal parameters: ALL variables free in the term*) |
264 val args = term_frees abs_v_u |
260 val args = term_frees abs_v_u |
265 val _ = Output.debug (fn()=>Int.toString (length args) ^ " arguments"); |
261 val _ = Output.debug (fn()=>Int.toString (length args) ^ " arguments"); |
266 val rhs = list_abs_free (map dest_Free args, abs_v_u) |
262 val rhs = list_abs_free (map dest_Free args, abs_v_u) |
267 (*Forms a lambda-abstraction over the formal parameters*) |
263 (*Forms a lambda-abstraction over the formal parameters*) |
268 val _ = Output.debug (fn()=>"Looking up " ^ string_of_cterm cu'); |
264 val _ = Output.debug (fn()=>"Looking up " ^ string_of_cterm cu'); |
269 val thy = theory_of_thm u'_th |
265 val thy = theory_of_thm u'_th |
270 val (ax,ax',thy) = |
266 val (ax,ax',thy) = |
271 case List.mapPartial (match_rhs thy abs_v_u) |
267 case List.mapPartial (match_rhs thy abs_v_u) |
272 (Net.match_term (!abstraction_cache) u') of |
268 (Net.match_term (!abstraction_cache) u') of |
273 (ax,ax')::_ => |
269 (ax,ax')::_ => |
274 (Output.debug (fn()=>"Re-using axiom " ^ string_of_thm ax); |
270 (Output.debug (fn()=>"Re-using axiom " ^ string_of_thm ax); |
275 (ax,ax',thy)) |
271 (ax,ax',thy)) |
276 | [] => |
272 | [] => |
277 let val _ = Output.debug (fn()=>"Lookup was empty"); |
273 let val _ = Output.debug (fn()=>"Lookup was empty"); |
278 val Ts = map type_of args |
274 val Ts = map type_of args |
289 |> mk_object_eq |> strip_lambdas (length args) |
285 |> mk_object_eq |> strip_lambdas (length args) |
290 |> mk_meta_eq |> Meson.generalize |
286 |> mk_meta_eq |> Meson.generalize |
291 val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax) |
287 val (_,ax') = Option.valOf (match_rhs thy abs_v_u ax) |
292 val _ = Output.debug (fn()=> "Declaring: " ^ string_of_thm ax ^ "\n" ^ |
288 val _ = Output.debug (fn()=> "Declaring: " ^ string_of_thm ax ^ "\n" ^ |
293 "Instance: " ^ string_of_thm ax'); |
289 "Instance: " ^ string_of_thm ax'); |
294 val _ = abstraction_cache := Net.insert_term eq_absdef |
290 val _ = abstraction_cache := Net.insert_term eq_absdef |
295 ((Logic.varify u'), ax) (!abstraction_cache) |
291 ((Logic.varify u'), ax) (!abstraction_cache) |
296 handle Net.INSERT => |
292 handle Net.INSERT => |
297 raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax]) |
293 raise THM ("declare_absfuns: INSERT", 0, [th,u'_th,ax]) |
298 in (ax,ax',thy) end |
294 in (ax,ax',thy) end |
299 in Output.debug (fn()=>"Lookup result: " ^ string_of_thm ax'); |
295 in Output.debug (fn()=>"Lookup result: " ^ string_of_thm ax'); |
330 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs) |
326 val (vs,Tvs) = ListPair.unzip (map (dest_Free o term_of) cvs) |
331 val (u'_th,defs) = abstract cta |
327 val (u'_th,defs) = abstract cta |
332 val cu' = Thm.rhs_of u'_th |
328 val cu' = Thm.rhs_of u'_th |
333 val u' = term_of cu' |
329 val u' = term_of cu' |
334 (*Could use Thm.cabs instead of lambda to work at level of cterms*) |
330 (*Could use Thm.cabs instead of lambda to work at level of cterms*) |
335 val abs_v_u = lambda_list (map term_of cvs) (term_of cu') |
331 val abs_v_u = fold_rev (lambda o term_of) cvs (term_of cu') |
336 (*get the formal parameters: free variables not present in the defs |
332 (*get the formal parameters: free variables not present in the defs |
337 (to avoid taking abstraction function names as parameters) *) |
333 (to avoid taking abstraction function names as parameters) *) |
338 val args = filter (valid_name defs) (term_frees abs_v_u) |
334 val args = filter (valid_name defs) (term_frees abs_v_u) |
339 val crhs = list_cabs (map cterm args, cterm abs_v_u) |
335 val crhs = list_cabs (map cterm args, cterm abs_v_u) |
340 (*Forms a lambda-abstraction over the formal parameters*) |
336 (*Forms a lambda-abstraction over the formal parameters*) |
341 val rhs = term_of crhs |
337 val rhs = term_of crhs |
342 val (ax,ax') = |
338 val (ax,ax') = |
343 case List.mapPartial (match_rhs thy abs_v_u) |
339 case List.mapPartial (match_rhs thy abs_v_u) |
344 (Net.match_term (!abstraction_cache) u') of |
340 (Net.match_term (!abstraction_cache) u') of |
345 (ax,ax')::_ => |
341 (ax,ax')::_ => |
346 (Output.debug (fn()=>"Re-using axiom " ^ string_of_thm ax); |
342 (Output.debug (fn()=>"Re-using axiom " ^ string_of_thm ax); |
347 (ax,ax')) |
343 (ax,ax')) |
348 | [] => |
344 | [] => |
349 let val Ts = map type_of args |
345 let val Ts = map type_of args |
350 val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu')) |
346 val const_ty = Ts ---> (Tvs ---> typ_of (ctyp_of_term cu')) |
481 fun copy (ref tab) : T = ref tab; |
477 fun copy (ref tab) : T = ref tab; |
482 val extend = copy; |
478 val extend = copy; |
483 fun merge _ (ref tab1, ref tab2) : T = ref (Thmtab.merge (K true) (tab1, tab2)); |
479 fun merge _ (ref tab1, ref tab2) : T = ref (Thmtab.merge (K true) (tab1, tab2)); |
484 ); |
480 ); |
485 |
481 |
486 (*The cache prevents repeated clausification of a theorem, and also repeated declaration of |
482 (*The cache prevents repeated clausification of a theorem, and also repeated declaration of |
487 Skolem functions. The global one holds theorems proved prior to this point. Theory data |
483 Skolem functions. The global one holds theorems proved prior to this point. Theory data |
488 holds the remaining ones.*) |
484 holds the remaining ones.*) |
489 val global_clause_cache = ref (Thmtab.empty : (thm list) Thmtab.table); |
485 val global_clause_cache = ref (Thmtab.empty : (thm list) Thmtab.table); |
490 |
486 |
491 (*Populate the clause cache using the supplied theorem. Return the clausal form |
487 (*Populate the clause cache using the supplied theorem. Return the clausal form |
493 fun skolem_cache_thm clause_cache th thy = |
489 fun skolem_cache_thm clause_cache th thy = |
494 case Thmtab.lookup (!clause_cache) th of |
490 case Thmtab.lookup (!clause_cache) th of |
495 NONE => |
491 NONE => |
496 (case skolem thy (Thm.transfer thy th) of |
492 (case skolem thy (Thm.transfer thy th) of |
497 NONE => ([th],thy) |
493 NONE => ([th],thy) |
498 | SOME (cls,thy') => |
494 | SOME (cls,thy') => |
499 (if null cls |
495 (if null cls |
500 then warning ("skolem_cache: empty clause set for " ^ string_of_thm th) |
496 then warning ("skolem_cache: empty clause set for " ^ string_of_thm th) |
501 else (); |
497 else (); |
502 change clause_cache (Thmtab.update (th, cls)); |
498 change clause_cache (Thmtab.update (th, cls)); |
503 (cls,thy'))) |
499 (cls,thy'))) |
504 | SOME cls => (cls,thy); |
500 | SOME cls => (cls,thy); |
505 |
501 |
506 (*Exported function to convert Isabelle theorems into axiom clauses*) |
502 (*Exported function to convert Isabelle theorems into axiom clauses*) |
507 fun cnf_axiom th = |
503 fun cnf_axiom th = |
508 let val cache = ThmCache.get (Thm.theory_of_thm th) |
504 let val cache = ThmCache.get (Thm.theory_of_thm th) |
509 handle ERROR _ => global_clause_cache |
505 handle ERROR _ => global_clause_cache |
510 val in_cache = if cache = global_clause_cache then NONE else Thmtab.lookup (!cache) th |
506 val in_cache = if cache = global_clause_cache then NONE else Thmtab.lookup (!cache) th |
511 in |
507 in |
512 case in_cache of |
508 case in_cache of |
513 NONE => |
509 NONE => |
514 (case Thmtab.lookup (!global_clause_cache) th of |
510 (case Thmtab.lookup (!global_clause_cache) th of |
515 NONE => |
511 NONE => |
516 let val cls = map Goal.close_result (skolem_thm th) |
512 let val cls = map Goal.close_result (skolem_thm th) |
517 in Output.debug (fn () => Int.toString (length cls) ^ " clauses inserted into cache: " ^ |
513 in Output.debug (fn () => Int.toString (length cls) ^ " clauses inserted into cache: " ^ |
518 (if PureThy.has_name_hint th then PureThy.get_name_hint th |
514 (if PureThy.has_name_hint th then PureThy.get_name_hint th |
519 else string_of_thm th)); |
515 else string_of_thm th)); |
520 change cache (Thmtab.update (th, cls)); cls |
516 change cache (Thmtab.update (th, cls)); cls |
521 end |
517 end |
522 | SOME cls => cls) |
518 | SOME cls => cls) |
523 | SOME cls => cls |
519 | SOME cls => cls |
524 end; |
520 end; |
525 |
521 |
526 fun pairname th = (PureThy.get_name_hint th, th); |
522 fun pairname th = (PureThy.get_name_hint th, th); |
527 |
523 |
603 fun expand_defs_tac st0 st = |
599 fun expand_defs_tac st0 st = |
604 let val hyps0 = #hyps (rep_thm st0) |
600 let val hyps0 = #hyps (rep_thm st0) |
605 val hyps = #hyps (crep_thm st) |
601 val hyps = #hyps (crep_thm st) |
606 val newhyps = filter_out (member (op aconv) hyps0 o Thm.term_of) hyps |
602 val newhyps = filter_out (member (op aconv) hyps0 o Thm.term_of) hyps |
607 val defs = filter (is_absko o Thm.term_of) newhyps |
603 val defs = filter (is_absko o Thm.term_of) newhyps |
608 val remaining_hyps = filter_out (member (op aconv) (map Thm.term_of defs)) |
604 val remaining_hyps = filter_out (member (op aconv) (map Thm.term_of defs)) |
609 (map Thm.term_of hyps) |
605 (map Thm.term_of hyps) |
610 val fixed = term_frees (concl_of st) @ |
606 val fixed = term_frees (concl_of st) @ |
611 foldl (gen_union (op aconv)) [] (map term_frees remaining_hyps) |
607 foldl (gen_union (op aconv)) [] (map term_frees remaining_hyps) |
612 in Output.debug (fn _ => "expand_defs_tac: " ^ string_of_thm st); |
608 in Output.debug (fn _ => "expand_defs_tac: " ^ string_of_thm st); |
613 Output.debug (fn _ => " st0: " ^ string_of_thm st0); |
609 Output.debug (fn _ => " st0: " ^ string_of_thm st0); |
650 let val st = Seq.hd (neg_skolemize_tac n st0) |
646 let val st = Seq.hd (neg_skolemize_tac n st0) |
651 val (params,_,_) = strip_context (Logic.nth_prem (n, Thm.prop_of st)) |
647 val (params,_,_) = strip_context (Logic.nth_prem (n, Thm.prop_of st)) |
652 in (neg_clausify (Option.valOf (metahyps_thms n st)), params) end |
648 in (neg_clausify (Option.valOf (metahyps_thms n st)), params) end |
653 handle Option => raise ERROR "unable to Skolemize subgoal"; |
649 handle Option => raise ERROR "unable to Skolemize subgoal"; |
654 |
650 |
655 (*Conversion of a subgoal to conjecture clauses. Each clause has |
651 (*Conversion of a subgoal to conjecture clauses. Each clause has |
656 leading !!-bound universal variables, to express generality. *) |
652 leading !!-bound universal variables, to express generality. *) |
657 val neg_clausify_tac = |
653 val neg_clausify_tac = |
658 neg_skolemize_tac THEN' |
654 neg_skolemize_tac THEN' |
659 SUBGOAL |
655 SUBGOAL |
660 (fn (prop,_) => |
656 (fn (prop,_) => |
661 let val ts = Logic.strip_assums_hyp prop |
657 let val ts = Logic.strip_assums_hyp prop |
662 in EVERY1 |
658 in EVERY1 |
663 [METAHYPS |
659 [METAHYPS |
664 (fn hyps => |
660 (fn hyps => |
665 (Method.insert_tac |
661 (Method.insert_tac |
666 (map forall_intr_vars (neg_clausify hyps)) 1)), |
662 (map forall_intr_vars (neg_clausify hyps)) 1)), |
667 REPEAT_DETERM_N (length ts) o (etac thin_rl)] |
663 REPEAT_DETERM_N (length ts) o (etac thin_rl)] |
668 end); |
664 end); |
669 |
665 |
670 (** The Skolemization attribute **) |
666 (** The Skolemization attribute **) |
671 |
667 |
672 fun conj2_rule (th1,th2) = conjI OF [th1,th2]; |
668 fun conj2_rule (th1,th2) = conjI OF [th1,th2]; |
683 val setup_attrs = Attrib.add_attributes |
679 val setup_attrs = Attrib.add_attributes |
684 [("skolem", Attrib.no_args skolem_attr, "skolemization of a theorem"), |
680 [("skolem", Attrib.no_args skolem_attr, "skolemization of a theorem"), |
685 ("clausify", clausify, "conversion of theorem to clauses")]; |
681 ("clausify", clausify, "conversion of theorem to clauses")]; |
686 |
682 |
687 val setup_methods = Method.add_methods |
683 val setup_methods = Method.add_methods |
688 [("neg_clausify", Method.no_args (Method.SIMPLE_METHOD' neg_clausify_tac), |
684 [("neg_clausify", Method.no_args (Method.SIMPLE_METHOD' neg_clausify_tac), |
689 "conversion of goal to conjecture clauses")]; |
685 "conversion of goal to conjecture clauses")]; |
690 |
686 |
691 val setup = clause_cache_setup #> ThmCache.init #> setup_attrs #> setup_methods; |
687 val setup = clause_cache_setup #> ThmCache.init #> setup_attrs #> setup_methods; |
692 |
688 |
693 end; |
689 end; |