author | desharna |
Thu, 27 Mar 2025 16:35:41 +0100 | |
changeset 82364 | 5af097d05e99 |
parent 82363 | 3a7fc54b50ca |
child 82366 | 7816e7be7bc7 |
permissions | -rw-r--r-- |
82364 | 1 |
(* Title: HOL/Tools/try0.ML |
2 |
Author: Jasmin Blanchette, LMU Muenchen |
|
3 |
Author: Martin Desharnais, LMU Muenchen |
|
4 |
Author: Fabian Huch, TU Muenchen |
|
38942
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
5 |
|
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
6 |
Try a combination of proof methods. |
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
7 |
*) |
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
8 |
|
46641 | 9 |
signature TRY0 = |
38942
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
10 |
sig |
82360 | 11 |
val serial_commas : string -> string list -> string list |
12 |
||
82355 | 13 |
type xref = Facts.ref * Token.src list |
82364 | 14 |
|
15 |
type facts = |
|
16 |
{usings: xref list, |
|
17 |
simps : xref list, |
|
18 |
intros : xref list, |
|
19 |
elims : xref list, |
|
20 |
dests : xref list} |
|
21 |
val empty_facts : facts |
|
22 |
||
82213 | 23 |
type result = {name: string, command: string, time: Time.time, state: Proof.state} |
82364 | 24 |
type proof_method = Time.time option -> facts -> Proof.state -> result option |
82358 | 25 |
type proof_method_options = {run_if_auto_try: bool} |
26 |
||
27 |
val register_proof_method : string -> proof_method_options -> proof_method -> unit |
|
28 |
val get_proof_method : string -> proof_method option |
|
82363
3a7fc54b50ca
tuned and moved configuration of auto_try0 to theory HOL
desharna
parents:
82362
diff
changeset
|
29 |
val get_all_proof_method_names : unit -> string list |
82358 | 30 |
|
82360 | 31 |
datatype mode = Auto_Try | Try | Normal |
82364 | 32 |
val generic_try0 : mode -> Time.time option -> facts -> Proof.state -> |
82360 | 33 |
(bool * (string * string list)) * result list |
82364 | 34 |
val try0 : Time.time option -> facts -> Proof.state -> result list |
81365 | 35 |
end |
38942
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
36 |
|
46641 | 37 |
structure Try0 : TRY0 = |
38942
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
38 |
struct |
e10c11971fa7
"try" -- a new diagnosis tool that tries to apply several methods in parallel
blanchet
parents:
diff
changeset
|
39 |
|
82360 | 40 |
fun serial_commas _ [] = ["??"] |
41 |
| serial_commas _ [s] = [s] |
|
42 |
| serial_commas conj [s1, s2] = [s1, conj, s2] |
|
43 |
| serial_commas conj [s1, s2, s3] = [s1 ^ ",", s2 ^ ",", conj, s3] |
|
44 |
| serial_commas conj (s :: ss) = s ^ "," :: serial_commas conj ss; |
|
45 |
||
81365 | 46 |
val noneN = "none" |
43026
0f15575a6465
handle non-auto try cases gracefully in Try Methods
blanchet
parents:
43024
diff
changeset
|
47 |
|
81365 | 48 |
datatype mode = Auto_Try | Try | Normal |
43020
abb5d1f907e4
added "try" command, to launch Solve Direct, Quickcheck, Nitpick, Sledgehammer, and Try Methods
blanchet
parents:
43018
diff
changeset
|
49 |
|
81365 | 50 |
val default_timeout = seconds 5.0 |
38944 | 51 |
|
81369
0677712016b5
try0: add 'use' modifier for thms to insert;
Fabian Huch <huch@in.tum.de>
parents:
81368
diff
changeset
|
52 |
datatype modifier = Use | Simp | Intro | Elim | Dest |
82355 | 53 |
type xref = Facts.ref * Token.src list |
54 |
type tagged_xref = xref * modifier list |
|
82364 | 55 |
type facts = |
56 |
{usings: xref list, |
|
57 |
simps : xref list, |
|
58 |
intros : xref list, |
|
59 |
elims : xref list, |
|
60 |
dests : xref list} |
|
61 |
||
62 |
val empty_facts: facts = {usings = [], simps = [], intros = [], elims = [], dests = []} |
|
63 |
fun union_facts (left : facts) (right : facts) : facts = |
|
64 |
{usings = #usings left @ #usings right, |
|
65 |
simps = #simps left @ #simps right, |
|
66 |
intros = #intros left @ #intros right, |
|
67 |
elims = #elims left @ #elims right, |
|
68 |
dests = #dests left @ #dests right} |
|
81366 | 69 |
|
82213 | 70 |
type result = {name: string, command: string, time: Time.time, state: Proof.state} |
82364 | 71 |
type proof_method = Time.time option -> facts -> Proof.state -> result option |
82356 | 72 |
type proof_method_options = {run_if_auto_try: bool} |
73 |
||
74 |
val noop_proof_method : proof_method = fn _ => fn _ => fn _ => NONE |
|
75 |
||
76 |
local |
|
77 |
val proof_methods = |
|
78 |
Synchronized.var "Try0.proof_methods" (Symtab.empty : proof_method Symtab.table); |
|
79 |
val auto_try_proof_methods_names = |
|
80 |
Synchronized.var "Try0.auto_try_proof_methods" (Symset.empty : Symset.T); |
|
81 |
in |
|
82 |
||
83 |
fun register_proof_method name ({run_if_auto_try} : proof_method_options) proof_method = |
|
84 |
let |
|
85 |
val () = if name = "" then error "Registering unnamed proof method" else () |
|
82364 | 86 |
val () = Synchronized.change proof_methods (Symtab.update (name, proof_method)) |
82356 | 87 |
val () = |
88 |
if run_if_auto_try then |
|
89 |
Synchronized.change auto_try_proof_methods_names (Symset.insert name) |
|
90 |
else |
|
91 |
() |
|
92 |
in () end |
|
93 |
||
82358 | 94 |
fun get_proof_method (name : string) : proof_method option = |
95 |
Symtab.lookup (Synchronized.value proof_methods) name; |
|
82356 | 96 |
|
82358 | 97 |
fun get_all_proof_methods () : (string * proof_method) list = |
82356 | 98 |
Symtab.fold (fn x => fn xs => x :: xs) (Synchronized.value proof_methods) [] |
99 |
||
82358 | 100 |
fun get_all_proof_method_names () : string list = |
82356 | 101 |
Symtab.fold (fn (name, _) => fn names => name :: names) (Synchronized.value proof_methods) [] |
102 |
||
103 |
fun get_all_auto_try_proof_method_names () : string list = |
|
104 |
Symset.dest (Synchronized.value auto_try_proof_methods_names) |
|
105 |
||
106 |
fun should_auto_try_proof_method (name : string) : bool = |
|
107 |
Symset.member (Synchronized.value auto_try_proof_methods_names) name |
|
108 |
||
109 |
end |
|
110 |
||
111 |
fun get_proof_method_or_noop name = |
|
112 |
(case get_proof_method name of |
|
113 |
NONE => noop_proof_method |
|
114 |
| SOME proof_method => proof_method) |
|
115 |
||
116 |
fun maybe_apply_proof_method name mode : proof_method = |
|
117 |
if mode <> Auto_Try orelse should_auto_try_proof_method name then |
|
118 |
get_proof_method_or_noop name |
|
119 |
else |
|
120 |
noop_proof_method |
|
121 |
||
122 |
fun time_string time = string_of_int (Time.toMilliseconds time) ^ " ms" |
|
123 |
fun tool_time_string (s, time) = s ^ ": " ^ time_string time |
|
124 |
||
82364 | 125 |
fun generic_try0 mode timeout_opt (facts : facts) st = |
82356 | 126 |
let |
82364 | 127 |
fun try_method (method : mode -> proof_method) = method mode timeout_opt facts st |
82356 | 128 |
fun get_message {command, time, ...} = "Found proof: " ^ Active.sendback_markup_command |
129 |
command ^ " (" ^ time_string time ^ ")" |
|
130 |
val print_step = Option.map (tap (writeln o get_message)) |
|
131 |
fun get_results methods : result list = |
|
132 |
if mode = Normal then |
|
133 |
methods |
|
134 |
|> Par_List.map (try_method #> print_step) |
|
135 |
|> map_filter I |
|
136 |
|> sort (Time.compare o apply2 #time) |
|
137 |
else |
|
138 |
methods |
|
139 |
|> Par_List.get_some try_method |
|
140 |
|> the_list |
|
141 |
val proof_method_names = get_all_proof_method_names () |
|
142 |
val maybe_apply_methods = map maybe_apply_proof_method proof_method_names |
|
143 |
in |
|
144 |
if mode = Normal then |
|
145 |
let val names = map quote proof_method_names in |
|
82360 | 146 |
writeln ("Trying " ^ implode_space (serial_commas "and" names) ^ "...") |
82356 | 147 |
end |
148 |
else |
|
149 |
(); |
|
150 |
(case get_results maybe_apply_methods of |
|
151 |
[] => (if mode = Normal then writeln "No proof found" else (); ((false, (noneN, [])), [])) |
|
152 |
| results as {name, command, ...} :: _ => |
|
153 |
let |
|
154 |
val method_times = |
|
155 |
results |
|
156 |
|> map (fn {name, time, ...} => (time, name)) |
|
157 |
|> AList.coalesce (op =) |
|
158 |
|> map (swap o apsnd commas) |
|
159 |
val message = |
|
160 |
(case mode of |
|
161 |
Auto_Try => "Auto Try0 found a proof" |
|
162 |
| Try => "Try0 found a proof" |
|
163 |
| Normal => "Try this") ^ ": " ^ |
|
164 |
Active.sendback_markup_command command ^ |
|
165 |
(case method_times of |
|
166 |
[(_, ms)] => " (" ^ time_string ms ^ ")" |
|
167 |
| method_times => "\n(" ^ space_implode "; " (map tool_time_string method_times) ^ ")") |
|
168 |
in |
|
169 |
((true, (name, if mode = Auto_Try then [message] else (writeln message; []))), results) |
|
170 |
end) |
|
171 |
end |
|
172 |
||
173 |
fun try0 timeout_opt = snd oo generic_try0 Normal timeout_opt |
|
174 |
||
82364 | 175 |
fun try0_trans (facts : facts) = |
82356 | 176 |
Toplevel.keep_proof |
82364 | 177 |
(ignore o generic_try0 Normal (SOME default_timeout) facts o Toplevel.proof_of) |
82356 | 178 |
|
179 |
val parse_fact_refs = Scan.repeat1 (Scan.unless (Parse.name -- Args.colon) Parse.thm) |
|
180 |
||
181 |
val parse_attr = |
|
82364 | 182 |
Args.$$$ "simp" |-- Args.colon |-- parse_fact_refs >> (fn xrefs => |
183 |
{usings = [], simps = xrefs, intros = [], elims = [], dests = []}) |
|
184 |
|| Args.$$$ "intro" |-- Args.colon |-- parse_fact_refs >> (fn xrefs => |
|
185 |
{usings = [], simps = [], intros = xrefs, elims = [], dests = []}) |
|
186 |
|| Args.$$$ "elim" |-- Args.colon |-- parse_fact_refs >> (fn xrefs => |
|
187 |
{usings = [], simps = [], intros = [], elims = xrefs, dests = []}) |
|
188 |
|| Args.$$$ "dest" |-- Args.colon |-- parse_fact_refs >> (fn xrefs => |
|
189 |
{usings = [], simps = [], intros = [], elims = [], dests = xrefs}) |
|
82356 | 190 |
|
191 |
fun parse_attrs x = |
|
192 |
(Args.parens parse_attrs |
|
82364 | 193 |
|| Scan.repeat parse_attr >> (fn factss => fold union_facts factss empty_facts)) x |
82356 | 194 |
|
195 |
val _ = |
|
196 |
Outer_Syntax.command \<^command_keyword>\<open>try0\<close> "try a combination of proof methods" |
|
82364 | 197 |
(Scan.optional parse_attrs empty_facts #>> try0_trans) |
82356 | 198 |
|
82216 | 199 |
end |