1 (* Title: HOL/Tools/Sledgehammer/sledgehammer_proof_methods.ML
2 Author: Jasmin Blanchette, TU Muenchen
3 Author: Steffen Juilf Smolka, TU Muenchen
8 signature SLEDGEHAMMER_PROOF_METHODS =
10 type stature = ATP_Problem_Generate.stature
12 datatype proof_method =
13 Metis_Method of string option * string option |
27 datatype play_outcome =
29 Play_Timed_Out of Time.time |
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
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
44 structure Sledgehammer_Proof_Methods : SLEDGEHAMMER_PROOF_METHODS =
48 open ATP_Problem_Generate
49 open ATP_Proof_Reconstruct
51 datatype proof_method =
52 Metis_Method of string option * string option |
66 datatype play_outcome =
68 Play_Timed_Out of Time.time |
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
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
82 fun maybe_paren s = s |> not (Symbol_Pos.is_identifier s) ? enclose "(" ")"
84 fun string_of_proof_method ctxt ss meth =
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")
104 maybe_paren (space_implode " " (meth_s :: ss))
107 val silence_methods = Try0.silence_methods false
109 fun tac_of_proof_method ctxt (local_facts, global_facts) meth =
110 Method.insert_tac local_facts THEN'
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
117 | Meson_Method => Meson_Tactic.meson_general_tac (silence_methods ctxt) global_facts
119 let val ctxt = Config.put SMT2_Config.verbose false ctxt in
120 SMT2_Solver.smt2_tac ctxt global_facts
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))
127 Method.insert_tac global_facts THEN'
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)
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))
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"
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
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
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
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 " (" ")") ^ "."
171 fun minimize_line _ [] = ""
172 | minimize_line minimize_command ss =
173 (case minimize_command ss of
175 | command => "\nTo minimize: " ^ Active.sendback_markup [Markup.padding_command] command ^ ".")
177 fun split_used_facts facts =
179 |> List.partition (fn (_, (sc, _)) => sc = Chained)
180 |> pairself (sort_distinct (string_ord o pairself fst))
182 fun one_line_proof_text ctxt num_chained
183 ((meth, play), banner, used_facts, minimize_command, subgoal, subgoal_count) =
185 val (chained, extra) = split_used_facts used_facts
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)
193 try_line ^ minimize_line minimize_command (map fst (extra @ chained))