29 reconstruct: (Proof.context -> SMT_Translate.recon -> string list -> |
29 reconstruct: (Proof.context -> SMT_Translate.recon -> string list -> |
30 (int list * thm) * Proof.context) option } |
30 (int list * thm) * Proof.context) option } |
31 |
31 |
32 (*options*) |
32 (*options*) |
33 val oracle: bool Config.T |
33 val oracle: bool Config.T |
|
34 val filter_only: bool Config.T |
34 val datatypes: bool Config.T |
35 val datatypes: bool Config.T |
35 val timeout: int Config.T |
36 val timeout: int Config.T |
36 val with_timeout: Proof.context -> ('a -> 'b) -> 'a -> 'b |
37 val with_timeout: Proof.context -> ('a -> 'b) -> 'a -> 'b |
37 val trace: bool Config.T |
38 val trace: bool Config.T |
38 val trace_msg: Proof.context -> ('a -> string) -> 'a -> unit |
39 val trace_msg: Proof.context -> ('a -> string) -> 'a -> unit |
51 val solver_name_of: Context.generic -> string |
52 val solver_name_of: Context.generic -> string |
52 val select_solver: string -> Context.generic -> Context.generic |
53 val select_solver: string -> Context.generic -> Context.generic |
53 val solver_of: Context.generic -> solver |
54 val solver_of: Context.generic -> solver |
54 |
55 |
55 (*filter*) |
56 (*filter*) |
56 val smt_filter: Proof.state -> int -> ('a * thm) list -> |
57 val smt_filter: bool -> Time.time -> Proof.state -> ('a * thm) list -> int -> |
57 'a list * failure option |
58 {outcome: failure option, used_facts: 'a list, run_time_in_msecs: int} |
58 |
59 |
59 (*tactic*) |
60 (*tactic*) |
60 val smt_tac': bool -> Proof.context -> thm list -> int -> Tactical.tactic |
61 val smt_tac': bool -> Proof.context -> thm list -> int -> Tactical.tactic |
61 val smt_tac: Proof.context -> thm list -> int -> Tactical.tactic |
62 val smt_tac: Proof.context -> thm list -> int -> Tactical.tactic |
62 |
63 |
108 |
109 |
109 |
110 |
110 (* SMT options *) |
111 (* SMT options *) |
111 |
112 |
112 val (oracle, setup_oracle) = Attrib.config_bool "smt_oracle" (K true) |
113 val (oracle, setup_oracle) = Attrib.config_bool "smt_oracle" (K true) |
|
114 |
|
115 val (filter_only, setup_filter_only) = |
|
116 Attrib.config_bool "smt_filter_only" (K false) |
113 |
117 |
114 val (datatypes, setup_datatypes) = Attrib.config_bool "smt_datatypes" (K false) |
118 val (datatypes, setup_datatypes) = Attrib.config_bool "smt_datatypes" (K false) |
115 |
119 |
116 val (timeout, setup_timeout) = Attrib.config_int "smt_timeout" (K 30) |
120 val (timeout, setup_timeout) = Attrib.config_int "smt_timeout" (K 30) |
117 |
121 |
246 builtin_fun=builtin_fun, has_datatypes=with_datatypes} |
250 builtin_fun=builtin_fun, has_datatypes=with_datatypes} |
247 val translate' = {prefixes=prefixes, header=header, strict=strict, |
251 val translate' = {prefixes=prefixes, header=header, strict=strict, |
248 builtins=builtins', serialize=serialize} |
252 builtins=builtins', serialize=serialize} |
249 in (with_datatypes', translate') end |
253 in (with_datatypes', translate') end |
250 |
254 |
|
255 fun trace_assumptions ctxt irules idxs = |
|
256 let |
|
257 val thms = filter (fn i => i >= 0) idxs |
|
258 |> map_filter (AList.lookup (op =) irules) |
|
259 in |
|
260 if Config.get ctxt trace_used_facts andalso length thms > 0 |
|
261 then |
|
262 tracing (Pretty.string_of (Pretty.big_list "SMT used facts:" |
|
263 (map (Display.pretty_thm ctxt) thms))) |
|
264 else () |
|
265 end |
|
266 |
251 fun gen_solver name info ctxt irules = |
267 fun gen_solver name info ctxt irules = |
252 let |
268 let |
253 val {env_var, is_remote, options, more_options, interface, reconstruct} = |
269 val {env_var, is_remote, options, more_options, interface, reconstruct} = |
254 info |
270 info |
255 val {extra_norm, translate} = interface |
271 val {extra_norm, translate} = interface |
261 |-> invoke translate' name (env_var, is_remote, name) more_options options |
277 |-> invoke translate' name (env_var, is_remote, name) more_options options |
262 |-> reconstruct |
278 |-> reconstruct |
263 |-> (fn (idxs, thm) => fn ctxt' => thm |
279 |-> (fn (idxs, thm) => fn ctxt' => thm |
264 |> singleton (ProofContext.export ctxt' ctxt) |
280 |> singleton (ProofContext.export ctxt' ctxt) |
265 |> discharge_definitions |
281 |> discharge_definitions |
|
282 |> tap (fn _ => trace_assumptions ctxt irules idxs) |
266 |> pair idxs) |
283 |> pair idxs) |
267 end |
284 end |
268 |
285 |
269 |
286 |
270 |
287 |
375 (* without this test, we would run into problems when atomizing the rules: *) |
392 (* without this test, we would run into problems when atomizing the rules: *) |
376 if exists (has_topsort o Thm.prop_of o snd) irules |
393 if exists (has_topsort o Thm.prop_of o snd) irules |
377 then raise SMT (Other_Failure "proof state contains the universal sort {}") |
394 then raise SMT (Other_Failure "proof state contains the universal sort {}") |
378 else solver_of (Context.Proof ctxt) ctxt irules |
395 else solver_of (Context.Proof ctxt) ctxt irules |
379 |
396 |
380 fun smt_filter st i xrules = |
397 fun smt_filter remote time_limit st xrules i = |
381 let |
398 let |
382 val {context, facts, goal} = Proof.goal st |
399 val {context, facts, goal} = Proof.goal st |
|
400 val ctxt = |
|
401 context |
|
402 |> Config.put timeout (Time.toSeconds time_limit) |
|
403 |> Config.put oracle false |
|
404 |> Config.put filter_only true |
383 val cprop = |
405 val cprop = |
384 Thm.cprem_of goal i |
406 Thm.cprem_of goal i |
385 |> Thm.rhs_of o SMT_Normalize.atomize_conv context |
407 |> Thm.rhs_of o SMT_Normalize.atomize_conv ctxt |
386 |> Thm.capply @{cterm Trueprop} o Thm.capply @{cterm Not} o Thm.dest_arg |
408 |> Thm.capply @{cterm Trueprop} o Thm.capply @{cterm Not} o Thm.dest_arg |
387 val irs = map (pair ~1) (Thm.assume cprop :: facts) |
409 val irs = map (pair ~1) (Thm.assume cprop :: facts) |
388 in |
410 in |
389 split_list xrules |
411 split_list xrules |
390 ||>> solver_of (Context.Proof context) context o append irs o map_index I |
412 ||> distinct (op =) o fst o smt_solver ctxt o append irs o map_index I |
391 |>> uncurry (map_filter o try o nth) o apsnd (distinct (op =)) |
413 |-> map_filter o try o nth |
392 |> rpair NONE o fst |
414 |> (fn xs => {outcome=NONE, used_facts=xs, run_time_in_msecs= ~1}) |
393 end |
415 end |
394 handle SMT fail => ([], SOME fail) |
416 handle SMT fail => {outcome=SOME fail, used_facts=[], run_time_in_msecs= ~1} |
395 |
417 |
396 |
418 |
397 |
419 |
398 (* SMT tactic *) |
420 (* SMT tactic *) |
399 |
421 |
430 Attrib.setup @{binding smt_solver} |
452 Attrib.setup @{binding smt_solver} |
431 (Scan.lift (Parse.$$$ "=" |-- Args.name) >> |
453 (Scan.lift (Parse.$$$ "=" |-- Args.name) >> |
432 (Thm.declaration_attribute o K o select_solver)) |
454 (Thm.declaration_attribute o K o select_solver)) |
433 "SMT solver configuration" #> |
455 "SMT solver configuration" #> |
434 setup_oracle #> |
456 setup_oracle #> |
|
457 setup_filter_only #> |
435 setup_datatypes #> |
458 setup_datatypes #> |
436 setup_timeout #> |
459 setup_timeout #> |
437 setup_trace #> |
460 setup_trace #> |
438 setup_trace_used_facts #> |
461 setup_trace_used_facts #> |
439 setup_fixed_certificates #> |
462 setup_fixed_certificates #> |