diff options
| author | aspiwack | 2013-11-04 18:08:48 +0000 |
|---|---|---|
| committer | aspiwack | 2013-11-04 18:08:48 +0000 |
| commit | 84b30df7b5ef9479a89de322bceee5619405d195 (patch) | |
| tree | d9a4a351e60041fb5a989379cc23e41ad0ca0142 | |
| parent | 5f4a61935e048a8e4490f5610e551d8844a373c4 (diff) | |
Fix Tacticals.New.tclREPEAT_MAiN: does not fail badly when every goal was solved.
This made "autorewrite using tac" fail.
Spotted in CoLoR and Demos.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@17059 85f007b7-540e-0410-9357-904b9bb8a0f7
| -rw-r--r-- | proofs/proofview.ml | 16 | ||||
| -rw-r--r-- | proofs/proofview.mli | 13 | ||||
| -rw-r--r-- | tactics/tacticals.ml | 2 |
3 files changed, 23 insertions, 8 deletions
diff --git a/proofs/proofview.ml b/proofs/proofview.ml index bbeed4ad10..950ee8a3cd 100644 --- a/proofs/proofview.ml +++ b/proofs/proofview.ml @@ -277,8 +277,12 @@ let tclEXACTLY_ONCE e t = (* Focuses a tactic at a range of subgoals, found by their indices. *) -(* arnaud: bug if 0 goals ! *) -let tclFOCUS i j t = +exception NoSuchGoals +let _ = Errors.register_handler begin function + | NoSuchGoals -> Errors.error "No such goals." + | _ -> raise Errors.Unhandled +end +let tclFOCUS_gen nosuchgoal i j t = (* spiwack: convenience notations, waiting for ocaml 3.12 *) let (>>=) = Proof.bind in let (>>) = Proof.seq in @@ -290,10 +294,10 @@ let tclFOCUS i j t = Proof.get >>= fun next -> Proof.set (unfocus context next) >> Proof.ret result - with e when Errors.noncritical e -> - (* spiwack: a priori the only possible exceptions are that of focus, - of course I haven't made them algebraic yet. *) - tclZERO e + with IndexOutOfRange -> nosuchgoal + +let tclFOCUS i j t = tclFOCUS_gen (tclZERO NoSuchGoals) i j t +let tclTRYFOCUS i j t = tclFOCUS_gen (tclUNIT ()) i j t (* Dispatch tacticals are used to apply a different tactic to each goal under diff --git a/proofs/proofview.mli b/proofs/proofview.mli index 8bd7b8a283..b9251fffbb 100644 --- a/proofs/proofview.mli +++ b/proofs/proofview.mli @@ -167,9 +167,20 @@ val tclONCE : 'a tactic -> 'a tactic val tclEXACTLY_ONCE : exn -> 'a tactic -> 'a tactic (* Focuses a tactic at a range of subgoals, found by their indices. - The other goals are restored to the focus when the tactic is done. *) + The other goals are restored to the focus when the tactic is done. + + If the specified range doesn't correspond to existing goals, fails + with [NoSuchGoals]. *) +exception NoSuchGoals val tclFOCUS : int -> int -> 'a tactic -> 'a tactic +(* Focuses a tactic at a range of subgoals, found by their indices. + The other goals are restored to the focus when the tactic is done. + + If the specified range doesn't correspond to existing goals, behaves + like [tclUNIT ()]. *) +val tclTRYFOCUS : int -> int -> unit tactic -> unit tactic + (* Dispatch tacticals are used to apply a different tactic to each goal under consideration. They come in two flavours: [tclDISPATCH] takes a list of [unit tactic]-s and build a [unit tactic]. diff --git a/tactics/tacticals.ml b/tactics/tacticals.ml index f815830ca2..639c4c97bc 100644 --- a/tactics/tacticals.ml +++ b/tactics/tacticals.ml @@ -495,7 +495,7 @@ module New = struct tclREPEAT0 (tclPROGRESS t) let rec tclREPEAT_MAIN0 t = tclIFCATCH t - (fun () -> tclFOCUS 1 1 (tclREPEAT_MAIN0 t)) + (fun () -> tclTRYFOCUS 1 1 (tclREPEAT_MAIN0 t)) (fun e -> catch_failerror e <*> tclUNIT ()) let tclREPEAT_MAIN t = tclREPEAT_MAIN0 (tclPROGRESS t) |
