51 message: string} |
51 message: string} |
52 |
52 |
53 type prover = params -> minimize_command -> prover_problem -> prover_result |
53 type prover = params -> minimize_command -> prover_problem -> prover_result |
54 |
54 |
55 (* for experimentation purposes -- do not use in production code *) |
55 (* for experimentation purposes -- do not use in production code *) |
|
56 val atp_first_iter_time_frac : real Unsynchronized.ref |
56 val smt_weights : bool Unsynchronized.ref |
57 val smt_weights : bool Unsynchronized.ref |
57 val smt_weight_min_facts : int Unsynchronized.ref |
58 val smt_weight_min_facts : int Unsynchronized.ref |
58 val smt_min_weight : int Unsynchronized.ref |
59 val smt_min_weight : int Unsynchronized.ref |
59 val smt_max_weight : int Unsynchronized.ref |
60 val smt_max_weight : int Unsynchronized.ref |
60 val smt_max_weight_index : int Unsynchronized.ref |
61 val smt_max_weight_index : int Unsynchronized.ref |
316 translate_atp_fact ctxt (untranslated_fact fact) |
317 translate_atp_fact ctxt (untranslated_fact fact) |
317 fun smt_weighted_fact _ _ (SMT_Weighted_Fact p, _) = p |
318 fun smt_weighted_fact _ _ (SMT_Weighted_Fact p, _) = p |
318 | smt_weighted_fact thy num_facts (fact, j) = |
319 | smt_weighted_fact thy num_facts (fact, j) = |
319 (untranslated_fact fact, j) |> weight_smt_fact thy num_facts |
320 (untranslated_fact fact, j) |> weight_smt_fact thy num_facts |
320 |
321 |
|
322 fun overlord_file_location_for_prover prover = |
|
323 (getenv "ISABELLE_HOME_USER", "prob_" ^ prover) |
|
324 |
|
325 |
321 (* generic TPTP-based ATPs *) |
326 (* generic TPTP-based ATPs *) |
322 |
327 |
323 fun int_opt_add (SOME m) (SOME n) = SOME (m + n) |
328 fun int_opt_add (SOME m) (SOME n) = SOME (m + n) |
324 | int_opt_add _ _ = NONE |
329 | int_opt_add _ _ = NONE |
325 |
330 |
326 fun overlord_file_location_for_prover prover = |
331 val atp_first_iter_time_frac = Unsynchronized.ref 0.67 |
327 (getenv "ISABELLE_HOME_USER", "prob_" ^ prover) |
|
328 |
|
329 val atp_first_iter_time_frac = 0.67 |
|
330 |
332 |
331 (* Important messages are important but not so important that users want to see |
333 (* Important messages are important but not so important that users want to see |
332 them each time. *) |
334 them each time. *) |
333 val important_message_keep_factor = 0.1 |
335 val important_message_keep_factor = 0.1 |
334 |
336 |
356 Path.append (Path.explode dest_dir) problem_file_name |
358 Path.append (Path.explode dest_dir) problem_file_name |
357 else |
359 else |
358 error ("No such directory: " ^ quote dest_dir ^ ".") |
360 error ("No such directory: " ^ quote dest_dir ^ ".") |
359 val measure_run_time = verbose orelse Config.get ctxt measure_run_time |
361 val measure_run_time = verbose orelse Config.get ctxt measure_run_time |
360 val command = Path.explode (getenv (fst exec) ^ "/" ^ snd exec) |
362 val command = Path.explode (getenv (fst exec) ^ "/" ^ snd exec) |
361 (* write out problem file and call ATP *) |
363 val command = Path.explode ("/Users/blanchet/misc/E-weights/PROVER/" ^ snd exec) (*###*) |
362 fun command_line complete timeout probfile = |
|
363 let |
|
364 val core = File.shell_path command ^ " " ^ arguments complete timeout ^ |
|
365 " " ^ File.shell_path probfile |
|
366 in |
|
367 (if measure_run_time then "TIMEFORMAT='%3R'; { time " ^ core ^ " ; }" |
|
368 else "exec " ^ core) ^ " 2>&1" |
|
369 end |
|
370 fun split_time s = |
364 fun split_time s = |
371 let |
365 let |
372 val split = String.tokens (fn c => str c = "\n"); |
366 val split = String.tokens (fn c => str c = "\n"); |
373 val (output, t) = s |> split |> split_last |> apfst cat_lines; |
367 val (output, t) = s |> split |> split_last |> apfst cat_lines; |
374 fun as_num f = f >> (fst o read_int); |
368 fun as_num f = f >> (fst o read_int); |
376 val digit = Scan.one Symbol.is_ascii_digit; |
370 val digit = Scan.one Symbol.is_ascii_digit; |
377 val num3 = as_num (digit ::: digit ::: (digit >> single)); |
371 val num3 = as_num (digit ::: digit ::: (digit >> single)); |
378 val time = num --| Scan.$$ "." -- num3 >> (fn (a, b) => a * 1000 + b); |
372 val time = num --| Scan.$$ "." -- num3 >> (fn (a, b) => a * 1000 + b); |
379 val as_time = Scan.read Symbol.stopper time o raw_explode |
373 val as_time = Scan.read Symbol.stopper time o raw_explode |
380 in (output, as_time t) end; |
374 in (output, as_time t) end; |
381 fun run_on probfile = |
375 fun run_on prob_file = |
382 case filter (curry (op =) "" o getenv o fst) (exec :: required_execs) of |
376 case filter (curry (op =) "" o getenv o fst) (exec :: required_execs) of |
383 (home_var, _) :: _ => |
377 (home_var, _) :: _ => |
384 error ("The environment variable " ^ quote home_var ^ " is not set.") |
378 error ("The environment variable " ^ quote home_var ^ " is not set.") |
385 | [] => |
379 | [] => |
386 if File.exists command then |
380 if File.exists command then |
387 let |
381 let |
|
382 val readable_names = debug andalso overlord |
|
383 val (atp_problem, pool, conjecture_offset, fact_names) = |
|
384 prepare_atp_problem ctxt readable_names explicit_forall type_sys |
|
385 explicit_apply hyp_ts concl_t facts |
|
386 val ss = tptp_strings_for_atp_problem use_conjecture_for_hypotheses |
|
387 atp_problem |
|
388 val _ = File.write_list prob_file ss |
|
389 val conjecture_shape = |
|
390 conjecture_offset + 1 upto conjecture_offset + length hyp_ts + 1 |
|
391 |> map single |
388 fun run complete timeout = |
392 fun run complete timeout = |
389 let |
393 let |
390 val command = command_line complete timeout probfile |
394 fun weights () = atp_problem_weights atp_problem |
|
395 val core = |
|
396 File.shell_path command ^ " " ^ |
|
397 arguments complete timeout weights ^ " " ^ |
|
398 File.shell_path prob_file |
|
399 val command = |
|
400 (if measure_run_time then |
|
401 "TIMEFORMAT='%3R'; { time " ^ core ^ " ; }" |
|
402 else |
|
403 "exec " ^ core) ^ " 2>&1" |
391 val ((output, msecs), res_code) = |
404 val ((output, msecs), res_code) = |
392 bash_output command |
405 bash_output command |
393 |>> (if overlord then |
406 |>> (if overlord then |
394 prefix ("% " ^ command ^ "\n% " ^ timestamp () ^ "\n") |
407 prefix ("% " ^ command ^ "\n% " ^ timestamp () ^ "\n") |
395 else |
408 else |
397 |>> (if measure_run_time then split_time else rpair NONE) |
410 |>> (if measure_run_time then split_time else rpair NONE) |
398 val (tstplike_proof, outcome) = |
411 val (tstplike_proof, outcome) = |
399 extract_tstplike_proof_and_outcome verbose complete res_code |
412 extract_tstplike_proof_and_outcome verbose complete res_code |
400 proof_delims known_failures output |
413 proof_delims known_failures output |
401 in (output, msecs, tstplike_proof, outcome) end |
414 in (output, msecs, tstplike_proof, outcome) end |
402 val readable_names = debug andalso overlord |
|
403 val (atp_problem, pool, conjecture_offset, fact_names) = |
|
404 prepare_atp_problem ctxt readable_names explicit_forall type_sys |
|
405 explicit_apply hyp_ts concl_t facts |
|
406 val ss = tptp_strings_for_atp_problem use_conjecture_for_hypotheses |
|
407 atp_problem |
|
408 val _ = File.write_list probfile ss |
|
409 val conjecture_shape = |
|
410 conjecture_offset + 1 upto conjecture_offset + length hyp_ts + 1 |
|
411 |> map single |
|
412 val run_twice = has_incomplete_mode andalso not auto |
415 val run_twice = has_incomplete_mode andalso not auto |
413 val timer = Timer.startRealTimer () |
416 val timer = Timer.startRealTimer () |
414 val result = |
417 val result = |
415 run false |
418 run false |
416 (if run_twice then |
419 (if run_twice then |
417 seconds (0.001 * atp_first_iter_time_frac |
420 seconds (0.001 * !atp_first_iter_time_frac |
418 * Real.fromInt (Time.toMilliseconds timeout)) |
421 * Real.fromInt (Time.toMilliseconds timeout)) |
419 else |
422 else |
420 timeout) |
423 timeout) |
421 |> run_twice |
424 |> run_twice |
422 ? (fn (_, msecs0, _, SOME _) => |
425 ? (fn (_, msecs0, _, SOME _) => |
429 else |
432 else |
430 error ("Bad executable: " ^ Path.implode command ^ ".") |
433 error ("Bad executable: " ^ Path.implode command ^ ".") |
431 |
434 |
432 (* If the problem file has not been exported, remove it; otherwise, export |
435 (* If the problem file has not been exported, remove it; otherwise, export |
433 the proof file too. *) |
436 the proof file too. *) |
434 fun cleanup probfile = |
437 fun cleanup prob_file = |
435 if dest_dir = "" then try File.rm probfile else NONE |
438 if dest_dir = "" then try File.rm prob_file else NONE |
436 fun export probfile (_, (output, _, _, _)) = |
439 fun export prob_file (_, (output, _, _, _)) = |
437 if dest_dir = "" then |
440 if dest_dir = "" then |
438 () |
441 () |
439 else |
442 else |
440 File.write (Path.explode (Path.implode probfile ^ "_proof")) output |
443 File.write (Path.explode (Path.implode prob_file ^ "_proof")) output |
441 val ((pool, conjecture_shape, fact_names), |
444 val ((pool, conjecture_shape, fact_names), |
442 (output, msecs, tstplike_proof, outcome)) = |
445 (output, msecs, tstplike_proof, outcome)) = |
443 with_path cleanup export run_on problem_path_name |
446 with_path cleanup export run_on problem_path_name |
444 val (conjecture_shape, fact_names) = |
447 val (conjecture_shape, fact_names) = |
445 repair_conjecture_shape_and_fact_names output conjecture_shape fact_names |
448 repair_conjecture_shape_and_fact_names output conjecture_shape fact_names |