279 isar_proofs : bool option, |
279 isar_proofs : bool option, |
280 isar_compress : real, |
280 isar_compress : real, |
281 isar_try0 : bool, |
281 isar_try0 : bool, |
282 slice : bool, |
282 slice : bool, |
283 minimize : bool option, |
283 minimize : bool option, |
284 timeout : Time.time option, |
284 timeout : Time.time, |
285 preplay_timeout : Time.time option, |
285 preplay_timeout : Time.time, |
286 expect : string} |
286 expect : string} |
287 |
287 |
288 type prover_problem = |
288 type prover_problem = |
289 {comment : string, |
289 {comment : string, |
290 state : Proof.state, |
290 state : Proof.state, |
376 (* based on "Mirabelle.can_apply" and generalized *) |
376 (* based on "Mirabelle.can_apply" and generalized *) |
377 fun timed_apply timeout tac state i = |
377 fun timed_apply timeout tac state i = |
378 let |
378 let |
379 val {context = ctxt, facts, goal} = Proof.goal state |
379 val {context = ctxt, facts, goal} = Proof.goal state |
380 val full_tac = Method.insert_tac facts i THEN tac ctxt i |
380 val full_tac = Method.insert_tac facts i THEN tac ctxt i |
381 in time_limit timeout (try (Seq.pull o full_tac)) goal end |
381 in |
|
382 TimeLimit.timeLimit timeout (try (Seq.pull o full_tac)) goal |
|
383 end |
382 |
384 |
383 fun tac_of_reconstructor (Metis (type_enc, lam_trans)) = |
385 fun tac_of_reconstructor (Metis (type_enc, lam_trans)) = |
384 metis_tac [type_enc] lam_trans |
386 metis_tac [type_enc] lam_trans |
385 | tac_of_reconstructor SMT = SMT_Solver.smt_tac |
387 | tac_of_reconstructor SMT = SMT_Solver.smt_tac |
386 |
388 |
399 let |
401 let |
400 fun get_preferred reconstrs = |
402 fun get_preferred reconstrs = |
401 if member (op =) reconstrs preferred then preferred |
403 if member (op =) reconstrs preferred then preferred |
402 else List.last reconstrs |
404 else List.last reconstrs |
403 in |
405 in |
404 if timeout = SOME Time.zeroTime then |
406 if timeout = Time.zeroTime then |
405 Play_Timed_Out (get_preferred reconstrs, Time.zeroTime) |
407 Play_Timed_Out (get_preferred reconstrs, Time.zeroTime) |
406 else |
408 else |
407 let |
409 let |
408 val _ = if mode = Minimize then Output.urgent_message "Preplaying proof..." else () |
410 val _ = if mode = Minimize then Output.urgent_message "Preplaying proof..." else () |
409 val ths = pairs |> sort_wrt (fst o fst) |> map snd |
411 val ths = pairs |> sort_wrt (fst o fst) |> map snd |
410 fun play [] [] = Play_Failed (get_preferred reconstrs) |
412 fun play [] [] = Play_Failed (get_preferred reconstrs) |
411 | play timed_outs [] = |
413 | play timed_outs [] = Play_Timed_Out (get_preferred timed_outs, timeout) |
412 Play_Timed_Out (get_preferred timed_outs, timeout |> the_default Time.zeroTime (* wrong *)) |
|
413 | play timed_out (reconstr :: reconstrs) = |
414 | play timed_out (reconstr :: reconstrs) = |
414 let |
415 let |
415 val _ = |
416 val _ = |
416 if verbose then |
417 if verbose then |
417 "Trying \"" ^ string_of_reconstructor reconstr ^ "\"" ^ |
418 Output.urgent_message ("Trying \"" ^ string_of_reconstructor reconstr ^ |
418 (case timeout of |
419 "\" for " ^ string_of_time timeout ^ "...") |
419 SOME timeout => " for " ^ string_of_time timeout |
|
420 | NONE => "") ^ "..." |
|
421 |> Output.urgent_message |
|
422 else |
420 else |
423 () |
421 () |
424 val timer = Timer.startRealTimer () |
422 val timer = Timer.startRealTimer () |
425 in |
423 in |
426 case timed_reconstructor reconstr debug timeout ths state i of |
424 case timed_reconstructor reconstr debug timeout ths state i of |
662 val type_enc = |
660 val type_enc = |
663 type_enc |> choose_type_enc strictness best_type_enc format |
661 type_enc |> choose_type_enc strictness best_type_enc format |
664 val sound = is_type_enc_sound type_enc |
662 val sound = is_type_enc_sound type_enc |
665 val real_ms = Real.fromInt o Time.toMilliseconds |
663 val real_ms = Real.fromInt o Time.toMilliseconds |
666 val slice_timeout = |
664 val slice_timeout = |
667 case time_left of |
665 (real_ms time_left |
668 SOME time_left => |
666 |> (if slice < num_actual_slices - 1 then |
669 ((real_ms time_left |
667 curry Real.min (time_frac * real_ms timeout) |
670 |> (if slice < num_actual_slices - 1 then |
668 else |
671 curry Real.min (time_frac * real_ms (the timeout)) |
669 I)) |
672 else |
670 * 0.001 |
673 I)) |
671 |> seconds |
674 * 0.001) |
|
675 |> seconds |> SOME |
|
676 | NONE => NONE |
|
677 val generous_slice_timeout = |
672 val generous_slice_timeout = |
678 if mode = MaSh then NONE |
673 if mode = MaSh then one_day else Time.+ (slice_timeout, atp_timeout_slack) |
679 else Option.map (curry Time.+ atp_timeout_slack) slice_timeout |
|
680 val _ = |
674 val _ = |
681 if debug then |
675 if debug then |
682 quote name ^ " slice #" ^ string_of_int (slice + 1) ^ |
676 quote name ^ " slice #" ^ string_of_int (slice + 1) ^ |
683 " with " ^ string_of_int num_facts ^ " fact" ^ |
677 " with " ^ string_of_int num_facts ^ " fact" ^ |
684 plural_s num_facts ^ |
678 plural_s num_facts ^ " for " ^ string_of_time slice_timeout ^ "..." |
685 (case slice_timeout of |
|
686 SOME timeout => " for " ^ string_of_time timeout |
|
687 | NONE => "") ^ "..." |
|
688 |> Output.urgent_message |
679 |> Output.urgent_message |
689 else |
680 else |
690 () |
681 () |
691 val readable_names = not (Config.get ctxt atp_full_names) |
682 val readable_names = not (Config.get ctxt atp_full_names) |
692 val lam_trans = |
683 val lam_trans = |
713 fun sel_weights () = atp_problem_selection_weights atp_problem |
704 fun sel_weights () = atp_problem_selection_weights atp_problem |
714 fun ord_info () = atp_problem_term_order_info atp_problem |
705 fun ord_info () = atp_problem_term_order_info atp_problem |
715 val ord = effective_term_order ctxt name |
706 val ord = effective_term_order ctxt name |
716 val full_proof = isar_proofs |> the_default (mode = Minimize) |
707 val full_proof = isar_proofs |> the_default (mode = Minimize) |
717 val args = |
708 val args = |
718 arguments ctxt full_proof extra (slice_timeout |> the_default one_day) |
709 arguments ctxt full_proof extra slice_timeout (File.shell_path prob_path) |
719 (File.shell_path prob_path) (ord, ord_info, sel_weights) |
710 (ord, ord_info, sel_weights) |
720 val command = |
711 val command = |
721 "(exec 2>&1; " ^ File.shell_path command0 ^ " " ^ args ^ " " ^ ")" |
712 "(exec 2>&1; " ^ File.shell_path command0 ^ " " ^ args ^ " " ^ ")" |
722 |> enclose "TIMEFORMAT='%3R'; { time " " ; }" |
713 |> enclose "TIMEFORMAT='%3R'; { time " " ; }" |
723 val _ = |
714 val _ = |
724 atp_problem |
715 atp_problem |
725 |> lines_of_atp_problem format ord ord_info |
716 |> lines_of_atp_problem format ord ord_info |
726 |> cons ("% " ^ command ^ "\n" ^ (if comment = "" then "" else "% " ^ comment ^ "\n")) |
717 |> cons ("% " ^ command ^ "\n" ^ (if comment = "" then "" else "% " ^ comment ^ "\n")) |
727 |> File.write_list prob_path |
718 |> File.write_list prob_path |
728 val ((output, run_time), (atp_proof, outcome)) = |
719 val ((output, run_time), (atp_proof, outcome)) = |
729 time_limit generous_slice_timeout Isabelle_System.bash_output command |
720 TimeLimit.timeLimit generous_slice_timeout Isabelle_System.bash_output command |
730 |>> (if overlord then prefix ("% " ^ command ^ "\n% " ^ timestamp () ^ "\n") else I) |
721 |>> (if overlord then prefix ("% " ^ command ^ "\n% " ^ timestamp () ^ "\n") else I) |
731 |> fst |> split_time |
722 |> fst |> split_time |
732 |> (fn accum as (output, _) => |
723 |> (fn accum as (output, _) => |
733 (accum, |
724 (accum, |
734 extract_tstplike_proof_and_outcome verbose proof_delims known_failures output |
725 extract_tstplike_proof_and_outcome verbose proof_delims known_failures output |
735 |>> atp_proof_of_tstplike_proof atp_problem |
726 |>> atp_proof_of_tstplike_proof atp_problem |
736 handle UNRECOGNIZED_ATP_PROOF () => ([], SOME ProofIncomplete))) |
727 handle UNRECOGNIZED_ATP_PROOF () => ([], SOME ProofIncomplete))) |
737 handle TimeLimit.TimeOut => (("", the slice_timeout), ([], SOME TimedOut)) |
728 handle TimeLimit.TimeOut => (("", slice_timeout), ([], SOME TimedOut)) |
738 val outcome = |
729 val outcome = |
739 case outcome of |
730 case outcome of |
740 NONE => |
731 NONE => |
741 (case used_facts_in_unsound_atp_proof ctxt fact_names atp_proof |
732 (case used_facts_in_unsound_atp_proof ctxt fact_names atp_proof |
742 |> Option.map (sort string_ord) of |
733 |> Option.map (sort string_ord) of |
757 end |
748 end |
758 val timer = Timer.startRealTimer () |
749 val timer = Timer.startRealTimer () |
759 fun maybe_run_slice slice |
750 fun maybe_run_slice slice |
760 (result as (cache, (_, run_time0, _, _, SOME _))) = |
751 (result as (cache, (_, run_time0, _, _, SOME _))) = |
761 let |
752 let |
762 val time_left = |
753 val time_left = Time.- (timeout, Timer.checkRealTimer timer) |
763 Option.map |
|
764 (fn timeout => Time.- (timeout, Timer.checkRealTimer timer)) |
|
765 timeout |
|
766 in |
754 in |
767 if time_left <> NONE andalso |
755 if Time.<= (time_left, Time.zeroTime) then |
768 Time.<= (the time_left, Time.zeroTime) then |
|
769 result |
756 result |
770 else |
757 else |
771 run_slice time_left cache slice |
758 run_slice time_left cache slice |
772 |> (fn (cache, (output, run_time, used_from, atp_proof, |
759 |> (fn (cache, (output, run_time, used_from, atp_proof, |
773 outcome)) => |
760 outcome)) => |
933 fun do_slice timeout slice outcome0 time_so_far |
920 fun do_slice timeout slice outcome0 time_so_far |
934 (weighted_factss as (fact_filter, weighted_facts) :: _) = |
921 (weighted_factss as (fact_filter, weighted_facts) :: _) = |
935 let |
922 let |
936 val timer = Timer.startRealTimer () |
923 val timer = Timer.startRealTimer () |
937 val slice_timeout = |
924 val slice_timeout = |
938 if slice < max_slices andalso timeout <> NONE then |
925 if slice < max_slices then |
939 let val ms = timeout |> the |> Time.toMilliseconds in |
926 let val ms = Time.toMilliseconds timeout in |
940 Int.min (ms, |
927 Int.min (ms, |
941 Int.max (1000 * Config.get ctxt smt_slice_min_secs, |
928 Int.max (1000 * Config.get ctxt smt_slice_min_secs, |
942 Real.ceil (Config.get ctxt smt_slice_time_frac |
929 Real.ceil (Config.get ctxt smt_slice_time_frac |
943 * Real.fromInt ms))) |
930 * Real.fromInt ms))) |
944 |> Time.fromMilliseconds |> SOME |
931 |> Time.fromMilliseconds |
945 end |
932 end |
946 else |
933 else |
947 timeout |
934 timeout |
948 val num_facts = length weighted_facts |
935 val num_facts = length weighted_facts |
949 val _ = |
936 val _ = |
950 if debug then |
937 if debug then |
951 quote name ^ " slice " ^ string_of_int slice ^ " with " ^ |
938 quote name ^ " slice " ^ string_of_int slice ^ " with " ^ string_of_int num_facts ^ |
952 string_of_int num_facts ^ " fact" ^ plural_s num_facts ^ |
939 " fact" ^ plural_s num_facts ^ " for " ^ string_of_time slice_timeout |
953 (case slice_timeout of |
|
954 SOME timeout => " for " ^ string_of_time timeout |
|
955 | NONE => "") ^ "..." |
|
956 |> Output.urgent_message |
940 |> Output.urgent_message |
957 else |
941 else |
958 () |
942 () |
959 val birth = Timer.checkRealTimer timer |
943 val birth = Timer.checkRealTimer timer |
960 val _ = |
944 val _ = |
961 if debug then Output.urgent_message "Invoking SMT solver..." else () |
945 if debug then Output.urgent_message "Invoking SMT solver..." else () |
962 val (outcome, used_facts) = |
946 val (outcome, used_facts) = |
963 SMT_Solver.smt_filter_preprocess ctxt [] goal weighted_facts i |
947 SMT_Solver.smt_filter_preprocess ctxt [] goal weighted_facts i |
964 |> SMT_Solver.smt_filter_apply (slice_timeout |> the_default one_day) |
948 |> SMT_Solver.smt_filter_apply slice_timeout |
965 |> (fn {outcome, used_facts} => (outcome, used_facts)) |
949 |> (fn {outcome, used_facts} => (outcome, used_facts)) |
966 handle exn => if Exn.is_interrupt exn then |
950 handle exn => if Exn.is_interrupt exn then |
967 reraise exn |
951 reraise exn |
968 else |
952 else |
969 (ML_Compiler.exn_message exn |
953 (ML_Compiler.exn_message exn |
977 | SOME (SMT_Failure.Counterexample _) => false |
961 | SOME (SMT_Failure.Counterexample _) => false |
978 | SOME SMT_Failure.Time_Out => slice_timeout <> timeout |
962 | SOME SMT_Failure.Time_Out => slice_timeout <> timeout |
979 | SOME (SMT_Failure.Abnormal_Termination _) => true (* kind of *) |
963 | SOME (SMT_Failure.Abnormal_Termination _) => true (* kind of *) |
980 | SOME SMT_Failure.Out_Of_Memory => true |
964 | SOME SMT_Failure.Out_Of_Memory => true |
981 | SOME (SMT_Failure.Other_Failure _) => true |
965 | SOME (SMT_Failure.Other_Failure _) => true |
982 val timeout = |
966 val timeout = Time.- (timeout, Timer.checkRealTimer timer) |
983 Option.map |
|
984 (fn timeout => Time.- (timeout, Timer.checkRealTimer timer)) |
|
985 timeout |
|
986 in |
967 in |
987 if too_many_facts_perhaps andalso slice < max_slices andalso |
968 if too_many_facts_perhaps andalso slice < max_slices andalso num_facts > 0 andalso |
988 num_facts > 0 andalso |
969 Time.> (timeout, Time.zeroTime) then |
989 (timeout = NONE orelse Time.> (the timeout, Time.zeroTime)) then |
|
990 let |
970 let |
991 val new_num_facts = |
971 val new_num_facts = |
992 Real.ceil (Config.get ctxt smt_slice_fact_frac |
972 Real.ceil (Config.get ctxt smt_slice_fact_frac * Real.fromInt num_facts) |
993 * Real.fromInt num_facts) |
|
994 val weighted_factss as (new_fact_filter, _) :: _ = |
973 val weighted_factss as (new_fact_filter, _) :: _ = |
995 weighted_factss |
974 weighted_factss |
996 |> rotate_one |
975 |> rotate_one |
997 |> app_hd (apsnd (take new_num_facts)) |
976 |> app_hd (apsnd (take new_num_facts)) |
998 val show_filter = fact_filter <> new_fact_filter |
977 val show_filter = fact_filter <> new_fact_filter |