8 signature SLEDGEHAMMER_FACT_PREPROCESSOR = |
8 signature SLEDGEHAMMER_FACT_PREPROCESSOR = |
9 sig |
9 sig |
10 val chained_prefix: string |
10 val chained_prefix: string |
11 val trace: bool Unsynchronized.ref |
11 val trace: bool Unsynchronized.ref |
12 val trace_msg: (unit -> string) -> unit |
12 val trace_msg: (unit -> string) -> unit |
13 val skolem_Eps_pseudo_theory: string |
13 val skolem_theory_name: string |
14 val skolem_prefix: string |
14 val skolem_prefix: string |
15 val skolem_infix: string |
15 val skolem_infix: string |
16 val is_skolem_const_name: string -> bool |
16 val is_skolem_const_name: string -> bool |
17 val skolem_type_and_args: typ -> term -> typ * term list |
|
18 val cnf_axiom: theory -> thm -> thm list |
17 val cnf_axiom: theory -> thm -> thm list |
19 val multi_base_blacklist: string list |
18 val multi_base_blacklist: string list |
20 val is_theorem_bad_for_atps: thm -> bool |
19 val is_theorem_bad_for_atps: thm -> bool |
21 val type_has_topsort: typ -> bool |
20 val type_has_topsort: typ -> bool |
22 val cnf_rules_pairs: |
21 val cnf_rules_pairs: |
40 val chained_prefix = "Sledgehammer.chained_" |
39 val chained_prefix = "Sledgehammer.chained_" |
41 |
40 |
42 val trace = Unsynchronized.ref false; |
41 val trace = Unsynchronized.ref false; |
43 fun trace_msg msg = if !trace then tracing (msg ()) else (); |
42 fun trace_msg msg = if !trace then tracing (msg ()) else (); |
44 |
43 |
45 val skolem_Eps_pseudo_theory = "Sledgehammer.Eps" |
44 val skolem_theory_name = "Sledgehammer.Sko" |
46 val skolem_prefix = "sko_" |
45 val skolem_prefix = "sko_" |
47 val skolem_infix = "$" |
46 val skolem_infix = "$" |
48 |
47 |
49 fun freeze_thm th = #1 (Drule.legacy_freeze_thaw th); |
48 fun freeze_thm th = #1 (Drule.legacy_freeze_thaw th); |
50 |
49 |
74 exception Clausify_failure of theory; |
73 exception Clausify_failure of theory; |
75 |
74 |
76 |
75 |
77 (**** SKOLEMIZATION BY INFERENCE (lcp) ****) |
76 (**** SKOLEMIZATION BY INFERENCE (lcp) ****) |
78 |
77 |
79 fun skolem_Eps_const T = |
|
80 Const (@{const_name skolem_Eps}, (T --> HOLogic.boolT) --> T) |
|
81 |
|
82 (*Keep the full complexity of the original name*) |
78 (*Keep the full complexity of the original name*) |
83 fun flatten_name s = space_implode "_X" (Long_Name.explode s); |
79 fun flatten_name s = space_implode "_X" (Long_Name.explode s); |
84 |
80 |
85 fun skolem_name thm_name j var_name = |
81 fun skolem_name thm_name j var_name = |
86 skolem_prefix ^ thm_name ^ "_" ^ Int.toString j ^ |
82 skolem_prefix ^ thm_name ^ "_" ^ Int.toString j ^ |
118 (*Existential: declare a Skolem function, then insert into body and continue*) |
114 (*Existential: declare a Skolem function, then insert into body and continue*) |
119 let |
115 let |
120 val id = skolem_name s (Unsynchronized.inc skolem_count) s' |
116 val id = skolem_name s (Unsynchronized.inc skolem_count) s' |
121 val (cT, args) = skolem_type_and_args T body |
117 val (cT, args) = skolem_type_and_args T body |
122 val rhs = list_abs_free (map dest_Free args, |
118 val rhs = list_abs_free (map dest_Free args, |
123 skolem_Eps_const T $ body) |
119 HOLogic.choice_const T $ body) |
124 (*Forms a lambda-abstraction over the formal parameters*) |
120 (*Forms a lambda-abstraction over the formal parameters*) |
125 val (c, thy) = |
121 val (c, thy) = |
126 Sign.declare_const ((Binding.conceal (Binding.name id), cT), NoSyn) thy |
122 Sign.declare_const ((Binding.conceal (Binding.name id), cT), NoSyn) thy |
127 val cdef = id ^ "_def" |
123 val cdef = id ^ "_def" |
128 val ((_, ax), thy) = |
124 val ((_, ax), thy) = |
137 | dec_sko (@{const "op |"} $ p $ q) thx = dec_sko q (dec_sko p thx) |
133 | dec_sko (@{const "op |"} $ p $ q) thx = dec_sko q (dec_sko p thx) |
138 | dec_sko (@{const Trueprop} $ p) thx = dec_sko p thx |
134 | dec_sko (@{const Trueprop} $ p) thx = dec_sko p thx |
139 | dec_sko t thx = thx |
135 | dec_sko t thx = thx |
140 in dec_sko (prop_of th) ([], thy) end |
136 in dec_sko (prop_of th) ([], thy) end |
141 |
137 |
|
138 fun mk_skolem_id t = |
|
139 let val T = fastype_of t in Const (@{const_name skolem_id}, T --> T) $ t end |
|
140 |
142 (*Traverse a theorem, accumulating Skolem function definitions.*) |
141 (*Traverse a theorem, accumulating Skolem function definitions.*) |
143 fun assume_skolem_funs inline s th = |
142 fun assume_skolem_funs inline s th = |
144 let |
143 let |
145 val skolem_count = Unsynchronized.ref 0 (* FIXME ??? *) |
144 val skolem_count = Unsynchronized.ref 0 (* FIXME ??? *) |
146 fun dec_sko (Const (@{const_name Ex}, _) $ (body as Abs (s', T, p))) defs = |
145 fun dec_sko (Const (@{const_name Ex}, _) $ (body as Abs (s', T, p))) defs = |
150 val args = subtract (op =) skos (OldTerm.term_frees body) (*the formal parameters*) |
149 val args = subtract (op =) skos (OldTerm.term_frees body) (*the formal parameters*) |
151 val Ts = map type_of args |
150 val Ts = map type_of args |
152 val cT = Ts ---> T (* FIXME: use "skolem_type_and_args" *) |
151 val cT = Ts ---> T (* FIXME: use "skolem_type_and_args" *) |
153 val id = skolem_name s (Unsynchronized.inc skolem_count) s' |
152 val id = skolem_name s (Unsynchronized.inc skolem_count) s' |
154 val c = Free (id, cT) |
153 val c = Free (id, cT) |
155 val rhs = list_abs_free (map dest_Free args, skolem_Eps_const T $ body) |
154 val rhs = list_abs_free (map dest_Free args, |
|
155 HOLogic.choice_const T $ body) |
|
156 |> inline ? mk_skolem_id |
156 (*Forms a lambda-abstraction over the formal parameters*) |
157 (*Forms a lambda-abstraction over the formal parameters*) |
157 val def = Logic.mk_equals (c, rhs) |
158 val def = Logic.mk_equals (c, rhs) |
158 val comb = list_comb (if inline then rhs else c, args) |
159 val comb = list_comb (if inline then rhs else c, args) |
159 in dec_sko (subst_bound (comb, p)) (def :: defs) end |
160 in dec_sko (subst_bound (comb, p)) (def :: defs) end |
160 | dec_sko (Const (@{const_name All},_) $ Abs (a, T, p)) defs = |
161 | dec_sko (Const (@{const_name All},_) $ Abs (a, T, p)) defs = |
293 (*Given the definition of a Skolem function, return a theorem to replace |
294 (*Given the definition of a Skolem function, return a theorem to replace |
294 an existential formula by a use of that function. |
295 an existential formula by a use of that function. |
295 Example: "EX x. x : A & x ~: B ==> sko A B : A & sko A B ~: B" [.] *) |
296 Example: "EX x. x : A & x ~: B ==> sko A B : A & sko A B ~: B" [.] *) |
296 fun skolem_theorem_of_def inline def = |
297 fun skolem_theorem_of_def inline def = |
297 let |
298 let |
298 val (c,rhs) = Thm.dest_equals (cprop_of (freeze_thm def)) |
299 val (c, rhs) = Thm.dest_equals (cprop_of (freeze_thm def)) |
299 val (ch, frees) = c_variant_abs_multi (rhs, []) |
300 val rhs' = rhs |> inline ? (snd o Thm.dest_comb) |
300 val (chilbert,cabs) = Thm.dest_comb ch |
301 val (ch, frees) = c_variant_abs_multi (rhs', []) |
|
302 val (chilbert, cabs) = ch |> Thm.dest_comb |
301 val thy = Thm.theory_of_cterm chilbert |
303 val thy = Thm.theory_of_cterm chilbert |
302 val t = Thm.term_of chilbert |
304 val t = Thm.term_of chilbert |
303 val T = |
305 val T = |
304 case t of |
306 case t of |
305 Const (@{const_name skolem_Eps}, Type (@{type_name fun}, [_, T])) => T |
307 Const (@{const_name Eps}, Type (@{type_name fun}, [_, T])) => T |
306 | _ => raise THM ("skolem_theorem_of_def: expected \"Eps\"", 0, [def]) |
308 | _ => raise TERM ("skolem_theorem_of_def: expected \"Eps\"", [t]) |
307 val cex = Thm.cterm_of thy (HOLogic.exists_const T) |
309 val cex = Thm.cterm_of thy (HOLogic.exists_const T) |
308 val ex_tm = c_mkTrueprop (Thm.capply cex cabs) |
310 val ex_tm = c_mkTrueprop (Thm.capply cex cabs) |
309 and conc = |
311 and conc = |
310 Drule.list_comb (if inline then rhs else c, frees) |
312 Drule.list_comb (if inline then rhs else c, frees) |
311 |> Drule.beta_conv cabs |> c_mkTrueprop |
313 |> Drule.beta_conv cabs |> c_mkTrueprop |
312 fun tacf [prem] = |
314 fun tacf [prem] = |
313 (if inline then all_tac else rewrite_goals_tac [def]) |
315 (if inline then rewrite_goals_tac @{thms skolem_id_def_raw} |
314 THEN rtac (prem RS @{thm skolem_someI_ex}) 1 |
316 else rewrite_goals_tac [def]) |
|
317 THEN rtac ((prem |> inline ? rewrite_rule @{thms skolem_id_def_raw}) |
|
318 RS @{thm someI_ex}) 1 |
315 in Goal.prove_internal [ex_tm] conc tacf |
319 in Goal.prove_internal [ex_tm] conc tacf |
316 |> forall_intr_list frees |
320 |> forall_intr_list frees |
317 |> Thm.forall_elim_vars 0 (*Introduce Vars, but don't discharge defs.*) |
321 |> Thm.forall_elim_vars 0 (*Introduce Vars, but don't discharge defs.*) |
318 |> Thm.varifyT_global |
322 |> Thm.varifyT_global |
319 end; |
323 end; |
396 [] |
400 [] |
397 else |
401 else |
398 let |
402 let |
399 val ctxt0 = Variable.global_thm_context th |
403 val ctxt0 = Variable.global_thm_context th |
400 val (nnfth, ctxt) = to_nnf th ctxt0 |
404 val (nnfth, ctxt) = to_nnf th ctxt0 |
401 |
|
402 val inline = false |
|
403 (* |
|
404 FIXME: Reintroduce code: |
|
405 val inline = exists_type (exists_subtype (can dest_TFree)) (prop_of nnfth) |
405 val inline = exists_type (exists_subtype (can dest_TFree)) (prop_of nnfth) |
406 *) |
|
407 val defs = skolem_theorems_of_assume inline s nnfth |
406 val defs = skolem_theorems_of_assume inline s nnfth |
408 val (cnfs, ctxt) = Meson.make_cnf defs nnfth ctxt |
407 val (cnfs, ctxt) = Meson.make_cnf defs nnfth ctxt |
409 in |
408 in |
410 cnfs |> map introduce_combinators |
409 cnfs |> map introduce_combinators |
411 |> Variable.export ctxt ctxt0 |
410 |> Variable.export ctxt ctxt0 |
490 val new_thms = (new_facts, []) |-> fold (fn (name, ths) => |
489 val new_thms = (new_facts, []) |-> fold (fn (name, ths) => |
491 if member (op =) multi_base_blacklist (Long_Name.base_name name) then |
490 if member (op =) multi_base_blacklist (Long_Name.base_name name) then |
492 I |
491 I |
493 else |
492 else |
494 fold_index (fn (i, th) => |
493 fold_index (fn (i, th) => |
495 if is_theorem_bad_for_atps th orelse is_some (lookup_cache thy th) then |
494 if is_theorem_bad_for_atps th orelse |
|
495 is_some (lookup_cache thy th) then |
496 I |
496 I |
497 else |
497 else |
498 cons (name ^ "_" ^ string_of_int (i + 1), Thm.transfer thy th)) ths) |
498 cons (name ^ "_" ^ string_of_int (i + 1), Thm.transfer thy th)) ths) |
499 in |
499 in |
500 if null new_facts then |
500 if null new_facts then |