62 case filter (fn s => String.isSubstring s proof) strs of |
63 case filter (fn s => String.isSubstring s proof) strs of |
63 [] => if is_proof_well_formed proof then NONE |
64 [] => if is_proof_well_formed proof then NONE |
64 else SOME "Ill-formed ATP output" |
65 else SOME "Ill-formed ATP output" |
65 | (failure :: _) => SOME failure |
66 | (failure :: _) => SOME failure |
66 |
67 |
67 fun external_prover relevance_filter prepare write cmd args failure_strs |
68 fun generic_prover get_facts prepare write cmd args failure_strs produce_answer |
68 produce_answer name ({with_full_types, subgoal, goal, axiom_clauses, |
69 name ({full_types, ...} : params) |
69 filtered_clauses}: problem) = |
70 ({subgoal, goal, relevance_override, axiom_clauses, filtered_clauses} |
|
71 : problem) = |
70 let |
72 let |
71 (* get clauses and prepare them for writing *) |
73 (* get clauses and prepare them for writing *) |
72 val (ctxt, (chain_ths, th)) = goal; |
74 val (ctxt, (chain_ths, th)) = goal; |
73 val thy = ProofContext.theory_of ctxt; |
75 val thy = ProofContext.theory_of ctxt; |
74 val chain_ths = map (Thm.put_name_hint chained_hint) chain_ths; |
76 val chain_ths = map (Thm.put_name_hint chained_hint) chain_ths; |
75 val goal_cls = #1 (Sledgehammer_Fact_Preprocessor.neg_conjecture_clauses ctxt th subgoal); |
77 val goal_cls = #1 (neg_conjecture_clauses ctxt th subgoal); |
76 val the_filtered_clauses = |
78 val the_filtered_clauses = |
77 (case filtered_clauses of |
79 (case filtered_clauses of |
78 NONE => relevance_filter goal goal_cls |
80 NONE => get_facts relevance_override goal goal_cls |
79 | SOME fcls => fcls); |
81 | SOME fcls => fcls); |
80 val the_axiom_clauses = |
82 val the_axiom_clauses = |
81 (case axiom_clauses of |
83 (case axiom_clauses of |
82 NONE => the_filtered_clauses |
84 NONE => the_filtered_clauses |
83 | SOME axcls => axcls); |
85 | SOME axcls => axcls); |
84 val (thm_names, clauses) = |
86 val (internal_thm_names, clauses) = |
85 prepare goal_cls chain_ths the_axiom_clauses the_filtered_clauses thy; |
87 prepare goal_cls chain_ths the_axiom_clauses the_filtered_clauses thy; |
86 |
88 |
87 (* path to unique problem file *) |
89 (* path to unique problem file *) |
88 val destdir' = Config.get ctxt destdir; |
90 val destdir' = Config.get ctxt destdir; |
89 val problem_prefix' = Config.get ctxt problem_prefix; |
91 val problem_prefix' = Config.get ctxt problem_prefix; |
119 in (proof, as_time t) end; |
121 in (proof, as_time t) end; |
120 fun split_time' s = |
122 fun split_time' s = |
121 if Config.get ctxt measure_runtime then split_time s else (s, 0) |
123 if Config.get ctxt measure_runtime then split_time s else (s, 0) |
122 fun run_on probfile = |
124 fun run_on probfile = |
123 if File.exists cmd then |
125 if File.exists cmd then |
124 write with_full_types probfile clauses |
126 write full_types probfile clauses |
125 |> pair (apfst split_time' (bash_output (cmd_line probfile))) |
127 |> pair (apfst split_time' (bash_output (cmd_line probfile))) |
126 else error ("Bad executable: " ^ Path.implode cmd); |
128 else error ("Bad executable: " ^ Path.implode cmd); |
127 |
129 |
128 (* if problemfile has not been exported, delete problemfile; otherwise export proof, too *) |
130 (* if problemfile has not been exported, delete problemfile; otherwise export proof, too *) |
129 fun cleanup probfile = if destdir' = "" then try File.rm probfile else NONE; |
131 fun cleanup probfile = if destdir' = "" then try File.rm probfile else NONE; |
130 fun export probfile (((proof, _), _), _) = |
132 fun export probfile (((proof, _), _), _) = |
131 if destdir' = "" then () |
133 if destdir' = "" then () |
132 else File.write (Path.explode (Path.implode probfile ^ "_proof")) proof; |
134 else File.write (Path.explode (Path.implode probfile ^ "_proof")) proof; |
133 |
135 |
134 val (((proof, time), rc), conj_pos) = |
136 val (((proof, atp_run_time_in_msecs), rc), conj_pos) = |
135 with_path cleanup export run_on (prob_pathname subgoal); |
137 with_path cleanup export run_on (prob_pathname subgoal); |
136 |
138 |
137 (* check for success and print out some information on failure *) |
139 (* check for success and print out some information on failure *) |
138 val failure = find_failure failure_strs proof; |
140 val failure = find_failure failure_strs proof; |
139 val success = rc = 0 andalso is_none failure; |
141 val success = rc = 0 andalso is_none failure; |
140 val (message, real_thm_names) = |
142 val (message, relevant_thm_names) = |
141 if is_some failure then ("External prover failed.", []) |
143 if is_some failure then ("External prover failed.", []) |
142 else if rc <> 0 then ("External prover failed: " ^ proof, []) |
144 else if rc <> 0 then ("External prover failed: " ^ proof, []) |
143 else apfst (fn s => "Try this command: " ^ s) |
145 else |
144 (produce_answer name (proof, thm_names, conj_pos, ctxt, th, subgoal)); |
146 (produce_answer name (proof, internal_thm_names, conj_pos, ctxt, th, |
|
147 subgoal)); |
145 in |
148 in |
146 {success = success, message = message, |
149 {success = success, message = message, |
147 theorem_names = real_thm_names, runtime = time, proof = proof, |
150 relevant_thm_names = relevant_thm_names, |
148 internal_thm_names = thm_names, filtered_clauses = the_filtered_clauses} |
151 atp_run_time_in_msecs = atp_run_time_in_msecs, proof = proof, |
|
152 internal_thm_names = internal_thm_names, |
|
153 filtered_clauses = the_filtered_clauses} |
149 end; |
154 end; |
150 |
155 |
151 |
156 |
152 (* generic TPTP-based provers *) |
157 (* generic TPTP-based provers *) |
153 |
158 |
154 fun generic_tptp_prover |
159 fun generic_tptp_prover |
155 (name, {command, arguments, failure_strs, max_new_clauses, |
160 (name, {command, arguments, failure_strs, max_new_clauses, |
156 insert_theory_const, emit_structured_proof}) timeout = |
161 add_theory_const, supports_isar_proofs}) |
157 external_prover (get_relevant_facts max_new_clauses insert_theory_const) |
162 (params as {relevance_threshold, higher_order, follow_defs, isar_proof, |
158 (prepare_clauses false) write_tptp_file command (arguments timeout) |
163 ...}) timeout = |
159 failure_strs |
164 generic_prover |
160 (if emit_structured_proof then structured_isar_proof |
165 (get_relevant_facts relevance_threshold higher_order follow_defs |
161 else metis_lemma_list false) name; |
166 max_new_clauses add_theory_const) |
162 |
167 (prepare_clauses higher_order false) write_tptp_file command |
163 fun tptp_prover (name, p) = (name, generic_tptp_prover (name, p)); |
168 (arguments timeout) failure_strs |
|
169 (if supports_isar_proofs andalso isar_proof then structured_isar_proof |
|
170 else metis_lemma_list false) name params; |
|
171 |
|
172 fun tptp_prover name p = (name, generic_tptp_prover (name, p)); |
164 |
173 |
165 |
174 |
166 (** common provers **) |
175 (** common provers **) |
167 |
176 |
168 (* Vampire *) |
177 (* Vampire *) |
169 |
178 |
170 (*NB: Vampire does not work without explicit timelimit*) |
179 (* NB: Vampire does not work without explicit time limit. *) |
171 |
180 |
172 val vampire_failure_strs = |
181 val vampire_config : prover_config = |
173 ["Satisfiability detected", "Refutation not found", "CANNOT PROVE"]; |
182 {command = Path.explode "$VAMPIRE_HOME/vampire", |
174 val vampire_max_new_clauses = 60; |
183 arguments = (fn timeout => "--output_syntax tptp --mode casc -t " ^ |
175 val vampire_insert_theory_const = false; |
184 string_of_int (Time.toSeconds timeout)), |
176 |
185 failure_strs = |
177 fun vampire_prover_config isar : prover_config = |
186 ["Satisfiability detected", "Refutation not found", "CANNOT PROVE"], |
178 {command = Path.explode "$VAMPIRE_HOME/vampire", |
187 max_new_clauses = 60, |
179 arguments = (fn timeout => "--output_syntax tptp --mode casc" ^ |
188 add_theory_const = false, |
180 " -t " ^ string_of_int timeout), |
189 supports_isar_proofs = true} |
181 failure_strs = vampire_failure_strs, |
190 val vampire = tptp_prover "vampire" vampire_config |
182 max_new_clauses = vampire_max_new_clauses, |
|
183 insert_theory_const = vampire_insert_theory_const, |
|
184 emit_structured_proof = isar}; |
|
185 |
|
186 val vampire = tptp_prover ("vampire", vampire_prover_config false); |
|
187 val vampire_isar = tptp_prover ("vampire_isar", vampire_prover_config true); |
|
188 |
191 |
189 |
192 |
190 (* E prover *) |
193 (* E prover *) |
191 |
194 |
192 val eprover_failure_strs = |
195 val e_config : prover_config = |
193 ["SZS status: Satisfiable", "SZS status Satisfiable", |
196 {command = Path.explode "$E_HOME/eproof", |
194 "SZS status: ResourceOut", "SZS status ResourceOut", |
197 arguments = (fn timeout => "--tstp-in --tstp-out -l5 -xAutoDev \ |
195 "# Cannot determine problem status"]; |
198 \-tAutoDev --silent --cpu-limit=" ^ |
196 val eprover_max_new_clauses = 100; |
199 string_of_int (Time.toSeconds timeout)), |
197 val eprover_insert_theory_const = false; |
200 failure_strs = |
198 |
201 ["SZS status: Satisfiable", "SZS status Satisfiable", |
199 fun eprover_config isar : prover_config = |
202 "SZS status: ResourceOut", "SZS status ResourceOut", |
200 {command = Path.explode "$E_HOME/eproof", |
203 "# Cannot determine problem status"], |
201 arguments = (fn timeout => "--tstp-in --tstp-out -l5 -xAutoDev -tAutoDev" ^ |
204 max_new_clauses = 100, |
202 " --silent --cpu-limit=" ^ string_of_int timeout), |
205 add_theory_const = false, |
203 failure_strs = eprover_failure_strs, |
206 supports_isar_proofs = true} |
204 max_new_clauses = eprover_max_new_clauses, |
207 val e = tptp_prover "e" e_config |
205 insert_theory_const = eprover_insert_theory_const, |
|
206 emit_structured_proof = isar}; |
|
207 |
|
208 val eprover = tptp_prover ("e", eprover_config false); |
|
209 val eprover_isar = tptp_prover ("e_isar", eprover_config true); |
|
210 |
208 |
211 |
209 |
212 (* SPASS *) |
210 (* SPASS *) |
213 |
211 |
214 val spass_failure_strs = |
212 fun generic_dfg_prover |
215 ["SPASS beiseite: Completion found.", "SPASS beiseite: Ran out of time.", |
213 (name, ({command, arguments, failure_strs, max_new_clauses, |
216 "SPASS beiseite: Maximal number of loops exceeded."]; |
214 add_theory_const, ...} : prover_config)) |
217 val spass_max_new_clauses = 40; |
215 (params as {relevance_threshold, higher_order, follow_defs, ...}) |
218 val spass_insert_theory_const = true; |
216 timeout = |
219 |
217 generic_prover |
220 fun spass_config insert_theory_const: prover_config = |
218 (get_relevant_facts relevance_threshold higher_order follow_defs |
|
219 max_new_clauses add_theory_const) |
|
220 (prepare_clauses higher_order true) write_dfg_file command |
|
221 (arguments timeout) failure_strs (metis_lemma_list true) name params; |
|
222 |
|
223 fun dfg_prover (name, p) = (name, generic_dfg_prover (name, p)); |
|
224 |
|
225 fun spass_config_for add_theory_const : prover_config = |
221 {command = Path.explode "$SPASS_HOME/SPASS", |
226 {command = Path.explode "$SPASS_HOME/SPASS", |
222 arguments = (fn timeout => "-Auto -SOS=1 -PGiven=0 -PProblem=0 -Splits=0" ^ |
227 arguments = (fn timeout => "-Auto -SOS=1 -PGiven=0 -PProblem=0 -Splits=0" ^ |
223 " -FullRed=0 -DocProof -TimeLimit=" ^ string_of_int timeout), |
228 " -FullRed=0 -DocProof -TimeLimit=" ^ |
224 failure_strs = spass_failure_strs, |
229 string_of_int (Time.toSeconds timeout)), |
225 max_new_clauses = spass_max_new_clauses, |
230 failure_strs = |
226 insert_theory_const = insert_theory_const, |
231 ["SPASS beiseite: Completion found.", "SPASS beiseite: Ran out of time.", |
227 emit_structured_proof = false}; |
232 "SPASS beiseite: Maximal number of loops exceeded."], |
228 |
233 max_new_clauses = 40, |
229 fun generic_dfg_prover |
234 add_theory_const = add_theory_const, |
230 (name, ({command, arguments, failure_strs, max_new_clauses, |
235 supports_isar_proofs = false}; |
231 insert_theory_const, ...} : prover_config)) timeout = |
236 |
232 external_prover |
237 val spass_config = spass_config_for true |
233 (get_relevant_facts max_new_clauses insert_theory_const) |
238 val spass = dfg_prover ("spass", spass_config) |
234 (prepare_clauses true) |
239 |
235 write_dfg_file |
240 val spass_no_tc_config = spass_config_for false |
236 command |
241 val spass_no_tc = dfg_prover ("spass_no_tc", spass_no_tc_config) |
237 (arguments timeout) |
|
238 failure_strs |
|
239 (metis_lemma_list true) |
|
240 name; |
|
241 |
|
242 fun dfg_prover (name, p) = (name, generic_dfg_prover (name, p)); |
|
243 |
|
244 val spass = dfg_prover ("spass", spass_config spass_insert_theory_const); |
|
245 val spass_no_tc = dfg_prover ("spass_no_tc", spass_config false); |
|
246 |
242 |
247 |
243 |
248 (* remote prover invocation via SystemOnTPTP *) |
244 (* remote prover invocation via SystemOnTPTP *) |
249 |
245 |
250 val systems = Synchronized.var "atp_wrapper_systems" ([]: string list); |
246 val systems = Synchronized.var "atp_wrapper_systems" ([]: string list); |
251 |
247 |
252 fun get_systems () = |
248 fun get_systems () = |
253 let |
249 let |
254 val (answer, rc) = bash_output ("\"$ISABELLE_ATP_MANAGER/SystemOnTPTP\" -w") |
250 val (answer, rc) = bash_output "\"$ISABELLE_ATP_MANAGER/SystemOnTPTP\" -w" |
255 in |
251 in |
256 if rc <> 0 then error ("Failed to get available systems at SystemOnTPTP:\n" ^ answer) |
252 if rc <> 0 then |
257 else split_lines answer |
253 error ("Failed to get available systems at SystemOnTPTP:\n" ^ answer) |
|
254 else |
|
255 split_lines answer |
258 end; |
256 end; |
259 |
257 |
260 fun refresh_systems_on_tptp () = |
258 fun refresh_systems_on_tptp () = |
261 Synchronized.change systems (fn _ => get_systems ()); |
259 Synchronized.change systems (fn _ => get_systems ()); |
262 |
260 |
269 NONE => error ("System " ^ quote prefix ^ " not available at SystemOnTPTP") |
267 NONE => error ("System " ^ quote prefix ^ " not available at SystemOnTPTP") |
270 | SOME sys => sys); |
268 | SOME sys => sys); |
271 |
269 |
272 val remote_failure_strs = ["Remote-script could not extract proof"]; |
270 val remote_failure_strs = ["Remote-script could not extract proof"]; |
273 |
271 |
274 fun remote_prover_config prover_prefix args max_new insert_tc: prover_config = |
272 fun remote_prover_config prover_prefix args max_new_clauses add_theory_const |
275 {command = Path.explode "$ISABELLE_ATP_MANAGER/SystemOnTPTP", |
273 : prover_config = |
276 arguments = (fn timeout => |
274 {command = Path.explode "$ISABELLE_ATP_MANAGER/SystemOnTPTP", |
277 args ^ " -t " ^ string_of_int timeout ^ " -s " ^ the_system prover_prefix), |
275 arguments = (fn timeout => |
278 failure_strs = remote_failure_strs, |
276 args ^ " -t " ^ string_of_int (Time.toSeconds timeout) ^ " -s " ^ |
279 max_new_clauses = max_new, |
277 the_system prover_prefix), |
280 insert_theory_const = insert_tc, |
278 failure_strs = remote_failure_strs, |
281 emit_structured_proof = false}; |
279 max_new_clauses = max_new_clauses, |
282 |
280 add_theory_const = add_theory_const, |
283 val remote_vampire = tptp_prover ("remote_vampire", remote_prover_config |
281 supports_isar_proofs = false} |
284 "Vampire---9" "" vampire_max_new_clauses vampire_insert_theory_const); |
282 |
285 |
283 val remote_vampire = |
286 val remote_eprover = tptp_prover ("remote_e", remote_prover_config |
284 tptp_prover "remote_vampire" |
287 "EP---" "" eprover_max_new_clauses eprover_insert_theory_const); |
285 (remote_prover_config "Vampire---9" "" |
288 |
286 (#max_new_clauses vampire_config) (#add_theory_const vampire_config)) |
289 val remote_spass = tptp_prover ("remote_spass", remote_prover_config |
287 |
290 "SPASS---" "-x" spass_max_new_clauses spass_insert_theory_const); |
288 val remote_e = |
|
289 tptp_prover "remote_e" |
|
290 (remote_prover_config "EP---" "" |
|
291 (#max_new_clauses e_config) (#add_theory_const e_config)) |
|
292 |
|
293 val remote_spass = |
|
294 tptp_prover "remote_spass" |
|
295 (remote_prover_config "SPASS---" "-x" |
|
296 (#max_new_clauses spass_config) (#add_theory_const spass_config)) |
291 |
297 |
292 val provers = |
298 val provers = |
293 [spass, vampire, eprover, vampire_isar, eprover_isar, spass_no_tc, |
299 [spass, vampire, e, spass_no_tc, remote_vampire, remote_spass, remote_e] |
294 remote_vampire, remote_spass, remote_eprover] |
|
295 val prover_setup = fold add_prover provers |
300 val prover_setup = fold add_prover provers |
296 |
301 |
297 val setup = |
302 val setup = |
298 destdir_setup |
303 destdir_setup |
299 #> problem_prefix_setup |
304 #> problem_prefix_setup |