src/HOL/Tools/Sledgehammer/sledgehammer_provers.ML
changeset 41313 a96ac4d180b7
parent 41259 13972ced98d9
child 41315 7f6baec2b27a
equal deleted inserted replaced
41299:fc8419fd4735 41313:a96ac4d180b7
    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