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] |
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 |