src/HOL/Tools/Sledgehammer/sledgehammer_proof_methods.ML
author blanchet
Fri, 25 Jul 2014 11:31:20 +0200
changeset 59016 3bad83e01ec2
parent 58807 ed826e2053c9
child 59017 47336af5d2b2
permissions -rw-r--r--
added missing facts to proof method
     1 (*  Title:      HOL/Tools/Sledgehammer/sledgehammer_proof_methods.ML
     2     Author:     Jasmin Blanchette, TU Muenchen
     3     Author:     Steffen Juilf Smolka, TU Muenchen
     4 
     5 Reconstructors.
     6 *)
     7 
     8 signature SLEDGEHAMMER_PROOF_METHODS =
     9 sig
    10   type stature = ATP_Problem_Generate.stature
    11 
    12   datatype proof_method =
    13     Metis_Method of string option * string option |
    14     Meson_Method |
    15     SMT2_Method |
    16     SATx_Method |
    17     Blast_Method |
    18     Simp_Method |
    19     Simp_Size_Method |
    20     Auto_Method |
    21     Fastforce_Method |
    22     Force_Method |
    23     Linarith_Method |
    24     Presburger_Method |
    25     Algebra_Method
    26 
    27   datatype play_outcome =
    28     Played of Time.time |
    29     Play_Timed_Out of Time.time |
    30     Play_Failed
    31 
    32   type minimize_command = string list -> string
    33   type one_line_params =
    34     (proof_method * play_outcome) * string * (string * stature) list * minimize_command * int * int
    35 
    36   val is_proof_method_direct : proof_method -> bool
    37   val string_of_proof_method : Proof.context -> string list -> proof_method -> string
    38   val tac_of_proof_method : Proof.context -> thm list * thm list -> proof_method -> int -> tactic
    39   val string_of_play_outcome : play_outcome -> string
    40   val play_outcome_ord : play_outcome * play_outcome -> order
    41   val one_line_proof_text : Proof.context -> int -> one_line_params -> string
    42 end;
    43 
    44 structure Sledgehammer_Proof_Methods : SLEDGEHAMMER_PROOF_METHODS =
    45 struct
    46 
    47 open ATP_Util
    48 open ATP_Problem_Generate
    49 open ATP_Proof_Reconstruct
    50 
    51 datatype proof_method =
    52   Metis_Method of string option * string option |
    53   Meson_Method |
    54   SMT2_Method |
    55   SATx_Method |
    56   Blast_Method |
    57   Simp_Method |
    58   Simp_Size_Method |
    59   Auto_Method |
    60   Fastforce_Method |
    61   Force_Method |
    62   Linarith_Method |
    63   Presburger_Method |
    64   Algebra_Method
    65 
    66 datatype play_outcome =
    67   Played of Time.time |
    68   Play_Timed_Out of Time.time |
    69   Play_Failed
    70 
    71 type minimize_command = string list -> string
    72 type one_line_params =
    73   (proof_method * play_outcome) * string * (string * stature) list * minimize_command * int * int
    74 
    75 fun is_proof_method_direct (Metis_Method _) = true
    76   | is_proof_method_direct Meson_Method = true
    77   | is_proof_method_direct SMT2_Method = true
    78   | is_proof_method_direct Simp_Method = true
    79   | is_proof_method_direct Simp_Size_Method = true
    80   | is_proof_method_direct _ = false
    81 
    82 fun maybe_paren s = s |> not (Symbol_Pos.is_identifier s) ? enclose "(" ")"
    83 
    84 fun string_of_proof_method ctxt ss meth =
    85   let
    86     val meth_s =
    87       (case meth of
    88         Metis_Method (NONE, NONE) => "metis"
    89       | Metis_Method (type_enc_opt, lam_trans_opt) =>
    90         "metis (" ^ commas (map_filter I [type_enc_opt, lam_trans_opt]) ^ ")"
    91       | Meson_Method => "meson"
    92       | SMT2_Method => "smt2"
    93       | SATx_Method => "satx"
    94       | Blast_Method => "blast"
    95       | Simp_Method => if null ss then "simp" else "simp add:"
    96       | Simp_Size_Method => "simp add: " ^ short_thm_name ctxt @{thm size_ne_size_imp_ne}
    97       | Auto_Method => "auto"
    98       | Fastforce_Method => "fastforce"
    99       | Force_Method => "force"
   100       | Linarith_Method => "linarith"
   101       | Presburger_Method => "presburger"
   102       | Algebra_Method => "algebra")
   103   in
   104     maybe_paren (space_implode " " (meth_s :: ss))
   105   end
   106 
   107 val silence_methods = Try0.silence_methods false
   108 
   109 fun tac_of_proof_method ctxt (local_facts, global_facts) meth =
   110   Method.insert_tac local_facts THEN'
   111   (case meth of
   112     Metis_Method (type_enc_opt, lam_trans_opt) =>
   113     let val ctxt = Config.put Metis_Tactic.verbose false ctxt in
   114       Metis_Tactic.metis_tac [type_enc_opt |> the_default (hd partial_type_encs)]
   115         (lam_trans_opt |> the_default default_metis_lam_trans) ctxt global_facts
   116     end
   117   | Meson_Method => Meson_Tactic.meson_general_tac (silence_methods ctxt) global_facts
   118   | SMT2_Method =>
   119     let val ctxt = Config.put SMT2_Config.verbose false ctxt in
   120       SMT2_Solver.smt2_tac ctxt global_facts
   121     end
   122   | Simp_Method => Simplifier.asm_full_simp_tac (silence_methods ctxt addsimps global_facts)
   123   | Simp_Size_Method =>
   124     Simplifier.asm_full_simp_tac
   125       (silence_methods ctxt addsimps (@{thm size_ne_size_imp_ne} :: global_facts))
   126   | _ =>
   127     Method.insert_tac global_facts THEN'
   128     (case meth of
   129       SATx_Method => SAT.satx_tac ctxt
   130     | Blast_Method => blast_tac ctxt
   131     | Auto_Method => K (Clasimp.auto_tac (silence_methods ctxt))
   132     | Fastforce_Method => Clasimp.fast_force_tac (silence_methods ctxt)
   133     | Force_Method => Clasimp.force_tac (silence_methods ctxt)
   134     | Linarith_Method =>
   135       let val ctxt = Config.put Lin_Arith.verbose false ctxt in Lin_Arith.tac ctxt end
   136     | Presburger_Method => Cooper.tac true [] [] ctxt
   137     | Algebra_Method => Groebner.algebra_tac [] [] ctxt))
   138 
   139 fun string_of_play_outcome (Played time) = string_of_ext_time (false, time)
   140   | string_of_play_outcome (Play_Timed_Out time) =
   141     if time = Time.zeroTime then "" else string_of_ext_time (true, time) ^ ", timed out"
   142   | string_of_play_outcome Play_Failed = "failed"
   143 
   144 fun play_outcome_ord (Played time1, Played time2) =
   145     int_ord (pairself Time.toMilliseconds (time1, time2))
   146   | play_outcome_ord (Played _, _) = LESS
   147   | play_outcome_ord (_, Played _) = GREATER
   148   | play_outcome_ord (Play_Timed_Out time1, Play_Timed_Out time2) =
   149     int_ord (pairself Time.toMilliseconds (time1, time2))
   150   | play_outcome_ord (Play_Timed_Out _, _) = LESS
   151   | play_outcome_ord (_, Play_Timed_Out _) = GREATER
   152   | play_outcome_ord (Play_Failed, Play_Failed) = EQUAL
   153 
   154 fun apply_on_subgoal _ 1 = "by "
   155   | apply_on_subgoal 1 _ = "apply "
   156   | apply_on_subgoal i n = "prefer " ^ string_of_int i ^ " " ^ apply_on_subgoal 1 n
   157 
   158 (* FIXME *)
   159 fun proof_method_command ctxt meth i n _(*used_chaineds*) _(*num_chained*) ss =
   160   let val (indirect_ss, direct_ss) = if is_proof_method_direct meth then ([], ss) else (ss, []) in
   161     (if null indirect_ss then "" else "using " ^ space_implode " " indirect_ss ^ " ") ^
   162     apply_on_subgoal i n ^ string_of_proof_method ctxt direct_ss meth
   163   end
   164 
   165 fun try_command_line banner play command =
   166   let val s = string_of_play_outcome play in
   167     banner ^ ": " ^ Active.sendback_markup [Markup.padding_command] command ^
   168     (s |> s <> "" ? enclose " (" ")") ^ "."
   169   end
   170 
   171 fun minimize_line _ [] = ""
   172   | minimize_line minimize_command ss =
   173     (case minimize_command ss of
   174       "" => ""
   175     | command => "\nTo minimize: " ^ Active.sendback_markup [Markup.padding_command] command ^ ".")
   176 
   177 fun split_used_facts facts =
   178   facts
   179   |> List.partition (fn (_, (sc, _)) => sc = Chained)
   180   |> pairself (sort_distinct (string_ord o pairself fst))
   181 
   182 fun one_line_proof_text ctxt num_chained
   183     ((meth, play), banner, used_facts, minimize_command, subgoal, subgoal_count) =
   184   let
   185     val (chained, extra) = split_used_facts used_facts
   186 
   187     val try_line =
   188       map fst extra
   189       |> proof_method_command ctxt meth subgoal subgoal_count (map fst chained) num_chained
   190       |> (if play = Play_Failed then enclose "One-line proof reconstruction failed: " "."
   191           else try_command_line banner play)
   192   in
   193     try_line ^ minimize_line minimize_command (map fst (extra @ chained))
   194   end
   195 
   196 end;