src/Provers/blast.ML
changeset 42801 da4ad5f98953
parent 42793 88bee9f6eec7
child 42802 51d7e74f6899
equal deleted inserted replaced
42800:df2dc9406287 42801:da4ad5f98953
   107 
   107 
   108 
   108 
   109 (* global state information *)
   109 (* global state information *)
   110 
   110 
   111 datatype state = State of
   111 datatype state = State of
   112  {thy: theory,
   112  {ctxt: Proof.context,
   113   fullTrace: branch list list Unsynchronized.ref,
   113   fullTrace: branch list list Unsynchronized.ref,
   114   trail: term option Unsynchronized.ref list Unsynchronized.ref,
   114   trail: term option Unsynchronized.ref list Unsynchronized.ref,
   115   ntrail: int Unsynchronized.ref,
   115   ntrail: int Unsynchronized.ref,
   116   nclosed: int Unsynchronized.ref,
   116   nclosed: int Unsynchronized.ref,
   117   ntried: int Unsynchronized.ref}
   117   ntried: int Unsynchronized.ref}
   118 
   118 
   119 fun reject_const thy c =
   119 fun reject_const thy c =
   120   is_some (Sign.const_type thy c) andalso
   120   is_some (Sign.const_type thy c) andalso
   121     error ("blast: theory contains illegal constant " ^ quote c);
   121     error ("blast: theory contains illegal constant " ^ quote c);
   122 
   122 
   123 fun initialize thy =
   123 fun initialize ctxt =
   124  (reject_const thy "*Goal*";
   124   let
   125   reject_const thy "*False*";
   125     val thy = Proof_Context.theory_of ctxt;
   126   State
   126     val _ = reject_const thy "*Goal*";
   127    {thy = thy,
   127     val _ = reject_const thy "*False*";
   128     fullTrace = Unsynchronized.ref [],
   128   in
   129     trail = Unsynchronized.ref [],
   129     State
   130     ntrail = Unsynchronized.ref 0,
   130      {ctxt = ctxt,
   131     nclosed = Unsynchronized.ref 0, (*branches closed: number of branches closed during the search*)
   131       fullTrace = Unsynchronized.ref [],
   132     ntried = Unsynchronized.ref 1}); (*branches tried: number of branches created by splitting (counting from 1)*)
   132       trail = Unsynchronized.ref [],
       
   133       ntrail = Unsynchronized.ref 0,
       
   134       nclosed = Unsynchronized.ref 0, (*number of branches closed during the search*)
       
   135       ntried = Unsynchronized.ref 1} (*number of branches created by splitting (counting from 1)*)
       
   136   end;
   133 
   137 
   134 
   138 
   135 
   139 
   136 (** Basic syntactic operations **)
   140 (** Basic syntactic operations **)
   137 
   141 
   166 fun mkGoal P = Const ("*Goal*", []) $ P;
   170 fun mkGoal P = Const ("*Goal*", []) $ P;
   167 
   171 
   168 fun isGoal (Const ("*Goal*", _) $ _) = true
   172 fun isGoal (Const ("*Goal*", _) $ _) = true
   169   | isGoal _ = false;
   173   | isGoal _ = false;
   170 
   174 
   171 val TruepropC = Object_Logic.judgment_name Data.thy;
   175 val TruepropC = Object_Logic.judgment_name Data.thy;  (* FIXME *)
   172 val TruepropT = Sign.the_const_type Data.thy TruepropC;
   176 val TruepropT = Sign.the_const_type Data.thy TruepropC;
   173 
   177 
   174 fun mk_Trueprop t = Term.$ (Term.Const (TruepropC, TruepropT), t);
   178 fun mk_Trueprop t = Term.$ (Term.Const (TruepropC, TruepropT), t);
   175 
   179 
   176 fun strip_Trueprop (tm as Const (c, _) $ t) = if c = TruepropC then t else tm
   180 fun strip_Trueprop (tm as Const (c, _) $ t) = if c = TruepropC then t else tm
   489 fun rmtac upd rl = TRACE rl (if upd then rtac rl else match_tac [rl]);
   493 fun rmtac upd rl = TRACE rl (if upd then rtac rl else match_tac [rl]);
   490 
   494 
   491 (*Tableau rule from elimination rule.
   495 (*Tableau rule from elimination rule.
   492   Flag "upd" says that the inference updated the branch.
   496   Flag "upd" says that the inference updated the branch.
   493   Flag "dup" requests duplication of the affected formula.*)
   497   Flag "dup" requests duplication of the affected formula.*)
   494 fun fromRule thy vars rl =
   498 fun fromRule ctxt vars rl =
   495   let val trl = rl |> Thm.prop_of |> fromTerm thy |> convertRule vars
   499   let val thy = Proof_Context.theory_of ctxt
       
   500       val trl = rl |> Thm.prop_of |> fromTerm thy |> convertRule vars
   496       fun tac (upd, dup,rot) i =
   501       fun tac (upd, dup,rot) i =
   497         emtac upd (if dup then rev_dup_elim rl else rl) i
   502         emtac upd (if dup then rev_dup_elim rl else rl) i
   498         THEN
   503         THEN
   499         rot_subgoals_tac (rot, #2 trl) i
   504         rot_subgoals_tac (rot, #2 trl) i
   500   in Option.SOME (trl, tac) end
   505   in Option.SOME (trl, tac) end
   501   handle
   506   handle
   502     ElimBadPrem => (*reject: prems don't preserve conclusion*)
   507     ElimBadPrem => (*reject: prems don't preserve conclusion*)
   503       (warning ("Ignoring weak elimination rule\n" ^ Display.string_of_thm_global thy rl);
   508       (warning ("Ignoring weak elimination rule\n" ^ Display.string_of_thm ctxt rl);
   504         Option.NONE)
   509         Option.NONE)
   505   | ElimBadConcl => (*ignore: conclusion is not just a variable*)
   510   | ElimBadConcl => (*ignore: conclusion is not just a variable*)
   506       (if !trace then
   511       (if !trace then
   507         (warning ("Ignoring ill-formed elimination rule:\n" ^
   512         (warning ("Ignoring ill-formed elimination rule:\n" ^
   508           "conclusion should be a variable\n" ^ Display.string_of_thm_global thy rl))
   513           "conclusion should be a variable\n" ^ Display.string_of_thm ctxt rl))
   509        else ();
   514        else ();
   510        Option.NONE);
   515        Option.NONE);
   511 
   516 
   512 
   517 
   513 (*** Conversion of Introduction Rules ***)
   518 (*** Conversion of Introduction Rules ***)
   523 (*Tableau rule from introduction rule.
   528 (*Tableau rule from introduction rule.
   524   Flag "upd" says that the inference updated the branch.
   529   Flag "upd" says that the inference updated the branch.
   525   Flag "dup" requests duplication of the affected formula.
   530   Flag "dup" requests duplication of the affected formula.
   526   Since haz rules are now delayed, "dup" is always FALSE for
   531   Since haz rules are now delayed, "dup" is always FALSE for
   527   introduction rules.*)
   532   introduction rules.*)
   528 fun fromIntrRule thy vars rl =
   533 fun fromIntrRule ctxt vars rl =
   529   let val trl = rl |> Thm.prop_of |> fromTerm thy |> convertIntrRule vars
   534   let val thy = Proof_Context.theory_of ctxt
       
   535       val trl = rl |> Thm.prop_of |> fromTerm thy |> convertIntrRule vars
   530       fun tac (upd,dup,rot) i =
   536       fun tac (upd,dup,rot) i =
   531          rmtac upd (if dup then Classical.dup_intr rl else rl) i
   537          rmtac upd (if dup then Classical.dup_intr rl else rl) i
   532          THEN
   538          THEN
   533          rot_subgoals_tac (rot, #2 trl) i
   539          rot_subgoals_tac (rot, #2 trl) i
   534   in (trl, tac) end;
   540   in (trl, tac) end;
   546   | toTerm d (Var _)       = dummyVar
   552   | toTerm d (Var _)       = dummyVar
   547   | toTerm d (Abs(a,_))    = dummyVar
   553   | toTerm d (Abs(a,_))    = dummyVar
   548   | toTerm d (f $ u)       = Term.$ (toTerm d f, toTerm (d-1) u);
   554   | toTerm d (f $ u)       = Term.$ (toTerm d f, toTerm (d-1) u);
   549 
   555 
   550 
   556 
   551 fun netMkRules thy P vars (nps: netpair list) =
   557 fun netMkRules ctxt P vars (nps: netpair list) =
   552   case P of
   558   case P of
   553       (Const ("*Goal*", _) $ G) =>
   559       (Const ("*Goal*", _) $ G) =>
   554         let val pG = mk_Trueprop (toTerm 2 G)
   560         let val pG = mk_Trueprop (toTerm 2 G)
   555             val intrs = maps (fn (inet,_) => Net.unify_term inet pG) nps
   561             val intrs = maps (fn (inet,_) => Net.unify_term inet pG) nps
   556         in  map (fromIntrRule thy vars o #2) (order_list intrs)  end
   562         in  map (fromIntrRule ctxt vars o #2) (order_list intrs)  end
   557     | _ =>
   563     | _ =>
   558         let val pP = mk_Trueprop (toTerm 3 P)
   564         let val pP = mk_Trueprop (toTerm 3 P)
   559             val elims = maps (fn (_,enet) => Net.unify_term enet pP) nps
   565             val elims = maps (fn (_,enet) => Net.unify_term enet pP) nps
   560         in  map_filter (fromRule thy vars o #2) (order_list elims)  end;
   566         in  map_filter (fromRule ctxt vars o #2) (order_list elims)  end;
   561 
   567 
   562 
   568 
   563 (*Normalize a branch--for tracing*)
   569 (*Normalize a branch--for tracing*)
   564 fun norm2 (G,md) = (norm G, md);
   570 fun norm2 (G,md) = (norm G, md);
   565 
   571 
   600   | showTerm d (Abs(a,t))    = if d=0 then dummyVar
   606   | showTerm d (Abs(a,t))    = if d=0 then dummyVar
   601                                else Term.Abs(a, dummyT, showTerm (d-1) t)
   607                                else Term.Abs(a, dummyT, showTerm (d-1) t)
   602   | showTerm d (f $ u)       = if d=0 then dummyVar
   608   | showTerm d (f $ u)       = if d=0 then dummyVar
   603                                else Term.$ (showTerm d f, showTerm (d-1) u);
   609                                else Term.$ (showTerm d f, showTerm (d-1) u);
   604 
   610 
   605 fun string_of thy d t = Syntax.string_of_term_global thy (showTerm d t);
   611 fun string_of ctxt d t = Syntax.string_of_term ctxt (showTerm d t);
   606 
   612 
   607 (*Convert a Goal to an ordinary Not.  Used also in dup_intr, where a goal like
   613 (*Convert a Goal to an ordinary Not.  Used also in dup_intr, where a goal like
   608   Ex(P) is duplicated as the assumption ~Ex(P). *)
   614   Ex(P) is duplicated as the assumption ~Ex(P). *)
   609 fun negOfGoal (Const ("*Goal*", _) $ G) = negate G
   615 fun negOfGoal (Const ("*Goal*", _) $ G) = negate G
   610   | negOfGoal G = G;
   616   | negOfGoal G = G;
   618 
   624 
   619 (*Tactic.  Convert *Goal* to negated assumption in FIRST position*)
   625 (*Tactic.  Convert *Goal* to negated assumption in FIRST position*)
   620 fun negOfGoal_tac i = TRACE Data.ccontr (rtac Data.ccontr) i THEN
   626 fun negOfGoal_tac i = TRACE Data.ccontr (rtac Data.ccontr) i THEN
   621                       rotate_tac ~1 i;
   627                       rotate_tac ~1 i;
   622 
   628 
   623 fun traceTerm thy t =
   629 fun traceTerm ctxt t =
   624   let val t' = norm (negOfGoal t)
   630   let val thy = Proof_Context.theory_of ctxt
   625       val stm = string_of thy 8 t'
   631       val t' = norm (negOfGoal t)
       
   632       val stm = string_of ctxt 8 t'
   626   in
   633   in
   627       case topType thy t' of
   634       case topType thy t' of
   628           NONE   => stm   (*no type to attach*)
   635           NONE   => stm   (*no type to attach*)
   629         | SOME T => stm ^ "\t:: " ^ Syntax.string_of_typ_global thy T
   636         | SOME T => stm ^ "\t:: " ^ Syntax.string_of_typ ctxt T
   630   end;
   637   end;
   631 
   638 
   632 
   639 
   633 (*Print tracing information at each iteration of prover*)
   640 (*Print tracing information at each iteration of prover*)
   634 fun tracing (State {thy, fullTrace, ...}) brs =
   641 fun tracing (State {ctxt, fullTrace, ...}) brs =
   635   let fun printPairs (((G,_)::_,_)::_)  = Output.tracing (traceTerm thy G)
   642   let fun printPairs (((G,_)::_,_)::_)  = Output.tracing (traceTerm ctxt G)
   636         | printPairs (([],(H,_)::_)::_) = Output.tracing (traceTerm thy H ^ "\t (Unsafe)")
   643         | printPairs (([],(H,_)::_)::_) = Output.tracing (traceTerm ctxt H ^ "\t (Unsafe)")
   637         | printPairs _                 = ()
   644         | printPairs _                 = ()
   638       fun printBrs (brs0 as {pairs, lits, lim, ...} :: brs) =
   645       fun printBrs (brs0 as {pairs, lits, lim, ...} :: brs) =
   639             (fullTrace := brs0 :: !fullTrace;
   646             (fullTrace := brs0 :: !fullTrace;
   640              List.app (fn _ => Output.tracing "+") brs;
   647              List.app (fn _ => Output.tracing "+") brs;
   641              Output.tracing (" [" ^ string_of_int lim ^ "] ");
   648              Output.tracing (" [" ^ string_of_int lim ^ "] ");
   645   end;
   652   end;
   646 
   653 
   647 fun traceMsg s = if !trace then writeln s else ();
   654 fun traceMsg s = if !trace then writeln s else ();
   648 
   655 
   649 (*Tracing: variables updated in the last branch operation?*)
   656 (*Tracing: variables updated in the last branch operation?*)
   650 fun traceVars (State {thy, ntrail, trail, ...}) ntrl =
   657 fun traceVars (State {ctxt, ntrail, trail, ...}) ntrl =
   651   if !trace then
   658   if !trace then
   652       (case !ntrail-ntrl of
   659       (case !ntrail-ntrl of
   653             0 => ()
   660             0 => ()
   654           | 1 => Output.tracing "\t1 variable UPDATED:"
   661           | 1 => Output.tracing "\t1 variable UPDATED:"
   655           | n => Output.tracing ("\t" ^ string_of_int n ^ " variables UPDATED:");
   662           | n => Output.tracing ("\t" ^ string_of_int n ^ " variables UPDATED:");
   656        (*display the instantiations themselves, though no variable names*)
   663        (*display the instantiations themselves, though no variable names*)
   657        List.app (fn v => Output.tracing ("   " ^ string_of thy 4 (the (!v))))
   664        List.app (fn v => Output.tracing ("   " ^ string_of ctxt 4 (the (!v))))
   658            (List.take(!trail, !ntrail-ntrl));
   665            (List.take(!trail, !ntrail-ntrl));
   659        writeln"")
   666        writeln "")
   660     else ();
   667     else ();
   661 
   668 
   662 (*Tracing: how many new branches are created?*)
   669 (*Tracing: how many new branches are created?*)
   663 fun traceNew prems =
   670 fun traceNew prems =
   664     if !trace then
   671     if !trace then
   738      | _             => raise DEST_EQ;
   745      | _             => raise DEST_EQ;
   739 
   746 
   740 (*Substitute through the branch if an equality goal (else raise DEST_EQ).
   747 (*Substitute through the branch if an equality goal (else raise DEST_EQ).
   741   Moves affected literals back into the branch, but it is not clear where
   748   Moves affected literals back into the branch, but it is not clear where
   742   they should go: this could make proofs fail.*)
   749   they should go: this could make proofs fail.*)
   743 fun equalSubst thy (G, {pairs, lits, vars, lim}) =
   750 fun equalSubst ctxt (G, {pairs, lits, vars, lim}) =
   744   let val (t,u) = orientGoal(dest_eq G)
   751   let val (t,u) = orientGoal(dest_eq G)
   745       val subst = subst_atomic (t,u)
   752       val subst = subst_atomic (t,u)
   746       fun subst2(G,md) = (subst G, md)
   753       fun subst2(G,md) = (subst G, md)
   747       (*substitute throughout list; extract affected formulae*)
   754       (*substitute throughout list; extract affected formulae*)
   748       fun subForm ((G,md), (changed, pairs)) =
   755       fun subForm ((G,md), (changed, pairs)) =
   761             in  if nlit aconv lit then (changed, nlit::nlits)
   768             in  if nlit aconv lit then (changed, nlit::nlits)
   762                                   else ((nlit,true)::changed, nlits)
   769                                   else ((nlit,true)::changed, nlits)
   763             end
   770             end
   764       val (changed, lits') = List.foldr subLit ([], []) lits
   771       val (changed, lits') = List.foldr subLit ([], []) lits
   765       val (changed', pairs') = List.foldr subFrame (changed, []) pairs
   772       val (changed', pairs') = List.foldr subFrame (changed, []) pairs
   766   in  if !trace then writeln ("Substituting " ^ traceTerm thy u ^
   773   in  if !trace then writeln ("Substituting " ^ traceTerm ctxt u ^
   767                               " for " ^ traceTerm thy t ^ " in branch" )
   774                               " for " ^ traceTerm ctxt t ^ " in branch" )
   768       else ();
   775       else ();
   769       {pairs = (changed',[])::pairs',   (*affected formulas, and others*)
   776       {pairs = (changed',[])::pairs',   (*affected formulas, and others*)
   770        lits  = lits',                   (*unaffected literals*)
   777        lits  = lits',                   (*unaffected literals*)
   771        vars  = vars,
   778        vars  = vars,
   772        lim   = lim}
   779        lim   = lim}
   798   end;
   805   end;
   799 
   806 
   800 (*Were there Skolem terms in the premise?  Must NOT chase Vars*)
   807 (*Were there Skolem terms in the premise?  Must NOT chase Vars*)
   801 fun hasSkolem (Skolem _)     = true
   808 fun hasSkolem (Skolem _)     = true
   802   | hasSkolem (Abs (_,body)) = hasSkolem body
   809   | hasSkolem (Abs (_,body)) = hasSkolem body
   803   | hasSkolem (f$t)          =  hasSkolem f orelse hasSkolem t
   810   | hasSkolem (f$t)          = hasSkolem f orelse hasSkolem t
   804   | hasSkolem _              = false;
   811   | hasSkolem _              = false;
   805 
   812 
   806 (*Attach the right "may duplicate" flag to new formulae: if they contain
   813 (*Attach the right "may duplicate" flag to new formulae: if they contain
   807   Skolem terms then allow duplication.*)
   814   Skolem terms then allow duplication.*)
   808 fun joinMd md [] = []
   815 fun joinMd md [] = []
   911 (*Tableau prover based on leanTaP.  Argument is a list of branches.  Each
   918 (*Tableau prover based on leanTaP.  Argument is a list of branches.  Each
   912   branch contains a list of unexpanded formulae, a list of literals, and a
   919   branch contains a list of unexpanded formulae, a list of literals, and a
   913   bound on unsafe expansions.
   920   bound on unsafe expansions.
   914  "start" is CPU time at start, for printing search time
   921  "start" is CPU time at start, for printing search time
   915 *)
   922 *)
   916 fun prove (state, start, ctxt, brs, cont) =
   923 fun prove (state, start, brs, cont) =
   917  let val State {thy, ntrail, nclosed, ntried, ...} = state;
   924  let val State {ctxt, ntrail, nclosed, ntried, ...} = state;
   918      val {safe0_netpair, safep_netpair, haz_netpair, ...} =
   925      val {safe0_netpair, safep_netpair, haz_netpair, ...} =
   919        Classical.rep_cs (Classical.claset_of ctxt);
   926        Classical.rep_cs (Classical.claset_of ctxt);
   920      val safeList = [safe0_netpair, safep_netpair]
   927      val safeList = [safe0_netpair, safep_netpair]
   921      and hazList  = [haz_netpair]
   928      and hazList  = [haz_netpair]
   922      fun prv (tacs, trs, choices, []) =
   929      fun prv (tacs, trs, choices, []) =
   930           let exception PRV (*backtrack to precisely this recursion!*)
   937           let exception PRV (*backtrack to precisely this recursion!*)
   931               val ntrl = !ntrail
   938               val ntrl = !ntrail
   932               val nbrs = length brs0
   939               val nbrs = length brs0
   933               val nxtVars = nextVars brs
   940               val nxtVars = nextVars brs
   934               val G = norm G
   941               val G = norm G
   935               val rules = netMkRules thy G vars safeList
   942               val rules = netMkRules ctxt G vars safeList
   936               (*Make a new branch, decrementing "lim" if instantiations occur*)
   943               (*Make a new branch, decrementing "lim" if instantiations occur*)
   937               fun newBr (vars',lim') prems =
   944               fun newBr (vars',lim') prems =
   938                   map (fn prem =>
   945                   map (fn prem =>
   939                        if (exists isGoal prem)
   946                        if (exists isGoal prem)
   940                        then {pairs = ((joinMd md prem, []) ::
   947                        then {pairs = ((joinMd md prem, []) ::
  1016           in tracing state brs0;
  1023           in tracing state brs0;
  1017              if lim<0 then (traceMsg "Limit reached.  "; backtrack choices)
  1024              if lim<0 then (traceMsg "Limit reached.  "; backtrack choices)
  1018              else
  1025              else
  1019              prv (Data.hyp_subst_tac (!trace) :: tacs,
  1026              prv (Data.hyp_subst_tac (!trace) :: tacs,
  1020                   brs0::trs,  choices,
  1027                   brs0::trs,  choices,
  1021                   equalSubst thy
  1028                   equalSubst ctxt
  1022                     (G, {pairs = (br,haz)::pairs,
  1029                     (G, {pairs = (br,haz)::pairs,
  1023                          lits  = lits, vars  = vars, lim   = lim})
  1030                          lits  = lits, vars  = vars, lim   = lim})
  1024                     :: brs)
  1031                     :: brs)
  1025              handle DEST_EQ =>   closeF lits
  1032              handle DEST_EQ =>   closeF lits
  1026               handle CLOSEF =>   closeFl ((br,haz)::pairs)
  1033               handle CLOSEF =>   closeFl ((br,haz)::pairs)
  1027                 handle CLOSEF => deeper rules
  1034                 handle CLOSEF => deeper rules
  1028                   handle NEWBRANCHES =>
  1035                   handle NEWBRANCHES =>
  1029                    (case netMkRules thy G vars hazList of
  1036                    (case netMkRules ctxt G vars hazList of
  1030                        [] => (*there are no plausible haz rules*)
  1037                        [] => (*there are no plausible haz rules*)
  1031                              (traceMsg "moving formula to literals";
  1038                              (traceMsg "moving formula to literals";
  1032                               prv (tacs, brs0::trs, choices,
  1039                               prv (tacs, brs0::trs, choices,
  1033                                    {pairs = (br,haz)::pairs,
  1040                                    {pairs = (br,haz)::pairs,
  1034                                     lits  = addLit(G,lits),
  1041                                     lits  = addLit(G,lits),
  1058                        lits, vars, lim} :: brs) =
  1065                        lits, vars, lim} :: brs) =
  1059              (*no safe steps possible at any level: apply a haz rule*)
  1066              (*no safe steps possible at any level: apply a haz rule*)
  1060           let exception PRV (*backtrack to precisely this recursion!*)
  1067           let exception PRV (*backtrack to precisely this recursion!*)
  1061               val H = norm H
  1068               val H = norm H
  1062               val ntrl = !ntrail
  1069               val ntrl = !ntrail
  1063               val rules = netMkRules thy H vars hazList
  1070               val rules = netMkRules ctxt H vars hazList
  1064               (*new premises of haz rules may NOT be duplicated*)
  1071               (*new premises of haz rules may NOT be duplicated*)
  1065               fun newPrem (vars,P,dup,lim') prem =
  1072               fun newPrem (vars,P,dup,lim') prem =
  1066                   let val Gs' = map (fn Q => (Q,false)) prem
  1073                   let val Gs' = map (fn Q => (Q,false)) prem
  1067                       and Hs' = if dup then Hs @ [(negOfGoal H, md)] else Hs
  1074                       and Hs' = if dup then Hs @ [(negOfGoal H, md)] else Hs
  1068                       and lits' = if (exists isGoal prem)
  1075                       and lits' = if (exists isGoal prem)
  1235 (*Tactic using tableau engine and proof reconstruction.
  1242 (*Tactic using tableau engine and proof reconstruction.
  1236  "start" is CPU time at start, for printing SEARCH time
  1243  "start" is CPU time at start, for printing SEARCH time
  1237         (also prints reconstruction time)
  1244         (also prints reconstruction time)
  1238  "lim" is depth limit.*)
  1245  "lim" is depth limit.*)
  1239 fun timing_depth_tac start ctxt lim i st0 =
  1246 fun timing_depth_tac start ctxt lim i st0 =
  1240   let val thy = Thm.theory_of_thm st0
  1247   let val thy = Proof_Context.theory_of ctxt
  1241       val state = initialize thy
  1248       val state = initialize ctxt
  1242       val st = st0
  1249       val st = st0
  1243         |> rotate_prems (i - 1)
  1250         |> rotate_prems (i - 1)
  1244         |> Conv.gconv_rule Object_Logic.atomize_prems 1
  1251         |> Conv.gconv_rule Object_Logic.atomize_prems 1
  1245       val skoprem = fromSubgoal thy (#1 (Logic.dest_implies (Thm.prop_of st)))
  1252       val skoprem = fromSubgoal thy (#1 (Logic.dest_implies (Thm.prop_of st)))
  1246       val hyps  = strip_imp_prems skoprem
  1253       val hyps  = strip_imp_prems skoprem
  1258                        then writeln (Timing.message (Timing.result start) ^ " for reconstruction")
  1265                        then writeln (Timing.message (Timing.result start) ^ " for reconstruction")
  1259                        else ();
  1266                        else ();
  1260                        Seq.make(fn()=> cell))
  1267                        Seq.make(fn()=> cell))
  1261           end
  1268           end
  1262   in
  1269   in
  1263     prove (state, start, ctxt, [initBranch (mkGoal concl :: hyps, lim)], cont)
  1270     prove (state, start, [initBranch (mkGoal concl :: hyps, lim)], cont)
  1264     |> Seq.map (rotate_prems (1 - i))
  1271     |> Seq.map (rotate_prems (1 - i))
  1265   end
  1272   end
  1266   handle PROVE => Seq.empty;
  1273   handle PROVE => Seq.empty;
  1267 
  1274 
  1268 (*Public version with fixed depth*)
  1275 (*Public version with fixed depth*)
  1269 fun depth_tac ctxt lim i st = timing_depth_tac (Timing.start ()) ctxt lim i st;
  1276 fun depth_tac ctxt lim i st = timing_depth_tac (Timing.start ()) ctxt lim i st;
  1270 
  1277 
  1271 val (depth_limit, setup_depth_limit) =
  1278 val (depth_limit, setup_depth_limit) =
  1272   Attrib.config_int_global @{binding blast_depth_limit} (K 20);
  1279   Attrib.config_int @{binding blast_depth_limit} (K 20);
  1273 
  1280 
  1274 fun blast_tac ctxt i st =
  1281 fun blast_tac ctxt i st =
  1275     ((DEEPEN (1, Config.get_global (Thm.theory_of_thm st) depth_limit)
  1282   ((DEEPEN (1, Config.get ctxt depth_limit) (timing_depth_tac (Timing.start ()) ctxt) 0) i
  1276         (timing_depth_tac (Timing.start ()) ctxt) 0) i
  1283     THEN flexflex_tac) st
  1277      THEN flexflex_tac) st
  1284   handle TRANS s => (if !trace then warning ("blast: " ^ s) else (); Seq.empty);
  1278     handle TRANS s =>
       
  1279       ((if !trace then warning ("blast: " ^ s) else ());
       
  1280        Seq.empty);
       
  1281 
  1285 
  1282 
  1286 
  1283 
  1287 
  1284 (*** For debugging: these apply the prover to a subgoal and return
  1288 (*** For debugging: these apply the prover to a subgoal and return
  1285      the resulting tactics, trace, etc.                            ***)
  1289      the resulting tactics, trace, etc.                            ***)
  1290 fun readGoal ctxt s =
  1294 fun readGoal ctxt s =
  1291   Syntax.read_prop ctxt s |> fromTerm (Proof_Context.theory_of ctxt) |> rand |> mkGoal;
  1295   Syntax.read_prop ctxt s |> fromTerm (Proof_Context.theory_of ctxt) |> rand |> mkGoal;
  1292 
  1296 
  1293 fun tryIt ctxt lim s =
  1297 fun tryIt ctxt lim s =
  1294   let
  1298   let
  1295     val thy = Proof_Context.theory_of ctxt;
  1299     val state as State {fullTrace = ft, ...} = initialize ctxt;
  1296     val state as State {fullTrace = ft, ...} = initialize thy;
  1300     val res = timeap prove (state, Timing.start (), [initBranch ([readGoal ctxt s], lim)], I);
  1297     val res = timeap prove
       
  1298       (state, Timing.start (), ctxt, [initBranch ([readGoal ctxt s], lim)], I);
       
  1299     val _ = fullTrace := !ft;
  1301     val _ = fullTrace := !ft;
  1300   in res end;
  1302   in res end;
  1301 
  1303 
  1302 
  1304 
  1303 (** method setup **)
  1305 (** method setup **)