diff options
Diffstat (limited to 'proofs')
| -rw-r--r-- | proofs/logic_monad.ml | 36 | ||||
| -rw-r--r-- | proofs/logic_monad.mli | 16 | ||||
| -rw-r--r-- | proofs/pfedit.ml | 2 | ||||
| -rw-r--r-- | proofs/proof_global.mli | 2 | ||||
| -rw-r--r-- | proofs/proofview.ml | 55 | ||||
| -rw-r--r-- | proofs/proofview.mli | 15 | ||||
| -rw-r--r-- | proofs/refiner.ml | 19 | ||||
| -rw-r--r-- | proofs/refiner.mli | 2 | ||||
| -rw-r--r-- | proofs/tactic_debug.ml | 12 |
9 files changed, 85 insertions, 74 deletions
diff --git a/proofs/logic_monad.ml b/proofs/logic_monad.ml index 55eb434d38..5bad5f0f52 100644 --- a/proofs/logic_monad.ml +++ b/proofs/logic_monad.ml @@ -80,22 +80,23 @@ struct (** [Pervasives.raise]. Except that exceptions are wrapped with {!Exception}. *) - let raise = fun e -> (); fun () -> raise (Exception e) + let raise ?info = fun e -> (); fun () -> Exninfo.raise ?info (Exception e) (** [try ... with ...] but restricted to {!Exception}. *) let catch = fun s h -> (); fun () -> try s () with Exception e as src -> - let src = Errors.push src in - let e = Backtrace.app_backtrace ~src ~dst:e in - h e () + let (src, info) = Errors.push src in + h (e, info) () - let read_line = fun () -> try Pervasives.read_line () with e -> let e = Errors.push e in raise e () + let read_line = fun () -> try Pervasives.read_line () with e -> + let (e, info) = Errors.push e in raise ~info e () let print_char = fun c -> (); fun () -> print_char c (** {!Pp.pp}. The buffer is also flushed. *) - let print = fun s -> (); fun () -> try Pp.pp s; Pp.pp_flush () with e -> let e = Errors.push e in raise e () + let print = fun s -> (); fun () -> try Pp.pp s; Pp.pp_flush () with e -> + let (e, info) = Errors.push e in raise ~info e () let timeout = fun n t -> (); fun () -> Control.timeout n t (Exception Timeout) @@ -103,14 +104,13 @@ struct let make f = (); fun () -> try f () with e when Errors.noncritical e -> - let e = Errors.push e in - Pervasives.raise (Exception e) + let (e, info) = Errors.push e in + Util.iraise (Exception e, info) let run = fun x -> try x () with Exception e as src -> - let src = Errors.push src in - let e = Backtrace.app_backtrace ~src ~dst:e in - Pervasives.raise e + let (src, info) = Errors.push src in + Util.iraise (e, info) end (** {6 Logical layer} *) @@ -136,7 +136,7 @@ end (** A view type for the logical monad, which is a form of list, hence we can decompose it with as a list. *) type ('a, 'b) list_view = - | Nil of exn + | Nil of Exninfo.iexn | Cons of 'a * 'b module type Param = sig @@ -205,9 +205,11 @@ struct In that vision, [bind] is simply [concat_map] (though the cps version is significantly simpler), [plus] is concatenation, and [split] is pattern-matching. *) + type rich_exn = Exninfo.iexn + type 'a iolist = - { iolist : 'r. (exn -> 'r NonLogical.t) -> - ('a -> (exn -> 'r NonLogical.t) -> 'r NonLogical.t) -> + { iolist : 'r. (rich_exn -> 'r NonLogical.t) -> + ('a -> (rich_exn -> 'r NonLogical.t) -> 'r NonLogical.t) -> 'r NonLogical.t } include Monad.Make(struct @@ -277,7 +279,7 @@ struct let m = m s in { iolist = fun nil cons -> m.iolist nil (fun x _ -> cons x nil) } - let break (f : exn -> exn option) (m : 'a t) : 'a t = (); fun s -> + let break (f : rich_exn -> rich_exn option) (m : 'a t) : 'a t = (); fun s -> let m = m s in { iolist = fun nil cons -> m.iolist nil (fun x next -> cons x (fun e -> match f e with None -> next e | Some e -> nil e)) @@ -285,7 +287,7 @@ struct (** For [reflect] and [split] see the "Backtracking, Interleaving, and Terminating Monad Transformers" paper. *) - type 'a reified = ('a, exn -> 'a reified) list_view NonLogical.t + type 'a reified = ('a, rich_exn -> 'a reified) list_view NonLogical.t let rec reflect (m : 'a reified) : 'a iolist = { iolist = fun nil cons -> @@ -296,7 +298,7 @@ struct NonLogical.(m >>= next) } - let split (m : 'a t) : ('a, exn -> 'a t) list_view t = (); fun s -> + let split (m : 'a t) : ('a, rich_exn -> 'a t) list_view t = (); fun s -> let m = m s in let rnil e = NonLogical.return (Nil e) in let rcons p l = NonLogical.return (Cons (p, l)) in diff --git a/proofs/logic_monad.mli b/proofs/logic_monad.mli index 46cab18d25..0d05a2181e 100644 --- a/proofs/logic_monad.mli +++ b/proofs/logic_monad.mli @@ -60,9 +60,9 @@ module NonLogical : sig (** [Pervasives.raise]. Except that exceptions are wrapped with {!Exception}. *) - val raise : exn -> 'a t + val raise : ?info:Exninfo.info -> exn -> 'a t (** [try ... with ...] but restricted to {!Exception}. *) - val catch : 'a t -> (exn -> 'a t) -> 'a t + val catch : 'a t -> (Exninfo.iexn -> 'a t) -> 'a t val timeout : int -> 'a t -> 'a t (** Construct a monadified side-effect. Exceptions raised by the argument are @@ -98,7 +98,7 @@ end (** A view type for the logical monad, which is a form of list, hence we can decompose it with as a list. *) type ('a, 'b) list_view = -| Nil of exn +| Nil of Exninfo.iexn | Cons of 'a * 'b (** The monad is parametrised in the types of state, environment and @@ -140,17 +140,17 @@ module Logical (P:Param) : sig val local : P.e -> 'a t -> 'a t val update : (P.u -> P.u) -> unit t - val zero : exn -> 'a t - val plus : 'a t -> (exn -> 'a t) -> 'a t - val split : 'a t -> (('a,(exn->'a t)) list_view) t + val zero : Exninfo.iexn -> 'a t + val plus : 'a t -> (Exninfo.iexn -> 'a t) -> 'a t + val split : 'a t -> (('a,(Exninfo.iexn->'a t)) list_view) t val once : 'a t -> 'a t - val break : (exn -> exn option) -> 'a t -> 'a t + val break : (Exninfo.iexn -> Exninfo.iexn option) -> 'a t -> 'a t val lift : 'a NonLogical.t -> 'a t type 'a reified - val repr : 'a reified -> ('a, exn -> 'a reified) list_view NonLogical.t + val repr : 'a reified -> ('a, Exninfo.iexn -> 'a reified) list_view NonLogical.t val run : 'a t -> P.e -> P.s -> ('a * P.s * P.w * P.u) reified diff --git a/proofs/pfedit.ml b/proofs/pfedit.ml index 8e0f3accb2..f4747c0d01 100644 --- a/proofs/pfedit.ml +++ b/proofs/pfedit.ml @@ -142,7 +142,7 @@ let build_constant_by_tactic id ctx sign ?(goal_kind = Global, false, Proof Theo with reraise -> let reraise = Errors.push reraise in delete_current_proof (); - raise reraise + iraise reraise let build_by_tactic env ctx ?(poly=false) typ tac = let id = Id.of_string ("temporary_proof"^string_of_int (next())) in diff --git a/proofs/proof_global.mli b/proofs/proof_global.mli index 8dd7396868..1a13edf17e 100644 --- a/proofs/proof_global.mli +++ b/proofs/proof_global.mli @@ -91,7 +91,7 @@ val start_dependent_proof : (* Takes a function to add to the exceptions data relative to the state in which the proof was built *) -val close_proof : (exn -> exn) -> closed_proof +val close_proof : Future.fix_exn -> closed_proof (* Intermediate step necessary to delegate the future. * Both access the current proof state. The formes is supposed to be diff --git a/proofs/proofview.ml b/proofs/proofview.ml index 01bb41ad35..f1d10bbe55 100644 --- a/proofs/proofview.ml +++ b/proofs/proofview.ml @@ -230,7 +230,7 @@ let apply env t sp = let ans = Proof.repr (Proof.run t false (sp,env)) in let ans = Logic_monad.NonLogical.run ans in match ans with - | Nil e -> raise (TacticFailure e) + | Nil (e, info) -> iraise (TacticFailure e, info) | Cons ((r, (state, _), status, info), _) -> r, state, status, Trace.to_tree info @@ -260,7 +260,12 @@ module Monad = Proof (** [tclZERO e] fails with exception [e]. It has no success. *) -let tclZERO = Proof.zero +let tclZERO ?info e = + let info = match info with + | None -> Exninfo.null + | Some info -> info + in + Proof.zero (e, info) (** [tclOR t1 t2] behaves like [t1] as long as [t1] succeeds. Whenever the successes of [t1] have been depleted and it failed with [e], @@ -312,17 +317,17 @@ let tclEXACTLY_ONCE e t = let open Logic_monad in let open Proof in split t >>= function - | Nil e -> tclZERO e + | Nil (e, info) -> tclZERO ~info e | Cons (x,k) -> - Proof.split (k e) >>= function + Proof.split (k (e, Exninfo.null)) >>= function | Nil _ -> tclUNIT x | _ -> tclZERO MoreThanOneSuccess (** [tclCASE t] wraps the {!Proofview_monad.Logical.split} primitive. *) type 'a case = -| Fail of exn -| Next of 'a * (exn -> 'a tactic) +| Fail of iexn +| Next of 'a * (iexn -> 'a tactic) let tclCASE t = let open Logic_monad in let map = function @@ -745,12 +750,12 @@ let tclTIMEOUT n t = | Logic_monad.Nil e -> return (Util.Inr e) | Logic_monad.Cons (r, _) -> return (Util.Inl r) end - begin let open Logic_monad.NonLogical in function - | Logic_monad.Timeout -> return (Util.Inr Timeout) - | Logic_monad.TacticFailure e as src -> - let e = Backtrace.app_backtrace ~src ~dst:e in - return (Util.Inr e) - | e -> Logic_monad.NonLogical.raise e + begin let open Logic_monad.NonLogical in function (e, info) -> + match e with + | Logic_monad.Timeout -> return (Util.Inr (Timeout, info)) + | Logic_monad.TacticFailure e -> + return (Util.Inr (e, info)) + | e -> Logic_monad.NonLogical.raise ~info e end end >>= function | Util.Inl (res,s,m,i) -> @@ -758,7 +763,7 @@ let tclTIMEOUT n t = Proof.put m >> Proof.update (fun _ -> i) >> return res - | Util.Inr e -> tclZERO e + | Util.Inr (e, info) -> tclZERO ~info e let tclTIME s t = let pr_time t1 t2 n msg = @@ -775,11 +780,11 @@ let tclTIME s t = tclUNIT () >>= fun () -> let tstart = System.get_time() in Proof.split t >>= let open Logic_monad in function - | Nil e -> + | Nil (e, info) -> begin let tend = System.get_time() in pr_time tstart tend n "failure"; - tclZERO e + tclZERO ~info e end | Cons (x,k) -> let tend = System.get_time() in @@ -894,8 +899,8 @@ module Goal = struct let (gl, sigma) = nf_gmake env sigma goal in tclTHEN (Unsafe.tclEVARS sigma) (InfoL.tag (Info.DBranch) (f gl)) with e when catchable_exception e -> - let e = Errors.push e in - tclZERO e + let (e, info) = Errors.push e in + tclZERO ~info e end end @@ -917,8 +922,8 @@ module Goal = struct tclEVARMAP >>= fun sigma -> try f (gmake env sigma goal) with e when catchable_exception e -> - let e = Errors.push e in - tclZERO e + let (e, info) = Errors.push e in + tclZERO ~info e end end @@ -1082,8 +1087,8 @@ module V82 = struct InfoL.leaf (Info.Tactic (fun () -> Pp.str"<unknown>")) >> Pv.set { solution = evd; comb = sgs; } with e when catchable_exception e -> - let e = Errors.push e in - tclZERO e + let (e, info) = Errors.push e in + tclZERO ~info e (* normalises the evars in the goals, and stores the result in @@ -1141,9 +1146,8 @@ module V82 = struct let (_,final,_,_) = apply (GoalV82.env gls.Evd.sigma gls.Evd.it) t init in { Evd.sigma = final.solution ; it = final.comb } with Logic_monad.TacticFailure e as src -> - let src = Errors.push src in - let e = Backtrace.app_backtrace ~src ~dst:e in - raise e + let (_, info) = Errors.push src in + iraise (e, info) let put_status = Status.put @@ -1151,6 +1155,7 @@ module V82 = struct let wrap_exceptions f = try f () - with e when catchable_exception e -> let e = Errors.push e in tclZERO e + with e when catchable_exception e -> + let (e, info) = Errors.push e in tclZERO ~info e end diff --git a/proofs/proofview.mli b/proofs/proofview.mli index eb54ba3ae5..25f4547a91 100644 --- a/proofs/proofview.mli +++ b/proofs/proofview.mli @@ -12,6 +12,7 @@ ['a tactic] is the (abstract) type of tactics modifying the proof state and returning a value of type ['a]. *) +open Util open Term (** Main state of tactics *) @@ -172,24 +173,24 @@ module Monad : Monad.S with type +'a t = 'a tactic (** {7 Failure and backtracking} *) (** [tclZERO e] fails with exception [e]. It has no success. *) -val tclZERO : exn -> 'a tactic +val tclZERO : ?info:Exninfo.info -> exn -> 'a tactic (** [tclOR t1 t2] behaves like [t1] as long as [t1] succeeds. Whenever the successes of [t1] have been depleted and it failed with [e], then it behaves as [t2 e]. In other words, [tclOR] inserts a backtracking point. *) -val tclOR : 'a tactic -> (exn -> 'a tactic) -> 'a tactic +val tclOR : 'a tactic -> (iexn -> 'a tactic) -> 'a tactic (** [tclORELSE t1 t2] is equal to [t1] if [t1] has at least one success or [t2 e] if [t1] fails with [e]. It is analogous to [try/with] handler of exception in that it is not a backtracking point. *) -val tclORELSE : 'a tactic -> (exn -> 'a tactic) -> 'a tactic +val tclORELSE : 'a tactic -> (iexn -> 'a tactic) -> 'a tactic (** [tclIFCATCH a s f] is a generalisation of {!tclORELSE}: if [a] succeeds at least once then it behaves as [tclBIND a s] otherwise, if [a] fails with [e], then it behaves as [f e]. *) -val tclIFCATCH : 'a tactic -> ('a -> 'b tactic) -> (exn -> 'b tactic) -> 'b tactic +val tclIFCATCH : 'a tactic -> ('a -> 'b tactic) -> (iexn -> 'b tactic) -> 'b tactic (** [tclONCE t] behave like [t] except it has at most one success: [tclONCE t] stops after the first success of [t]. If [t] fails @@ -211,8 +212,8 @@ val tclEXACTLY_ONCE : exn -> 'a tactic -> 'a tactic continuation. It is the most general primitive to control backtracking. *) type 'a case = - | Fail of exn - | Next of 'a * (exn -> 'a tactic) + | Fail of iexn + | Next of 'a * (iexn -> 'a tactic) val tclCASE : 'a tactic -> 'a case tactic (** [tclBREAK p t] is a generalization of [tclONCE t]. Instead of @@ -220,7 +221,7 @@ val tclCASE : 'a tactic -> 'a case tactic failure with an exception [e] such that [p e = Some e'] is raised. At which point it drops the remaining successes, failing with [e']. [tclONCE t] is equivalent to [tclBREAK (fun e -> Some e) t]. *) -val tclBREAK : (exn -> exn option) -> 'a tactic -> 'a tactic +val tclBREAK : (iexn -> iexn option) -> 'a tactic -> 'a tactic (** {7 Focusing tactics} *) diff --git a/proofs/refiner.ml b/proofs/refiner.ml index 391a78b34a..e443ce0772 100644 --- a/proofs/refiner.ml +++ b/proofs/refiner.ml @@ -218,14 +218,14 @@ let tclSHOWHYPS (tac : tactic) (goal: Goal.goal Evd.sigma) rslt;; -let catch_failerror e = +let catch_failerror (e, info) = if catchable_exception e then Control.check_for_interrupt () else match e with | FailError (0,_) -> Control.check_for_interrupt () | FailError (lvl,s) -> - raise (Exninfo.copy e (FailError (lvl - 1, s))) - | e -> raise e + iraise (FailError (lvl - 1, s), info) + | e -> iraise (e, info) (** FIXME: do we need to add a [Errors.push] here? *) (* ORELSE0 t1 t2 tries to apply t1 and if it fails, applies t2 *) @@ -233,7 +233,8 @@ let tclORELSE0 t1 t2 g = try t1 g with (* Breakpoint *) - | e when Errors.noncritical e -> catch_failerror e; t2 g + | e when Errors.noncritical e -> + let e = Errors.push e in catch_failerror e; t2 g (* ORELSE t1 t2 tries to apply t1 and if it fails or does not progress, then applies t2 *) @@ -245,7 +246,8 @@ let tclORELSE t1 t2 = tclORELSE0 (tclPROGRESS t1) t2 let tclORELSE_THEN t1 t2then t2else gls = match try Some(tclPROGRESS t1 gls) - with e when Errors.noncritical e -> catch_failerror e; None + with e when Errors.noncritical e -> + let e = Errors.push e in catch_failerror e; None with | None -> t2else gls | Some sgl -> @@ -270,16 +272,17 @@ let ite_gen tcal tac_if continue tac_else gl= success:=true;result in let tac_else0 e gl= if !success then - raise e + iraise e else try tac_else gl with - e' when Errors.noncritical e' -> raise e in + e' when Errors.noncritical e' -> iraise e in try tcal tac_if0 continue gl with (* Breakpoint *) - | e when Errors.noncritical e -> catch_failerror e; tac_else0 e gl + | e when Errors.noncritical e -> + let e = Errors.push e in catch_failerror e; tac_else0 e gl (* Try the first tactic and, if it succeeds, continue with the second one, and if it fails, use the third one *) diff --git a/proofs/refiner.mli b/proofs/refiner.mli index ea1677f069..744843fc94 100644 --- a/proofs/refiner.mli +++ b/proofs/refiner.mli @@ -102,7 +102,7 @@ exception FailError of int * Pp.std_ppcmds Lazy.t (** Takes an exception and either raise it at the next level or do nothing. *) -val catch_failerror : exn -> unit +val catch_failerror : Exninfo.iexn -> unit val tclORELSE0 : tactic -> tactic -> tactic val tclORELSE : tactic -> tactic -> tactic diff --git a/proofs/tactic_debug.ml b/proofs/tactic_debug.ml index 80aaf9f2a9..b25f37b369 100644 --- a/proofs/tactic_debug.ml +++ b/proofs/tactic_debug.ml @@ -138,9 +138,9 @@ let rec prompt level = Proofview.NonLogical.print (fnl () ++ str "TcDebug (" ++ int level ++ str ") > ") >> let exit = (skip:=0) >> (skipped:=0) >> raise Sys.Break in Proofview.NonLogical.catch Proofview.NonLogical.read_line - begin function + begin function (e, info) -> match e with | End_of_file -> exit - | e -> raise e + | e -> raise ~info e end >>= fun inst -> match inst with @@ -154,9 +154,9 @@ let rec prompt level = end | _ -> Proofview.NonLogical.catch (run_com inst >> runtrue >> return (DebugOn (level+1))) - begin function + begin function (e, info) -> match e with | Failure _ | Invalid_argument _ -> prompt level - | e -> raise e + | e -> raise ~info e end end @@ -189,7 +189,7 @@ let debug_prompt lev tac f = (* What to execute *) Proofview.tclOR (f newlevel) - begin fun reraise -> + begin fun (reraise, info) -> Proofview.tclTHEN (Proofview.tclLIFT begin (skip:=0) >> (skipped:=0) >> @@ -197,7 +197,7 @@ let debug_prompt lev tac f = msg_tac_debug (str "Level " ++ int lev ++ str ": " ++ Pervasives.(!) explain_logic_error reraise) else return () end) - (Proofview.tclZERO reraise) + (Proofview.tclZERO ~info reraise) end let is_debug db = |
