src/HOL/Tools/ATP_Manager/atp_minimal.ML
changeset 32947 3c19b98a35cd
parent 32942 b6711ec9de26
child 32948 e95a4be101a8
equal deleted inserted replaced
32946:22664da2923b 32947:3c19b98a35cd
    11 end
    11 end
    12 
    12 
    13 structure ATP_Minimal: ATP_MINIMAL =
    13 structure ATP_Minimal: ATP_MINIMAL =
    14 struct
    14 struct
    15 
    15 
    16 (* output control *)
       
    17 
       
    18 fun debug str = Output.debug (fn () => str)
       
    19 fun debug_fn f = if ! Output.debugging then f () else ()
       
    20 fun answer str = Output.writeln str
       
    21 fun println str = Output.priority str
       
    22 
       
    23 fun order_unique name_list = OrdList.make (String.collate Char.compare) name_list
       
    24 fun length_string namelist = Int.toString (length namelist)
       
    25 
       
    26 fun print_names name_thms_pairs =
       
    27   let
       
    28     val names = map fst name_thms_pairs
       
    29     val ordered = order_unique names
       
    30   in
       
    31     app (fn name => (debug ("  " ^ name))) ordered
       
    32   end
       
    33 
       
    34 
       
    35 (* minimalization algorithm *)
    16 (* minimalization algorithm *)
    36 
    17 
    37 local
    18 local
    38   fun isplit (l,r) [] = (l,r)
    19   fun isplit (l, r) [] = (l, r)
    39     | isplit (l,r) (h::[]) = (h::l, r)
    20     | isplit (l, r) [h] = (h :: l, r)
    40     | isplit (l,r) (h1::h2::t) = isplit (h1::l, h2::r) t
    21     | isplit (l, r) (h1 :: h2 :: t) = isplit (h1 :: l, h2 :: r) t
    41 in
    22 in
    42   fun split lst = isplit ([],[]) lst
    23   fun split lst = isplit ([], []) lst
    43 end
    24 end
    44 
    25 
    45 local
    26 local
    46   fun min p sup [] = raise Empty
    27   fun min p sup [] = raise Empty
    47     | min p sup [s0] = [s0]
    28     | min p sup [s0] = [s0]
    67    @pre p(s) & ~p([]) & monotone(p)
    48    @pre p(s) & ~p([]) & monotone(p)
    68    @post v subset s & p(v) &
    49    @post v subset s & p(v) &
    69          forall e in v. ~p(v \ e)
    50          forall e in v. ~p(v \ e)
    70    *)
    51    *)
    71   fun minimal p s =
    52   fun minimal p s =
    72     let val c = Unsynchronized.ref 0
    53     let
    73         fun pc xs = (c := !c + 1; p xs)
    54       val count = Unsynchronized.ref 0
    74     in
    55       fun p_count xs = (Unsynchronized.inc count; p xs)
    75     (case min pc [] s of
    56       val v =
    76        [x] => if pc [] then [] else [x]
    57         (case min p_count [] s of
    77      | m => m,
    58           [x] => if p_count [] then [] else [x]
    78      !c)
    59         | m => m);
    79     end
    60     in (v, ! count) end
    80 end
    61 end
    81 
    62 
    82 
    63 
    83 (* failure check and producing answer *)
    64 (* failure check and producing answer *)
    84 
    65 
   100 fun produce_answer (result: ATP_Wrapper.prover_result) =
    81 fun produce_answer (result: ATP_Wrapper.prover_result) =
   101   let
    82   let
   102     val {success, proof = result_string, internal_thm_names = thm_name_vec,
    83     val {success, proof = result_string, internal_thm_names = thm_name_vec,
   103       filtered_clauses = filtered, ...} = result
    84       filtered_clauses = filtered, ...} = result
   104   in
    85   in
   105   if success then
    86     if success then
   106     (Success (Vector.foldr op:: [] thm_name_vec, filtered), result_string)
    87       (Success (Vector.foldr (op ::) [] thm_name_vec, filtered), result_string)
   107   else
    88     else
   108     let
    89       let
   109       val failure = failure_strings |> get_first (fn (s, t) =>
    90         val failure = failure_strings |> get_first (fn (s, t) =>
   110           if String.isSubstring s result_string then SOME (t, result_string) else NONE)
    91             if String.isSubstring s result_string then SOME (t, result_string) else NONE)
   111     in
    92       in
   112       if is_some failure then
    93         (case failure of
   113         the failure
    94           SOME res => res
   114       else
    95         | NONE => (Failure, result_string))
   115         (Failure, result_string)
    96       end
   116     end
       
   117   end
    97   end
   118 
    98 
   119 
    99 
   120 (* wrapper for calling external prover *)
   100 (* wrapper for calling external prover *)
   121 
   101 
   122 fun sh_test_thms prover time_limit subgoalno state filtered name_thms_pairs =
   102 fun sh_test_thms prover time_limit subgoalno state filtered name_thms_pairs =
   123   let
   103   let
   124     val _ = println ("Testing " ^ (length_string name_thms_pairs) ^ " theorems... ")
   104     val _ = priority ("Testing " ^ string_of_int (length name_thms_pairs) ^ " theorems... ")
   125     val name_thm_pairs = maps (fn (n, ths) => map (pair n) ths) name_thms_pairs
   105     val name_thm_pairs = maps (fn (n, ths) => map (pair n) ths) name_thms_pairs
   126     val _ = debug_fn (fn () => print_names name_thm_pairs)
       
   127     val axclauses = ResAxioms.cnf_rules_pairs (Proof.theory_of state) name_thm_pairs
   106     val axclauses = ResAxioms.cnf_rules_pairs (Proof.theory_of state) name_thm_pairs
   128     val problem =
   107     val problem =
   129      {with_full_types = ! ATP_Manager.full_types,
   108      {with_full_types = ! ATP_Manager.full_types,
   130       subgoal = subgoalno,
   109       subgoal = subgoalno,
   131       goal = Proof.get_goal state,
   110       goal = Proof.get_goal state,
   132       axiom_clauses = SOME axclauses,
   111       axiom_clauses = SOME axclauses,
   133       filtered_clauses = filtered}
   112       filtered_clauses = filtered}
   134     val (result, proof) = produce_answer (prover problem time_limit)
   113     val (result, proof) = produce_answer (prover problem time_limit)
   135     val _ = println (string_of_result result)
   114     val _ = priority (string_of_result result)
   136     val _ = debug proof
       
   137   in
   115   in
   138     (result, proof)
   116     (result, proof)
   139   end
   117   end
   140 
   118 
   141 
   119 
   142 (* minimalization of thms *)
   120 (* minimalization of thms *)
   143 
   121 
   144 fun minimalize prover prover_name time_limit state name_thms_pairs =
   122 fun minimalize prover prover_name time_limit state name_thms_pairs =
   145   let
   123   let
   146     val _ =
   124     val _ =
   147       println ("Minimize called with " ^ length_string name_thms_pairs ^ " theorems, prover: "
   125       priority ("Minimize called with " ^ string_of_int (length name_thms_pairs) ^
   148         ^ prover_name ^ ", time limit: " ^ Int.toString time_limit ^ " seconds")
   126         " theorems, prover: " ^ prover_name ^
   149     val _ = debug_fn (fn () => app (fn (n, tl) =>
   127         ", time limit: " ^ string_of_int time_limit ^ " seconds")
   150         (debug n; app (fn t =>
       
   151           debug ("  " ^ Display.string_of_thm (Proof.context_of state) t)) tl)) name_thms_pairs)
       
   152     val test_thms_fun = sh_test_thms prover time_limit 1 state
   128     val test_thms_fun = sh_test_thms prover time_limit 1 state
   153     fun test_thms filtered thms =
   129     fun test_thms filtered thms =
   154       case test_thms_fun filtered thms of (Success _, _) => true | _ => false
   130       case test_thms_fun filtered thms of (Success _, _) => true | _ => false
   155     val answer' = pair and answer'' = pair NONE
       
   156   in
   131   in
   157     (* try prove first to check result and get used theorems *)
   132     (* try prove first to check result and get used theorems *)
   158     (case test_thms_fun NONE name_thms_pairs of
   133     (case test_thms_fun NONE name_thms_pairs of
   159       (Success (used, filtered), _) =>
   134       (Success (used, filtered), _) =>
   160         let
   135         let
   161           val ordered_used = order_unique used
   136           val ordered_used = sort_distinct string_ord used
   162           val to_use =
   137           val to_use =
   163             if length ordered_used < length name_thms_pairs then
   138             if length ordered_used < length name_thms_pairs then
   164               filter (fn (name1, _) => List.exists (equal name1) ordered_used) name_thms_pairs
   139               filter (fn (name1, _) => List.exists (equal name1) ordered_used) name_thms_pairs
   165             else
   140             else
   166               name_thms_pairs
   141               name_thms_pairs
   167           val (min_thms, n) = if null to_use then ([], 0)
   142           val (min_thms, n) = if null to_use then ([], 0)
   168             else minimal (test_thms (SOME filtered)) to_use
   143             else minimal (test_thms (SOME filtered)) to_use
   169           val min_names = order_unique (map fst min_thms)
   144           val min_names = sort_distinct string_ord (map fst min_thms)
   170           val _ = println ("Interations: " ^ string_of_int n)
   145           val _ = priority (cat_lines
   171           val _ = println ("Minimal " ^ (length_string min_thms) ^ " theorems")
   146             ["Interations: " ^ string_of_int n,
   172           val _ = debug_fn (fn () => print_names min_thms)
   147               "Minimal " ^ string_of_int (length min_thms) ^ " theorems"])
   173         in
   148         in
   174           answer' (SOME(min_thms,n)) ("Try this command: " ^
   149           (SOME (min_thms, n), "Try this command: " ^
   175             Markup.markup Markup.sendback ("apply (metis " ^ space_implode " " min_names ^ ")"))
   150             Markup.markup Markup.sendback ("apply (metis " ^ space_implode " " min_names ^ ")"))
   176         end
   151         end
   177     | (Timeout, _) =>
   152     | (Timeout, _) =>
   178         answer'' ("Timeout: You may need to increase the time limit of " ^
   153         (NONE, "Timeout: You may need to increase the time limit of " ^
   179           Int.toString time_limit ^ " seconds. Call atp_minimize [time=...] ")
   154           string_of_int time_limit ^ " seconds. Call atp_minimize [time=...] ")
   180     | (Error, msg) =>
   155     | (Error, msg) =>
   181         answer'' ("Error in prover: " ^ msg)
   156         (NONE, "Error in prover: " ^ msg)
   182     | (Failure, _) =>
   157     | (Failure, _) =>
   183         answer'' "Failure: No proof with the theorems supplied")
   158         (NONE, "Failure: No proof with the theorems supplied"))
   184     handle ResHolClause.TOO_TRIVIAL =>
   159     handle ResHolClause.TOO_TRIVIAL =>
   185         answer' (SOME ([],0)) ("Trivial: Try this command: " ^ Markup.markup Markup.sendback "apply metis")
   160         (SOME ([], 0), "Trivial: Try this command: " ^ Markup.markup Markup.sendback "apply metis")
   186     | ERROR msg =>
   161       | ERROR msg => (NONE, "Error: " ^ msg)
   187         answer'' ("Error: " ^ msg)
       
   188   end
   162   end
   189 
   163 
   190 
   164 
   191 (* Isar command and parsing input *)
   165 (* Isar command and parsing input *)
   192 
   166 
   208 fun get_time_limit_arg time_string =
   182 fun get_time_limit_arg time_string =
   209   (case Int.fromString time_string of
   183   (case Int.fromString time_string of
   210     SOME t => t
   184     SOME t => t
   211   | NONE => error ("Invalid time limit: " ^ quote time_string))
   185   | NONE => error ("Invalid time limit: " ^ quote time_string))
   212 
   186 
   213 val get_options =
   187 fun get_opt (name, a) (p, t) =
   214   let
   188   (case name of
   215     val def = (default_prover, default_time_limit)
   189     "time" => (p, get_time_limit_arg a)
   216   in
   190   | "atp" => (a, t)
   217     foldl (fn ((name, a), (p, t)) =>
   191   | n => error ("Invalid argument: " ^ n))
   218       (case name of
   192 
   219         "time" => (p, (get_time_limit_arg a))
   193 fun get_options args = fold get_opt args (default_prover, default_time_limit)
   220       | "atp" => (a, t)
       
   221       | n => error ("Invalid argument: " ^ n))) def
       
   222   end
       
   223 
   194 
   224 fun sh_min_command args thm_names state =
   195 fun sh_min_command args thm_names state =
   225   let
   196   let
   226     val (prover_name, time_limit) = get_options args
   197     val (prover_name, time_limit) = get_options args
   227     val prover =
   198     val prover =
   228       case ATP_Manager.get_prover prover_name (Proof.theory_of state) of
   199       (case ATP_Manager.get_prover (Proof.theory_of state) prover_name of
   229         SOME prover => prover
   200         SOME prover => prover
   230       | NONE => error ("Unknown prover: " ^ quote prover_name)
   201       | NONE => error ("Unknown prover: " ^ quote prover_name))
   231     val name_thms_pairs = get_thms (Proof.context_of state) thm_names
   202     val name_thms_pairs = get_thms (Proof.context_of state) thm_names
   232     fun print_answer (_, msg) = answer msg
   203   in
   233   in
   204     writeln (#2 (minimalize prover prover_name time_limit state name_thms_pairs))
   234     print_answer (minimalize prover prover_name time_limit state name_thms_pairs)
       
   235   end
   205   end
   236 
   206 
   237 val parse_args = Scan.optional (Args.bracks (P.list (P.xname --| P.$$$ "=" -- P.xname))) []
   207 val parse_args = Scan.optional (Args.bracks (P.list (P.xname --| P.$$$ "=" -- P.xname))) []
   238 val parse_thm_names = Scan.repeat (P.xname -- Scan.option Attrib.thm_sel)
   208 val parse_thm_names = Scan.repeat (P.xname -- Scan.option Attrib.thm_sel)
   239 
   209