src/HOL/Tools/SMT/smt_solver.ML
changeset 40164 57f5db2a48a3
parent 40162 7f58a9a843c2
child 40165 b1780e551273
equal deleted inserted replaced
40163:a462d5207aa6 40164:57f5db2a48a3
    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 #>