| author | traytel |
| Wed, 08 May 2013 09:45:30 +0200 | |
| changeset 51916 | eac9e9a45bf5 |
| parent 51879 | ee9562d31778 |
| child 51998 | f732a674db1b |
| permissions | -rw-r--r-- |
|
51130
76d68444cd59
renamed sledgehammer_shrink to sledgehammer_compress
smolkas
parents:
51128
diff
changeset
|
1 |
(* Title: HOL/Tools/Sledgehammer/sledgehammer_preplay.ML |
| 50923 | 2 |
Author: Jasmin Blanchette, TU Muenchen |
3 |
Author: Steffen Juilf Smolka, TU Muenchen |
|
4 |
||
| 50924 | 5 |
Preplaying of isar proofs. |
| 50923 | 6 |
*) |
7 |
||
8 |
signature SLEDGEHAMMER_PREPLAY = |
|
9 |
sig |
|
10 |
type isar_step = Sledgehammer_Proof.isar_step |
|
| 50924 | 11 |
eqtype preplay_time |
12 |
val zero_preplay_time : preplay_time |
|
13 |
val some_preplay_time : preplay_time |
|
14 |
val add_preplay_time : preplay_time -> preplay_time -> preplay_time |
|
15 |
val string_of_preplay_time : preplay_time -> string |
|
| 51879 | 16 |
val try_metis : bool -> bool -> string -> string -> Proof.context -> |
| 51178 | 17 |
Time.time -> isar_step -> unit -> preplay_time |
| 51879 | 18 |
val try_metis_quietly : bool -> bool -> string -> string -> Proof.context -> |
| 51178 | 19 |
Time.time -> isar_step -> unit -> preplay_time |
| 50923 | 20 |
end |
21 |
||
22 |
structure Sledgehammer_Preplay : SLEDGEHAMMER_PREPLAY = |
|
23 |
struct |
|
24 |
||
25 |
open Sledgehammer_Util |
|
26 |
open Sledgehammer_Proof |
|
27 |
||
| 50924 | 28 |
(* The boolean flag encodes whether the time is exact (false) or an lower bound |
| 51131 | 29 |
(true): |
30 |
(t, false) = "t ms" |
|
31 |
(t, true) = "> t ms" *) |
|
| 50924 | 32 |
type preplay_time = bool * Time.time |
33 |
||
| 51131 | 34 |
val zero_preplay_time = (false, Time.zeroTime) (* 0 ms *) |
35 |
val some_preplay_time = (true, Time.zeroTime) (* > 0 ms *) |
|
| 50924 | 36 |
|
37 |
fun add_preplay_time (b1, t1) (b2, t2) = (b1 orelse b2, Time.+(t1,t2)) |
|
38 |
||
39 |
val string_of_preplay_time = ATP_Util.string_from_ext_time |
|
40 |
||
| 51879 | 41 |
(* preplay tracing *) |
42 |
fun preplay_trace ctxt assms concl time = |
|
43 |
let |
|
44 |
val ctxt = ctxt |> Config.put show_markup true |
|
45 |
val time = "[" ^ (string_of_preplay_time time) ^ "]" |> Pretty.str |
|
46 |
val nr_of_assms = length assms |
|
47 |
val assms = assms |> map (Display.pretty_thm ctxt) |
|
48 |
|> (fn [] => Pretty.str "" |
|
49 |
| [a] => a |
|
50 |
| assms => Pretty.enum ";" "⟦" "⟧" assms) |
|
51 |
val concl = concl |> Syntax.pretty_term ctxt |
|
52 |
val trace_list = [] |> cons concl |
|
53 |
|> nr_of_assms>0 ? cons (Pretty.str "⟹") |
|
54 |
|> cons assms |
|
55 |
|> cons time |
|
56 |
val pretty_trace = Pretty.blk(2, Pretty.breaks trace_list) |
|
57 |
in tracing (Pretty.string_of pretty_trace) end |
|
58 |
||
| 50923 | 59 |
(* timing *) |
60 |
fun take_time timeout tac arg = |
|
61 |
let |
|
62 |
val timing = Timing.start () |
|
63 |
in |
|
| 50924 | 64 |
(TimeLimit.timeLimit timeout tac arg; |
65 |
Timing.result timing |> #cpu |> pair false) |
|
66 |
handle TimeLimit.TimeOut => (true, timeout) |
|
| 50923 | 67 |
end |
68 |
||
69 |
(* lookup facts in context *) |
|
70 |
fun resolve_fact_names ctxt names = |
|
|
51179
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
71 |
(names |
| 50923 | 72 |
|>> map string_for_label |
73 |
|> op @ |
|
|
51179
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
74 |
|> maps (thms_of_name ctxt)) |
|
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
75 |
handle ERROR msg => error ("preplay error: " ^ msg)
|
| 50923 | 76 |
|
| 51879 | 77 |
(* turn terms/proofs into theorems *) |
| 51178 | 78 |
fun thm_of_term ctxt = Skip_Proof.make_thm (Proof_Context.theory_of ctxt) |
| 51879 | 79 |
fun thm_of_proof ctxt (Proof (Fix fixed_frees, Assume assms, steps)) = |
| 50923 | 80 |
let |
|
51179
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
81 |
val concl = (case try List.last steps of |
|
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
82 |
SOME (Prove (_, _, t, _)) => t |
| 51876 | 83 |
| _ => raise Fail "preplay error: malformed subproof") |
| 51178 | 84 |
val var_idx = maxidx_of_term concl + 1 |
85 |
fun var_of_free (x, T) = Var((x, var_idx), T) |
|
86 |
val substitutions = |
|
87 |
map (`var_of_free #> swap #> apfst Free) fixed_frees |
|
88 |
in |
|
|
51179
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
89 |
Logic.list_implies (assms |> map snd, concl) |
| 51178 | 90 |
|> subst_free substitutions |
91 |
|> thm_of_term ctxt |
|
92 |
end |
|
93 |
||
94 |
exception ZEROTIME |
|
| 51879 | 95 |
fun try_metis debug trace type_enc lam_trans ctxt timeout step = |
| 51178 | 96 |
let |
| 51879 | 97 |
val (prop, subproofs, fact_names, obtain) = |
| 50923 | 98 |
(case step of |
| 51178 | 99 |
Prove (_, _, t, By_Metis (subproofs, fact_names)) => |
100 |
(t, subproofs, fact_names, false) |
|
|
51179
0d5f8812856f
split isar_step into isar_step, fix, assms; made isar_proof explicit; register fixed variables in ctxt and auto_fix terms to avoid superfluous annotations
smolkas
parents:
51178
diff
changeset
|
101 |
| Obtain (_, Fix xs, _, t, By_Metis (subproofs, fact_names)) => |
| 50923 | 102 |
(* proof obligation: !!thesis. (!!x. A x ==> thesis) ==> thesis |
103 |
(see ~~/src/Pure/Isar/obtain.ML) *) |
|
104 |
let |
|
105 |
val thesis = Term.Free ("thesis", HOLogic.boolT)
|
|
106 |
val thesis_prop = thesis |> HOLogic.mk_Trueprop |
|
107 |
val frees = map Term.Free xs |
|
108 |
||
109 |
(* !!x1..xn. t ==> thesis (xs = [x1, .., xn]) *) |
|
110 |
val inner_prop = |
|
111 |
fold_rev Logic.all frees (Logic.mk_implies (t, thesis_prop)) |
|
112 |
||
113 |
(* !!thesis. (!!x1..xn. t ==> thesis) ==> thesis *) |
|
114 |
val prop = |
|
115 |
Logic.all thesis (Logic.mk_implies (inner_prop, thesis_prop)) |
|
116 |
in |
|
| 51178 | 117 |
(prop, subproofs, fact_names, true) |
| 50923 | 118 |
end |
119 |
| _ => raise ZEROTIME) |
|
120 |
val facts = |
|
| 51879 | 121 |
map (thm_of_proof ctxt) subproofs @ resolve_fact_names ctxt fact_names |
| 50923 | 122 |
val ctxt = ctxt |> Config.put Metis_Tactic.verbose debug |
123 |
|> obtain ? Config.put Metis_Tactic.new_skolem true |
|
124 |
val goal = |
|
| 51879 | 125 |
Goal.prove (Config.put Metis_Tactic.verbose debug ctxt) [] [] prop |
| 50923 | 126 |
fun tac {context = ctxt, prems = _} =
|
127 |
Metis_Tactic.metis_tac [type_enc] lam_trans ctxt facts 1 |
|
| 51879 | 128 |
fun run_tac () = goal tac |
129 |
handle ERROR msg => error ("preplay error: " ^ msg)
|
|
| 50923 | 130 |
in |
| 51879 | 131 |
fn () => |
132 |
let |
|
133 |
val preplay_time = take_time timeout run_tac () |
|
134 |
(* tracing *) |
|
135 |
val _ = if trace then preplay_trace ctxt facts prop preplay_time else () |
|
136 |
in |
|
137 |
preplay_time |
|
138 |
end |
|
| 50923 | 139 |
end |
| 50924 | 140 |
handle ZEROTIME => K zero_preplay_time |
| 50923 | 141 |
|
| 50924 | 142 |
(* this version treats exceptions like timeouts *) |
| 51879 | 143 |
fun try_metis_quietly debug trace type_enc lam_trans ctxt timeout = |
144 |
the_default (true, timeout) oo try |
|
145 |
o try_metis debug trace type_enc lam_trans ctxt timeout |
|
| 50923 | 146 |
|
147 |
end |