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