5 *) |
5 *) |
6 |
6 |
7 infix 1 THEN_MAYBE THEN_MAYBE'; |
7 infix 1 THEN_MAYBE THEN_MAYBE'; |
8 |
8 |
9 signature SEARCH = |
9 signature SEARCH = |
10 sig |
10 sig |
11 val DEEPEN : int*int -> (int->int->tactic) -> int -> int -> tactic |
11 val trace_DEPTH_FIRST: bool Unsynchronized.ref |
12 |
12 val DEPTH_FIRST: (thm -> bool) -> tactic -> tactic |
13 val THEN_MAYBE : tactic * tactic -> tactic |
13 val has_fewer_prems: int -> thm -> bool |
14 val THEN_MAYBE' : ('a -> tactic) * ('a -> tactic) -> ('a -> tactic) |
14 val IF_UNSOLVED: tactic -> tactic |
15 |
15 val SOLVE: tactic -> tactic |
16 val trace_DEPTH_FIRST : bool Unsynchronized.ref |
|
17 val DEPTH_FIRST : (thm -> bool) -> tactic -> tactic |
|
18 val DEPTH_SOLVE : tactic -> tactic |
|
19 val DEPTH_SOLVE_1 : tactic -> tactic |
|
20 val ITER_DEEPEN : (thm->bool) -> (int->tactic) -> tactic |
|
21 val THEN_ITER_DEEPEN : tactic -> (thm->bool) -> (int->tactic) -> tactic |
|
22 val iter_deepen_limit : int Unsynchronized.ref |
|
23 |
|
24 val has_fewer_prems : int -> thm -> bool |
|
25 val IF_UNSOLVED : tactic -> tactic |
|
26 val SOLVE : tactic -> tactic |
|
27 val DETERM_UNTIL_SOLVED: tactic -> tactic |
16 val DETERM_UNTIL_SOLVED: tactic -> tactic |
28 val trace_BEST_FIRST : bool Unsynchronized.ref |
17 val THEN_MAYBE: tactic * tactic -> tactic |
29 val BEST_FIRST : (thm -> bool) * (thm -> int) -> tactic -> tactic |
18 val THEN_MAYBE': ('a -> tactic) * ('a -> tactic) -> 'a -> tactic |
30 val THEN_BEST_FIRST : tactic -> (thm->bool) * (thm->int) -> tactic |
19 val DEPTH_SOLVE: tactic -> tactic |
31 -> tactic |
20 val DEPTH_SOLVE_1: tactic -> tactic |
32 val trace_ASTAR : bool Unsynchronized.ref |
21 val iter_deepen_limit: int Unsynchronized.ref |
33 val ASTAR : (thm -> bool) * (int->thm->int) -> tactic -> tactic |
22 val THEN_ITER_DEEPEN: tactic -> (thm -> bool) -> (int -> tactic) -> tactic |
34 val THEN_ASTAR : tactic -> (thm->bool) * (int->thm->int) -> tactic |
23 val ITER_DEEPEN: (thm -> bool) -> (int -> tactic) -> tactic |
35 -> tactic |
24 val DEEPEN: int * int -> (int -> int -> tactic) -> int -> int -> tactic |
36 val BREADTH_FIRST : (thm -> bool) -> tactic -> tactic |
25 val trace_BEST_FIRST: bool Unsynchronized.ref |
37 val QUIET_BREADTH_FIRST : (thm -> bool) -> tactic -> tactic |
26 val THEN_BEST_FIRST: tactic -> (thm -> bool) * (thm -> int) -> tactic -> tactic |
38 end; |
27 val BEST_FIRST: (thm -> bool) * (thm -> int) -> tactic -> tactic |
39 |
28 val BREADTH_FIRST: (thm -> bool) -> tactic -> tactic |
40 |
29 val QUIET_BREADTH_FIRST: (thm -> bool) -> tactic -> tactic |
41 (** Instantiation of heaps for best-first search **) |
30 val trace_ASTAR: bool Unsynchronized.ref |
42 |
31 val THEN_ASTAR: tactic -> (thm -> bool) * (int -> thm -> int) -> tactic -> tactic |
43 (*total ordering on theorems, allowing duplicates to be found*) |
32 val ASTAR: (thm -> bool) * (int -> thm -> int) -> tactic -> tactic |
44 structure ThmHeap = Heap |
33 end; |
45 ( |
34 |
46 type elem = int * thm; |
35 structure Search: SEARCH = |
47 val ord = prod_ord int_ord (TermOrd.term_ord o pairself Thm.prop_of); |
|
48 ); |
|
49 |
|
50 |
|
51 structure Search : SEARCH = |
|
52 struct |
36 struct |
53 |
37 |
54 (**** Depth-first search ****) |
38 (**** Depth-first search ****) |
55 |
39 |
56 val trace_DEPTH_FIRST = Unsynchronized.ref false; |
40 val trace_DEPTH_FIRST = Unsynchronized.ref false; |
85 val DETERM_UNTIL_SOLVED = DETERM_UNTIL (has_fewer_prems 1); |
69 val DETERM_UNTIL_SOLVED = DETERM_UNTIL (has_fewer_prems 1); |
86 |
70 |
87 (*Execute tac1, but only execute tac2 if there are at least as many subgoals |
71 (*Execute tac1, but only execute tac2 if there are at least as many subgoals |
88 as before. This ensures that tac2 is only applied to an outcome of tac1.*) |
72 as before. This ensures that tac2 is only applied to an outcome of tac1.*) |
89 fun (tac1 THEN_MAYBE tac2) st = |
73 fun (tac1 THEN_MAYBE tac2) st = |
90 (tac1 THEN COND (has_fewer_prems (nprems_of st)) all_tac tac2) st; |
74 (tac1 THEN COND (has_fewer_prems (nprems_of st)) all_tac tac2) st; |
91 |
75 |
92 fun (tac1 THEN_MAYBE' tac2) x = tac1 x THEN_MAYBE tac2 x; |
76 fun (tac1 THEN_MAYBE' tac2) x = tac1 x THEN_MAYBE tac2 x; |
93 |
77 |
94 (*Tactical to reduce the number of premises by 1. |
78 (*Tactical to reduce the number of premises by 1. |
95 If no subgoals then it must fail! *) |
79 If no subgoals then it must fail! *) |
198 no_tac) |
182 no_tac) |
199 else (priority ("Search depth = " ^ string_of_int m); |
183 else (priority ("Search depth = " ^ string_of_int m); |
200 tacf m i ORELSE dpn (m+inc))) |
184 tacf m i ORELSE dpn (m+inc))) |
201 in dpn m end; |
185 in dpn m end; |
202 |
186 |
|
187 |
203 (*** Best-first search ***) |
188 (*** Best-first search ***) |
|
189 |
|
190 (*total ordering on theorems, allowing duplicates to be found*) |
|
191 structure Thm_Heap = Heap |
|
192 ( |
|
193 type elem = int * thm; |
|
194 val ord = prod_ord int_ord (TermOrd.term_ord o pairself Thm.prop_of); |
|
195 ); |
204 |
196 |
205 val trace_BEST_FIRST = Unsynchronized.ref false; |
197 val trace_BEST_FIRST = Unsynchronized.ref false; |
206 |
198 |
207 (*For creating output sequence*) |
199 (*For creating output sequence*) |
208 fun some_of_list [] = NONE |
200 fun some_of_list [] = NONE |
209 | some_of_list (x::l) = SOME (x, Seq.make (fn () => some_of_list l)); |
201 | some_of_list (x::l) = SOME (x, Seq.make (fn () => some_of_list l)); |
210 |
202 |
211 (*Check for and delete duplicate proof states*) |
203 (*Check for and delete duplicate proof states*) |
212 fun deleteAllMin prf heap = |
204 fun delete_all_min prf heap = |
213 if ThmHeap.is_empty heap then heap |
205 if Thm_Heap.is_empty heap then heap |
214 else if Thm.eq_thm (prf, #2 (ThmHeap.min heap)) |
206 else if Thm.eq_thm (prf, #2 (Thm_Heap.min heap)) |
215 then deleteAllMin prf (ThmHeap.delete_min heap) |
207 then delete_all_min prf (Thm_Heap.delete_min heap) |
216 else heap; |
208 else heap; |
217 |
209 |
218 (*Best-first search for a state that satisfies satp (incl initial state) |
210 (*Best-first search for a state that satisfies satp (incl initial state) |
219 Function sizef estimates size of problem remaining (smaller means better). |
211 Function sizef estimates size of problem remaining (smaller means better). |
220 tactic tac0 sets up the initial priority queue, while tac1 searches it. *) |
212 tactic tac0 sets up the initial priority queue, while tac1 searches it. *) |
221 fun THEN_BEST_FIRST tac0 (satp, sizef) tac1 = |
213 fun THEN_BEST_FIRST tac0 (satp, sizef) tac1 = |
222 let val tac = tracify trace_BEST_FIRST tac1 |
214 let val tac = tracify trace_BEST_FIRST tac1 |
223 fun pairsize th = (sizef th, th); |
215 fun pairsize th = (sizef th, th); |
224 fun bfs (news,nprf_heap) = |
216 fun bfs (news,nprf_heap) = |
225 (case List.partition satp news of |
217 (case List.partition satp news of |
226 ([],nonsats) => next(fold_rev ThmHeap.insert (map pairsize nonsats) nprf_heap) |
218 ([],nonsats) => next(fold_rev Thm_Heap.insert (map pairsize nonsats) nprf_heap) |
227 | (sats,_) => some_of_list sats) |
219 | (sats,_) => some_of_list sats) |
228 and next nprf_heap = |
220 and next nprf_heap = |
229 if ThmHeap.is_empty nprf_heap then NONE |
221 if Thm_Heap.is_empty nprf_heap then NONE |
230 else |
222 else |
231 let val (n,prf) = ThmHeap.min nprf_heap |
223 let val (n,prf) = Thm_Heap.min nprf_heap |
232 in if !trace_BEST_FIRST |
224 in if !trace_BEST_FIRST |
233 then tracing("state size = " ^ string_of_int n) |
225 then tracing("state size = " ^ string_of_int n) |
234 else (); |
226 else (); |
235 bfs (Seq.list_of (tac prf), |
227 bfs (Seq.list_of (tac prf), |
236 deleteAllMin prf (ThmHeap.delete_min nprf_heap)) |
228 delete_all_min prf (Thm_Heap.delete_min nprf_heap)) |
237 end |
229 end |
238 fun btac st = bfs (Seq.list_of (tac0 st), ThmHeap.empty) |
230 fun btac st = bfs (Seq.list_of (tac0 st), Thm_Heap.empty) |
239 in traced_tac btac end; |
231 in traced_tac btac end; |
240 |
232 |
241 (*Ordinary best-first search, with no initial tactic*) |
233 (*Ordinary best-first search, with no initial tactic*) |
242 val BEST_FIRST = THEN_BEST_FIRST all_tac; |
234 val BEST_FIRST = THEN_BEST_FIRST all_tac; |
243 |
235 |