author | nipkow |
Tue, 17 Jun 2025 14:11:40 +0200 | |
changeset 82733 | 8b537e1af2ec |
parent 82578 | cf21066637d7 |
permissions | -rw-r--r-- |
82360 | 1 |
(* Title: HOL/Tools/try0_hol.ML |
2 |
Author: Jasmin Blanchette, LMU Muenchen |
|
3 |
Author: Martin Desharnais, LMU Muenchen |
|
4 |
Author: Fabian Huch, TU Muenchen |
|
5 |
||
6 |
General-purpose functions used by Try0. |
|
7 |
*) |
|
8 |
||
9 |
signature TRY0_UTIL = |
|
10 |
sig |
|
11 |
val string_of_xref : Try0.xref -> string |
|
82364 | 12 |
|
82577 | 13 |
type facts_config = |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
14 |
{usings_as_params : bool, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
15 |
simps_prefix : string option, |
82577 | 16 |
intros_prefix : string option, |
17 |
elims_prefix : string option, |
|
18 |
dests_prefix : string option} |
|
19 |
val full_attrs : facts_config |
|
20 |
val clas_attrs : facts_config |
|
21 |
val simp_attrs : facts_config |
|
22 |
val metis_attrs : facts_config |
|
23 |
val no_attrs : facts_config |
|
24 |
val apply_raw_named_method : string -> bool -> facts_config -> |
|
82364 | 25 |
(Proof.context -> Proof.context) -> Time.time option -> Try0.facts -> Proof.state -> |
82363
3a7fc54b50ca
tuned and moved configuration of auto_try0 to theory HOL
desharna
parents:
82361
diff
changeset
|
26 |
Try0.result option |
82360 | 27 |
end |
28 |
||
29 |
structure Try0_Util : TRY0_UTIL = struct |
|
30 |
||
31 |
fun string_of_xref ((xref, args) : Try0.xref) = |
|
32 |
(case xref of |
|
33 |
Facts.Fact literal => literal |> Symbol_Pos.explode0 |> Symbol_Pos.implode |> cartouche |
|
34 |
| _ => |
|
35 |
Facts.string_of_ref xref) ^ implode |
|
36 |
(map (enclose "[" "]" o Pretty.unformatted_string_of o Token.pretty_src \<^context>) args) |
|
37 |
||
82577 | 38 |
type facts_config = |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
39 |
{usings_as_params : bool, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
40 |
simps_prefix : string option, |
82577 | 41 |
intros_prefix : string option, |
42 |
elims_prefix : string option, |
|
43 |
dests_prefix : string option} |
|
82364 | 44 |
|
82577 | 45 |
val no_attrs : facts_config = |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
46 |
{usings_as_params = false, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
47 |
simps_prefix = NONE, |
82577 | 48 |
intros_prefix = NONE, |
49 |
elims_prefix = NONE, |
|
50 |
dests_prefix = NONE} |
|
51 |
val full_attrs : facts_config = |
|
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
52 |
{usings_as_params = false, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
53 |
simps_prefix = SOME "simp: ", |
82577 | 54 |
intros_prefix = SOME "intro: ", |
55 |
elims_prefix = SOME "elim: ", |
|
56 |
dests_prefix = SOME "dest: "} |
|
57 |
val clas_attrs : facts_config = |
|
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
58 |
{usings_as_params = false, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
59 |
simps_prefix = NONE, |
82577 | 60 |
intros_prefix = SOME "intro: ", |
61 |
elims_prefix = SOME "elim: ", |
|
62 |
dests_prefix = SOME "dest: "} |
|
63 |
val simp_attrs : facts_config = |
|
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
64 |
{usings_as_params = false, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
65 |
simps_prefix = SOME "add: ", |
82577 | 66 |
intros_prefix = NONE, |
67 |
elims_prefix = NONE, |
|
68 |
dests_prefix = NONE} |
|
69 |
val metis_attrs : facts_config = |
|
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
70 |
{usings_as_params = true, |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
71 |
simps_prefix = SOME "", |
82577 | 72 |
intros_prefix = SOME "", |
73 |
elims_prefix = SOME "", |
|
74 |
dests_prefix = SOME ""} |
|
82363
3a7fc54b50ca
tuned and moved configuration of auto_try0 to theory HOL
desharna
parents:
82361
diff
changeset
|
75 |
|
82361 | 76 |
local |
77 |
||
78 |
fun parse_method ctxt s = |
|
79 |
enclose "(" ")" s |
|
80 |
|> Token.explode (Thy_Header.get_keywords' ctxt) Position.start |
|
81 |
|> filter Token.is_proper |
|
82 |
|> Scan.read Token.stopper Method.parse |
|
83 |
|> (fn SOME (Method.Source src, _) => src | _ => raise Fail "expected Source") |
|
84 |
||
85 |
fun run_tac timeout_opt tac st = |
|
86 |
let val with_timeout = |
|
87 |
(case timeout_opt of SOME timeout => Timeout.apply_physical timeout | NONE => I) |
|
88 |
in with_timeout (Seq.pull o tac) st |> Option.map fst end |
|
89 |
||
90 |
val num_goals = Thm.nprems_of o #goal o Proof.goal |
|
91 |
||
92 |
fun apply_recursive recurse elapsed0 timeout_opt apply st = |
|
93 |
(case Timing.timing (Option.join o try (run_tac timeout_opt apply)) st of |
|
94 |
({elapsed, ...}, SOME st') => |
|
95 |
if recurse andalso num_goals st' > 0 andalso num_goals st' < num_goals st then |
|
96 |
let val timeout_opt1 = (Option.map (fn timeout => timeout - elapsed) timeout_opt) |
|
97 |
in apply_recursive recurse (elapsed0 + elapsed) timeout_opt1 apply st' end |
|
98 |
else (elapsed0 + elapsed, st') |
|
99 |
|_ => (elapsed0, st)) |
|
100 |
||
101 |
in |
|
102 |
||
82577 | 103 |
fun apply_raw_named_method (name : string) all_goals (facts_config: facts_config) |
82364 | 104 |
(silence_methods : Proof.context -> Proof.context) timeout_opt (facts : Try0.facts) |
82363
3a7fc54b50ca
tuned and moved configuration of auto_try0 to theory HOL
desharna
parents:
82361
diff
changeset
|
105 |
(st : Proof.state) : Try0.result option = |
82361 | 106 |
let |
82363
3a7fc54b50ca
tuned and moved configuration of auto_try0 to theory HOL
desharna
parents:
82361
diff
changeset
|
107 |
val st = Proof.map_contexts silence_methods st |
82361 | 108 |
val ctxt = Proof.context_of st |
109 |
||
82364 | 110 |
val (unused_simps, simps_attrs) = |
82368 | 111 |
if null (#simps facts) then |
112 |
([], "") |
|
82364 | 113 |
else |
82577 | 114 |
(case #simps_prefix facts_config of |
82368 | 115 |
NONE => (#simps facts, "") |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
116 |
| SOME prefix => ([], " " ^ prefix ^ implode_space (map string_of_xref (#simps facts)))) |
82364 | 117 |
|
118 |
val (unused_intros, intros_attrs) = |
|
82368 | 119 |
if null (#intros facts) then |
120 |
([], "") |
|
82364 | 121 |
else |
82577 | 122 |
(case #intros_prefix facts_config of |
82368 | 123 |
NONE => (#intros facts, "") |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
124 |
| SOME prefix => ([], " " ^ prefix ^ implode_space (map string_of_xref (#intros facts)))) |
82364 | 125 |
|
126 |
val (unused_elims, elims_attrs) = |
|
82368 | 127 |
if null (#elims facts) then |
128 |
([], "") |
|
82364 | 129 |
else |
82577 | 130 |
(case #elims_prefix facts_config of |
82368 | 131 |
NONE => (#elims facts, "") |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
132 |
| SOME prefix => ([], " " ^ prefix ^ implode_space (map string_of_xref (#elims facts)))) |
82364 | 133 |
|
134 |
val (unused_dests, dests_attrs) = |
|
82368 | 135 |
if null (#dests facts) then |
136 |
([], "") |
|
82364 | 137 |
else |
82577 | 138 |
(case #dests_prefix facts_config of |
82368 | 139 |
NONE => (#dests facts, "") |
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
140 |
| SOME prefix => ([], " " ^ prefix ^ implode_space (map string_of_xref (#dests facts)))) |
82364 | 141 |
|
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
142 |
val (unused_usings, using_attrs) = |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
143 |
if null (#usings facts) then |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
144 |
([], "") |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
145 |
else if #usings_as_params facts_config then |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
146 |
([], " " ^ implode_space (map string_of_xref (#usings facts))) |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
147 |
else |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
148 |
(#usings facts, "") |
82364 | 149 |
|
82578
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
150 |
val unused = unused_simps @ unused_intros @ unused_elims @ unused_dests @ unused_usings |
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
151 |
|
cf21066637d7
pass "using" facts as parameters to metis in try0
desharna
parents:
82577
diff
changeset
|
152 |
val attrs = simps_attrs ^ intros_attrs ^ elims_attrs ^ dests_attrs ^ using_attrs |
82361 | 153 |
val text = |
154 |
name ^ attrs |
|
155 |
|> parse_method ctxt |
|
156 |
|> Method.method_cmd ctxt |
|
157 |
|> Method.Basic |
|
158 |
|> (fn m => Method.Combinator (Method.no_combinator_info, Method.Select_Goals 1, [m])) |
|
159 |
||
160 |
val apply = |
|
82364 | 161 |
Proof.using [Attrib.eval_thms ctxt unused |> map (rpair [] o single)] |
162 |
#> Proof.refine text #> Seq.filter_results |
|
82361 | 163 |
val num_before = num_goals st |
164 |
val multiple_goals = all_goals andalso num_before > 1 |
|
165 |
val (time, st') = apply_recursive multiple_goals Time.zeroTime timeout_opt apply st |
|
166 |
val num_after = num_goals st' |
|
167 |
val select = "[" ^ string_of_int (num_before - num_after) ^ "]" |
|
168 |
val unused = implode_space (unused |> map string_of_xref) |
|
169 |
val command = |
|
170 |
(if unused <> "" then "using " ^ unused ^ " " else "") ^ |
|
171 |
(if num_after = 0 then "by " else "apply ") ^ |
|
172 |
(name ^ attrs |> attrs <> "" ? enclose "(" ")") ^ |
|
173 |
(if multiple_goals andalso num_after > 0 then select else "") |
|
174 |
in |
|
175 |
if num_before > num_after then |
|
176 |
SOME {name = name, command = command, time = time, state = st'} |
|
177 |
else NONE |
|
178 |
end |
|
179 |
||
180 |
end |
|
181 |
||
82577 | 182 |
end |