31 val is_locally_installed: Proof.context -> string -> bool |
31 val is_locally_installed: Proof.context -> string -> bool |
32 val is_remotely_available: Proof.context -> string -> bool |
32 val is_remotely_available: Proof.context -> string -> bool |
33 val default_max_relevant: Proof.context -> string -> int |
33 val default_max_relevant: Proof.context -> string -> int |
34 |
34 |
35 (*filter*) |
35 (*filter*) |
36 val smt_filter: bool -> Time.time -> Proof.state -> |
36 type 'a smt_filter_head_result = 'a list * (int option * thm) list * |
37 ('a * (int option * thm)) list -> int -> |
37 (((int * thm) list * Proof.context) * (int * (int option * thm)) list) |
38 {outcome: SMT_Failure.failure option, used_facts: ('a * thm) list, |
38 val smt_filter_head: Time.time -> Proof.state -> |
39 run_time_in_msecs: int option} |
39 ('a * (int option * thm)) list -> int -> 'a smt_filter_head_result |
|
40 val smt_filter_tail: bool -> 'a smt_filter_head_result -> |
|
41 {outcome: SMT_Failure.failure option, used_facts: ('a * thm) list} |
40 |
42 |
41 (*tactic*) |
43 (*tactic*) |
42 val smt_tac': bool -> Proof.context -> thm list -> int -> Tactical.tactic |
44 val smt_tac': bool -> Proof.context -> thm list -> int -> Tactical.tactic |
43 val smt_tac: Proof.context -> thm list -> int -> Tactical.tactic |
45 val smt_tac: Proof.context -> thm list -> int -> Tactical.tactic |
44 |
46 |
210 options: Proof.context -> string list, |
212 options: Proof.context -> string list, |
211 reconstruct: Proof.context -> string list * SMT_Translate.recon -> |
213 reconstruct: Proof.context -> string list * SMT_Translate.recon -> |
212 int list * thm, |
214 int list * thm, |
213 default_max_relevant: int } |
215 default_max_relevant: int } |
214 |
216 |
215 fun gen_solver name (info : solver_info) rm ctxt iwthms = |
217 fun gen_solver_head ctxt iwthms = |
|
218 SMT_Normalize.normalize ctxt iwthms |
|
219 |> rpair ctxt |
|
220 |-> SMT_Monomorph.monomorph |
|
221 |
|
222 fun gen_solver_tail (name, info : solver_info) rm (iwthms', ctxt) iwthms = |
216 let |
223 let |
217 val {env_var, is_remote, options, reconstruct, ...} = info |
224 val {env_var, is_remote, options, reconstruct, ...} = info |
218 val cmd = (rm, env_var, is_remote, name) |
225 val cmd = (rm, env_var, is_remote, name) |
219 in |
226 in |
220 SMT_Normalize.normalize ctxt iwthms |
227 (iwthms', ctxt) |
221 |> rpair ctxt |
228 |-> invoke name cmd options |
222 |-> SMT_Monomorph.monomorph |
229 |> reconstruct ctxt |
223 |> (fn (iwthms', ctxt') => invoke name cmd options iwthms' ctxt' |
|
224 |> reconstruct ctxt') |
|
225 |> (fn (idxs, thm) => thm |
230 |> (fn (idxs, thm) => thm |
226 |> tap (fn _ => trace_assumptions ctxt iwthms idxs) |
231 |> tap (fn _ => trace_assumptions ctxt iwthms idxs) |
227 |> pair idxs) |
232 |> pair idxs) |
228 end |
233 end |
229 |
234 |
282 fun name_and_solver_of ctxt = |
287 fun name_and_solver_of ctxt = |
283 let val name = C.solver_of ctxt |
288 let val name = C.solver_of ctxt |
284 in (name, get_info ctxt name) end |
289 in (name, get_info ctxt name) end |
285 |
290 |
286 val solver_name_of = fst o name_and_solver_of |
291 val solver_name_of = fst o name_and_solver_of |
287 fun solver_of ctxt = |
292 fun solver_of ctxt rm ctxt' = |
288 let val (name, raw_solver) = name_and_solver_of ctxt |
293 `(gen_solver_head ctxt') #-> gen_solver_tail (name_and_solver_of ctxt) rm |
289 in gen_solver name raw_solver end |
|
290 |
294 |
291 val available_solvers_of = Symtab.keys o Solvers.get o Context.Proof |
295 val available_solvers_of = Symtab.keys o Solvers.get o Context.Proof |
292 |
296 |
293 fun is_locally_installed ctxt name = |
297 fun is_locally_installed ctxt name = |
294 let val {env_var, ...} = get_info ctxt name |
298 let val {env_var, ...} = get_info ctxt name |
304 val has_topsort = Term.exists_type (Term.exists_subtype (fn |
308 val has_topsort = Term.exists_type (Term.exists_subtype (fn |
305 TFree (_, []) => true |
309 TFree (_, []) => true |
306 | TVar (_, []) => true |
310 | TVar (_, []) => true |
307 | _ => false)) |
311 | _ => false)) |
308 |
312 |
309 fun smt_solver rm ctxt iwthms = |
313 (* without this test, we would run into problems when atomizing the rules: *) |
310 (* without this test, we would run into problems when atomizing the rules: *) |
314 fun check_topsort iwthms = |
311 if exists (has_topsort o Thm.prop_of o snd o snd) iwthms then |
315 if exists (has_topsort o Thm.prop_of o snd o snd) iwthms then |
312 raise SMT_Failure.SMT (SMT_Failure.Other_Failure ("proof state " ^ |
316 raise SMT_Failure.SMT (SMT_Failure.Other_Failure ("proof state " ^ |
313 "contains the universal sort {}")) |
317 "contains the universal sort {}")) |
314 else solver_of ctxt rm ctxt iwthms |
318 else |
|
319 () |
315 |
320 |
316 val cnot = Thm.cterm_of @{theory} @{const Not} |
321 val cnot = Thm.cterm_of @{theory} @{const Not} |
317 |
322 |
318 fun mk_result outcome xrules = |
323 fun mk_result outcome xrules = { outcome = outcome, used_facts = xrules } |
319 { outcome = outcome, used_facts = xrules, run_time_in_msecs = NONE } |
324 |
320 |
325 type 'a smt_filter_head_result = 'a list * (int option * thm) list * |
321 fun smt_filter run_remote time_limit st xwrules i = |
326 (((int * thm) list * Proof.context) * (int * (int option * thm)) list) |
|
327 |
|
328 fun smt_filter_head time_limit st xwrules i = |
322 let |
329 let |
323 val ctxt = |
330 val ctxt = |
324 Proof.context_of st |
331 Proof.context_of st |
325 |> Config.put C.oracle false |
332 |> Config.put C.oracle false |
326 |> Config.put C.timeout (Time.toReal time_limit) |
333 |> Config.put C.timeout (Time.toReal time_limit) |
331 val ({context=ctxt', prems, concl, ...}, _) = Subgoal.focus ctxt i goal |
338 val ({context=ctxt', prems, concl, ...}, _) = Subgoal.focus ctxt i goal |
332 fun negate ct = Thm.dest_comb ct ||> Thm.capply cnot |-> Thm.capply |
339 fun negate ct = Thm.dest_comb ct ||> Thm.capply cnot |-> Thm.capply |
333 val cprop = negate (Thm.rhs_of (SMT_Normalize.atomize_conv ctxt' concl)) |
340 val cprop = negate (Thm.rhs_of (SMT_Normalize.atomize_conv ctxt' concl)) |
334 |
341 |
335 val (xs, wthms) = split_list xwrules |
342 val (xs, wthms) = split_list xwrules |
336 val xrules = xs ~~ map snd wthms |
343 in |
337 in |
344 (xs, wthms, |
338 wthms |
345 wthms |
339 |> map_index I |
346 |> map_index I |
340 |> append (map (pair ~1 o pair NONE) (Thm.assume cprop :: prems @ facts)) |
347 |> append (map (pair ~1 o pair NONE) (Thm.assume cprop :: prems @ facts)) |
341 |> smt_solver (SOME run_remote) ctxt' |
348 |> tap check_topsort |
|
349 |> `(gen_solver_head ctxt')) |
|
350 end |
|
351 |
|
352 fun smt_filter_tail run_remote (xs, wthms, head as ((_, ctxt), _)) = |
|
353 let val xrules = xs ~~ map snd wthms in |
|
354 head |
|
355 |-> gen_solver_tail (name_and_solver_of ctxt) (SOME run_remote) |
342 |> distinct (op =) o fst |
356 |> distinct (op =) o fst |
343 |> map_filter (try (nth xrules)) |
357 |> map_filter (try (nth xrules)) |
344 |> (if solver_name_of ctxt = "z3" (* FIXME *) then I else K xrules) |
358 |> (if solver_name_of ctxt = "z3" (* FIXME *) then I else K xrules) |
345 |> mk_result NONE |
359 |> mk_result NONE |
346 end |
360 end |
347 handle SMT_Failure.SMT fail => mk_result (SOME fail) [] |
361 handle SMT_Failure.SMT fail => mk_result (SOME fail) [] |
348 (* FIXME: measure runtime *) |
|
349 |
|
350 |
362 |
351 |
363 |
352 (* SMT tactic *) |
364 (* SMT tactic *) |
353 |
365 |
354 fun smt_tac' pass_exns ctxt rules = |
366 fun smt_tac' pass_exns ctxt rules = |
355 CONVERSION (SMT_Normalize.atomize_conv ctxt) |
367 CONVERSION (SMT_Normalize.atomize_conv ctxt) |
356 THEN' Tactic.rtac @{thm ccontr} |
368 THEN' Tactic.rtac @{thm ccontr} |
357 THEN' SUBPROOF (fn {context=ctxt', prems, ...} => |
369 THEN' SUBPROOF (fn {context=ctxt', prems, ...} => |
358 let |
370 let |
359 fun solve iwthms = snd (smt_solver NONE ctxt' iwthms) |
371 val solve = snd o solver_of ctxt' NONE ctxt' o tap check_topsort |
360 val tag = "Solver " ^ C.solver_of ctxt' ^ ": " |
372 val tag = "Solver " ^ C.solver_of ctxt' ^ ": " |
361 val str_of = prefix tag o SMT_Failure.string_of_failure ctxt' |
373 val str_of = prefix tag o SMT_Failure.string_of_failure ctxt' |
362 fun safe_solve iwthms = |
374 fun safe_solve iwthms = |
363 if pass_exns then SOME (solve iwthms) |
375 if pass_exns then SOME (solve iwthms) |
364 else (SOME (solve iwthms) |
376 else (SOME (solve iwthms) |