src/Pure/search.ML
changeset 32940 51d450f278ce
parent 32939 1b5a401c78cb
child 33335 1e189f96c393
equal deleted inserted replaced
32939:1b5a401c78cb 32940:51d450f278ce
     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