aboutsummaryrefslogtreecommitdiffhomepage
path: root/library/lib.ml
diff options
context:
space:
mode:
authorGravatar letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7>2012-03-23 16:49:52 +0000
committerGravatar letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7>2012-03-23 16:49:52 +0000
commit85a16702cc7561f9a96eed9c2d707b9711130f09 (patch)
tree76acae0330eb6ddf125f48e7f1c5994d24b05296 /library/lib.ml
parent5c915de161fe453914525e5920d1a165bba8fa43 (diff)
A unified backtrack mechanism, with a basic "Show Script" as side-effect
Migrate the backtracking code from ide_slave.ml into a new backtrack.ml. In particular the history stack of commands that used to be there is now non-coqide-specific. ** Adapted commands ** - "Show Script": a basic functional version is restored (and the printing of scripts at Qed in coqtop). No indentation, one Coq command per line, based on the vernac_expr asts recorded in the history stack, printed via Ppvernac. - "Back n" : now mimics the backtrack of coqide: it goes n steps back (both commands and proofs), and maybe more if needed to avoid re-entering a proof (it outputs a warning in this case). - "BackTo n" : still try to go back to state n, but it also handles the proof state, and it may end on some state n' <= n if needed to avoid re-entering a proof. Ideally, it could someday be used by ProofGeneral instead of the complex Backtrack command. ** Compatible commands ** - "Backtrack" is left intact from compatibility with current ProofGeneral. We simply re-synchronize the command history stack after each Backtrack. - "Undo" is kept as a standard command, not a backtracking one, a bit like "Focus". Same for "Restart" and "Abort". All of these are now accepted in coqide (Undo simply triggers a warning). - Undocumented command "Undo To n" (counting from start of proof instead of from end) also keep its semantics, it is simply made compatible with the new stack mechanism. ** New restrictions ** We now forbid backtracking commands (Reset* / Back*) inside files when Load'ing or compiling, or inside VernacList/VernacTime/VernacFail. Too much work dealing with these situation that nobody uses. ** Internal details ** Internally, the command stack differs a bit from what was in Ide_slave earlier (which was inspired by lisp code in ProofGeneral). We now tag commands that are unreachable by a backtrack, due to some proof being finished, aborted, restarted, or partly Undo'ed. This induce a bit of bookkeeping during Qed/Abort/Restart/Undo, but then the backtracking code is straightforward: we simply search backward the first reachable state starting from the desired place. We don't depend anymore on the proof names (apart in the last proof block), It's more robust this way (think of re-entering a M.foo from an outside proof foo). Many internal clarifications in Lib, Vernac, etc. For instance "Reset Initial" is now just a BackTo 1, while "Reset foo" now calls (Lib.label_before_name "foo"), and performs a BackTo to the corresponding label. Concerning Coqide, we directly suppress the regular printing of goals via a flag in Vernacentries. This avoid relying on a classification of commands in Ide_slave as earlier. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@15085 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'library/lib.ml')
-rw-r--r--library/lib.ml83
1 files changed, 16 insertions, 67 deletions
diff --git a/library/lib.ml b/library/lib.ml
index 54087ce1c..40a427e49 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -573,44 +573,16 @@ let reset_to_gen test =
let reset_to sp = reset_to_gen (fun x -> fst x = sp)
-let reset_name (loc,id) =
- let (sp,_) =
- try
- find_entry_p (fun (sp,_) -> let (_,spi) = repr_path (fst sp) in id = spi)
- with Not_found ->
- user_err_loc (loc,"reset_name",pr_id id ++ str ": no such entry")
- in
- reset_to sp
-
-let is_mod_node = function
- | OpenedModule _ | OpenedSection _
- | ClosedModule _ | ClosedSection _ -> true
- | Leaf o -> let t = object_tag o in t = "MODULE" || t = "MODULE TYPE"
- || t = "MODULE ALIAS"
- | _ -> false
-
-(* Reset on a module or section name in order to bypass constants with
- the same name *)
-
-let reset_mod (loc,id) =
- let (_,before) =
- try
- find_split_p (fun (sp,node) ->
- let (_,spi) = repr_path (fst sp) in id = spi
- && is_mod_node node)
- with Not_found ->
- user_err_loc (loc,"reset_mod",pr_id id ++ str ": no such entry")
- in
- set_lib_stk before
+let first_command_label = 1
-let mark_end_of_command, current_command_label, set_command_label =
- let n = ref 0 in
+let mark_end_of_command, current_command_label, reset_command_label =
+ let n = ref (first_command_label-1) in
(fun () ->
match !lib_stk with
(_,Leaf o)::_ when object_tag o = "DOT" -> ()
| _ -> incr n;add_anonymous_leaf (inLabel !n)),
(fun () -> !n),
- (fun x -> n:=x)
+ (fun x -> n:=x;add_anonymous_leaf (inLabel x))
let is_label_n n x =
match x with
@@ -623,21 +595,21 @@ let is_label_n n x =
let reset_label n =
if n >= current_command_label () then
error "Cannot backtrack to the current label or a future one";
- let res = reset_to_gen (is_label_n n) in
+ reset_to_gen (is_label_n n);
(* forget state numbers after n only if reset succeeded *)
- set_command_label (n-1);
- res
+ reset_command_label n
-let rec back_stk n stk =
- match stk with
- (sp,Leaf o)::tail when object_tag o = "DOT" ->
- if n=0 then sp else back_stk (n-1) tail
- | _::tail -> back_stk n tail
- | [] -> error "Reached begin of command history"
+(** Search the last label registered before defining [id] *)
-let back n =
- reset_to (back_stk n !lib_stk);
- set_command_label (current_command_label () - n - 1)
+let label_before_name (loc,id) =
+ let found = ref false in
+ let search = function
+ | (_,Leaf o) when !found && object_tag o = "DOT" -> true
+ | (sp,_) -> (if id = snd (repr_path (fst sp)) then found := true); false
+ in
+ match find_entry_p search with
+ | (_,Leaf o) -> outLabel o
+ | _ -> raise Not_found
(* State and initialization. *)
@@ -657,29 +629,6 @@ let init () =
path_prefix := initial_prefix;
init_summaries()
-(* Initial state. *)
-
-let initial_state = ref None
-
-let declare_initial_state () =
- let name = add_anonymous_entry (FrozenState (freeze_summaries())) in
- initial_state := Some name
-
-let reset_initial () =
- match !initial_state with
- | None ->
- error "Resetting to the initial state is possible only interactively"
- | Some sp ->
- begin match split_lib sp with
- | (_,[_,FrozenState fs as hd],before) ->
- lib_stk := hd::before;
- recalc_path_prefix ();
- set_command_label 0;
- unfreeze_summaries fs
- | _ -> assert false
- end
-
-
(* Misc *)
let mp_of_global ref =