aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ide/coq.ml127
-rw-r--r--ide/coq.mli30
-rw-r--r--ide/coqide.ml75
-rw-r--r--library/lib.ml15
-rw-r--r--library/lib.mli3
5 files changed, 135 insertions, 115 deletions
diff --git a/ide/coq.ml b/ide/coq.ml
index 4e0150918..17f80b0ec 100644
--- a/ide/coq.ml
+++ b/ide/coq.ml
@@ -271,6 +271,57 @@ let is_vernac_state_preserving_command com =
let is_vernac_tactic_command com =
List.mem SolveCommand (attribute_of_vernac_command com)
+type reset_mark =
+ | ResetToId of Names.identifier
+ | ResetToState of Libnames.object_name
+
+type reset_info =
+ | NoReset
+ | ResetAtDecl of reset_mark * bool ref
+ | ResetAtSegmentStart of Names.identifier * bool ref
+ | ResetAtFrozenState of Libnames.object_name * bool ref
+
+let reset_mark id = match Lib.has_top_frozen_state () with
+ | Some sp -> ResetToState sp
+ | None -> ResetToId id
+
+let compute_reset_info = function
+ | VernacBeginSection id
+ | VernacDefineModule (_,id, _, _, _)
+ | VernacDeclareModule (_,id, _, _)
+ | VernacDeclareModuleType (id, _, _) ->
+ ResetAtSegmentStart (snd id, ref true)
+
+ | VernacDefinition (_, (_,id), DefineBody _, _)
+ | VernacAssumption (_,_ ,(_,((_,id)::_,_))::_)
+ | VernacInductive (_, (((_,id),_,_,_),_) :: _) ->
+ ResetAtDecl (reset_mark id, ref true)
+
+ | VernacDefinition (_, (_,id), ProveBody _, _)
+ | VernacStartTheoremProof (_, [Some (_,id), _], _, _) ->
+ ResetAtDecl (reset_mark id, ref false)
+
+ | VernacEndProof _ -> NoReset
+ | _ -> match Lib.has_top_frozen_state () with
+ | Some sp -> ResetAtFrozenState (sp, ref true)
+ | None -> NoReset
+
+let reset_initial () =
+ prerr_endline "Reset initial called"; flush stderr;
+ Vernacentries.abort_refine Lib.reset_initial ()
+
+let reset_to = function
+ | ResetToId id ->
+ prerr_endline ("Reset called with "^(string_of_id id));
+ Vernacentries.abort_refine Lib.reset_name (Util.dummy_loc,id)
+ | ResetToState sp ->
+ Vernacentries.abort_refine Lib.reset_to_state sp
+
+let reset_to_mod id =
+ prerr_endline ("Reset called to Mod/Sect with "^(string_of_id id));
+ Vernacentries.abort_refine Lib.reset_mod (Util.dummy_loc,id)
+
+
let interp verbosely s =
prerr_endline "Starting interp...";
prerr_endline s;
@@ -291,10 +342,11 @@ let interp verbosely s =
if not (is_vernac_goal_printing_command vernac) then
(* Verbose if in small step forward and not a tactic *)
Flags.make_silent (not verbosely);
+ let reset_info = compute_reset_info vernac in
Vernac.raw_do_vernac (Pcoq.Gram.parsable (Stream.of_string s));
Flags.make_silent true;
prerr_endline ("...Done with interp of : "^s);
- last
+ reset_info,last
let interp_and_replace s =
let result = interp false s in
@@ -425,79 +477,6 @@ let print_no_goal () =
msg (Printer.pr_subgoals (Decl_mode.get_end_command pfts) sigma gls)
-type word_class = Normal | Kwd | Reserved
-
-
-let kwd = [(* "Compile";"Inductive";"Qed";"Type";"end";"Axiom";
- "Definition";"Load";"Quit";"Variable";"in";"Cases";"FixPoint";
- "Parameter";"Set";"of";"CoFixpoint";"Grammar";"Proof";"Syntax";
- "using";"CoInductive";"Hypothesis";"Prop";"Theorem";
- *)
- "Add"; "AddPath"; "Axiom"; "Chapter"; "CoFixpoint";
- "CoInductive"; "Defined"; "Definition";
- "End"; "Export"; "Fact"; "Fix"; "Fixpoint"; "Global"; "Grammar"; "Hint";
- "Hypothesis"; "Immediate"; "Implicits"; "Import"; "Inductive";
- "Infix"; "Lemma"; "Load"; "Local";
- "Match"; "Module"; "Module Type";
- "Mutual"; "Parameter"; "Print"; "Proof"; "Qed";
- "Record"; "Recursive"; "Remark"; "Require"; "Save"; "Scheme";
- "Section"; "Show"; "Syntactic"; "Syntax"; "Tactic"; "Theorem";
- "Unset"; "Variable"; "Variables";
-]
-
-let reserved = []
-
-module SHashtbl =
- Hashtbl.Make
- (struct
- type t = string
- let equal = ( = )
- let hash = Hashtbl.hash
- end)
-
-
-let word_tbl = SHashtbl.create 37
-let _ =
- List.iter (fun w -> SHashtbl.add word_tbl w Kwd) kwd;
- List.iter (fun w -> SHashtbl.add word_tbl w Reserved) reserved
-
-let word_class s =
- try
- SHashtbl.find word_tbl s
- with Not_found -> Normal
-
-type reset_info =
- | NoReset
- | ResetAtDecl of Names.identifier * bool ref
- | ResetAtSegmentStart of Names.identifier * bool ref
-
-let compute_reset_info = function
- | VernacBeginSection id
- | VernacDefineModule (_,id, _, _, _)
- | VernacDeclareModule (_,id, _, _)
- | VernacDeclareModuleType (id, _, _) ->
- ResetAtSegmentStart (snd id, ref true)
- | VernacDefinition (_, (_,id), DefineBody _, _)
- | VernacAssumption (_,_ ,(_,((_,id)::_,_))::_)
- | VernacInductive (_, (((_,id),_,_,_),_) :: _) ->
- ResetAtDecl (id, ref true)
- | VernacDefinition (_, (_,id), ProveBody _, _)
- | VernacStartTheoremProof (_, [Some (_,id), _], _, _) ->
- ResetAtDecl (id, ref false)
- | _ -> NoReset
-
-let reset_initial () =
- prerr_endline "Reset initial called"; flush stderr;
- Vernacentries.abort_refine Lib.reset_initial ()
-
-let reset_to id =
- prerr_endline ("Reset called with "^(string_of_id id));
- Vernacentries.abort_refine Lib.reset_name (Util.dummy_loc,id)
-let reset_to_mod id =
- prerr_endline ("Reset called to Mod/Sect with "^(string_of_id id));
- Vernacentries.abort_refine Lib.reset_mod (Util.dummy_loc,id)
-
-
let hyp_menu (env, sigma, ((coqident,ident),_,ast),(s,pr_ast)) =
[("clear "^ident),("clear "^ident^".");
diff --git a/ide/coq.mli b/ide/coq.mli
index 9c8e27320..5ded2b573 100644
--- a/ide/coq.mli
+++ b/ide/coq.mli
@@ -15,10 +15,26 @@ open Evd
val version : unit -> string
+type reset_mark =
+ | ResetToId of Names.identifier
+ | ResetToState of Libnames.object_name
+
+type reset_info =
+ | NoReset
+ | ResetAtDecl of reset_mark * bool ref
+ | ResetAtSegmentStart of Names.identifier * bool ref
+ | ResetAtFrozenState of Libnames.object_name * bool ref
+
+val compute_reset_info : Vernacexpr.vernac_expr -> reset_info
+val reset_initial : unit -> unit
+val reset_to : reset_mark -> unit
+val reset_to_mod : identifier -> unit
+
val init : unit -> string list
-val interp : bool -> string -> Util.loc * Vernacexpr.vernac_expr
+val interp : bool -> string -> reset_info * (Util.loc * Vernacexpr.vernac_expr)
val interp_last : Util.loc * Vernacexpr.vernac_expr -> unit
-val interp_and_replace : string -> (Util.loc * Vernacexpr.vernac_expr) * string
+val interp_and_replace : string ->
+ (reset_info * (Util.loc * Vernacexpr.vernac_expr)) * string
val is_vernac_tactic_command : Vernacexpr.vernac_expr -> bool
val is_vernac_state_preserving_command : Vernacexpr.vernac_expr -> bool
@@ -42,16 +58,6 @@ val print_no_goal : unit -> string
val process_exn : exn -> string*(Util.loc option)
-type reset_info =
- | NoReset
- | ResetAtDecl of Names.identifier * bool ref
- | ResetAtSegmentStart of Names.identifier * bool ref
-
-val compute_reset_info : Vernacexpr.vernac_expr -> reset_info
-val reset_initial : unit -> unit
-val reset_to : identifier -> unit
-val reset_to_mod : identifier -> unit
-
val hyp_menu : hyp -> (string * string) list
val concl_menu : concl -> (string * string) list
diff --git a/ide/coqide.ml b/ide/coqide.ml
index 7cfeb694d..4e5223b02 100644
--- a/ide/coqide.ml
+++ b/ide/coqide.ml
@@ -159,7 +159,7 @@ object('self)
method activate : unit -> unit
method active_keypress_handler : GdkEvent.Key.t -> bool
method backtrack_to : GText.iter -> unit
- method backtrack_to_no_lock : GText.iter -> Names.identifier option -> unit
+ method backtrack_to_no_lock : GText.iter -> reset_mark option -> unit
method clear_message : unit
method deactivate : unit -> unit
method disconnected_keypress_handler : GdkEvent.Key.t -> bool
@@ -182,7 +182,8 @@ object('self)
method reset_initial : unit
method send_to_coq :
bool -> bool -> string ->
- bool -> bool -> bool -> (bool*(Util.loc * Vernacexpr.vernac_expr)) option
+ bool -> bool -> bool ->
+ (bool*(reset_info*(Util.loc * Vernacexpr.vernac_expr))) option
method set_message : string -> unit
method show_pm_goal : unit
method show_goals : unit
@@ -502,6 +503,9 @@ let is_empty () = Stack.is_empty processed_stack
let update_on_end_of_proof () =
let lookup_lemma = function
+ | { reset_info = ResetAtFrozenState (_, r) } ->
+ prerr_endline "Toggling Frozen State info to false";
+ r := false
| { reset_info = ResetAtDecl (_, r) } ->
if not !r then begin
prerr_endline "Toggling Reset info to true";
@@ -521,15 +525,16 @@ let update_on_end_of_segment id =
| { reset_info = ResetAtSegmentStart (id', r) } when id = id' -> raise Exit
| { reset_info = ResetAtSegmentStart (_, r) } -> r := false
| { reset_info = ResetAtDecl (_, r) } -> r := false
+ | { reset_info = ResetAtFrozenState (_, r) } -> r := false
| _ -> ()
in
try Stack.iter lookup_section processed_stack with Exit -> ()
-let push_phrase start_of_phrase_mark end_of_phrase_mark ast =
+let push_phrase reset_info start_of_phrase_mark end_of_phrase_mark ast =
let x = {start = start_of_phrase_mark;
stop = end_of_phrase_mark;
ast = ast;
- reset_info = Coq.compute_reset_info (snd ast)
+ reset_info = reset_info
} in
begin
match snd ast with
@@ -540,8 +545,8 @@ let push_phrase start_of_phrase_mark end_of_phrase_mark ast =
push x
-let repush_phrase x =
- let x = { x with reset_info = Coq.compute_reset_info (snd x.ast) } in
+let repush_phrase reset_info x =
+ let x = { x with reset_info = reset_info } in
begin
match snd x.ast with
| VernacEndProof (Proved (_, None)) -> update_on_end_of_proof ()
@@ -1143,7 +1148,7 @@ object(self)
input_view#set_editable true;
!pop_info ();
end in
- let mark_processed complete (start,stop) ast =
+ let mark_processed reset_info complete (start,stop) ast =
let b = input_buffer in
b#move_mark ~where:stop (`NAME "start_of_input");
b#apply_tag_by_name
@@ -1155,7 +1160,8 @@ object(self)
end;
let start_of_phrase_mark = `MARK (b#create_mark start) in
let end_of_phrase_mark = `MARK (b#create_mark stop) in
- push_phrase
+ push_phrase
+ reset_info
start_of_phrase_mark
end_of_phrase_mark ast;
if display_goals then self#show_goals;
@@ -1165,14 +1171,14 @@ object(self)
None -> false
| Some (loc,phrase) ->
(match self#send_to_coq verbosely false phrase true true true with
- | Some (complete,ast) ->
- sync (mark_processed complete) loc ast; true
+ | Some (complete,(reset_info,ast)) ->
+ sync (mark_processed reset_info complete) loc ast; true
| None -> sync remove_tag loc; false)
end
method insert_this_phrase_on_success
show_output show_msg localize coqphrase insertphrase =
- let mark_processed complete ast =
+ let mark_processed reset_info complete ast =
let stop = self#get_start_of_input in
if stop#starts_line then
input_buffer#insert ~iter:stop insertphrase
@@ -1185,7 +1191,7 @@ object(self)
input_buffer#place_cursor stop;
let start_of_phrase_mark = `MARK (input_buffer#create_mark start) in
let end_of_phrase_mark = `MARK (input_buffer#create_mark stop) in
- push_phrase start_of_phrase_mark end_of_phrase_mark ast;
+ push_phrase reset_info start_of_phrase_mark end_of_phrase_mark ast;
self#show_goals;
(*Auto insert save on success...
try (match Coq.get_current_goals () with
@@ -1206,13 +1212,15 @@ object(self)
`MARK (input_buffer#create_mark start) in
let end_of_phrase_mark =
`MARK (input_buffer#create_mark stop) in
- push_phrase start_of_phrase_mark end_of_phrase_mark ast
+ push_phrase
+ reset_info start_of_phrase_mark end_of_phrase_mark ast
end
| None -> ())
| _ -> ())
with _ -> ()*) in
match self#send_to_coq false false coqphrase show_output show_msg localize with
- | Some (complete,ast) -> sync (mark_processed complete) ast; true
+ | Some (complete,(reset_info,ast)) ->
+ sync (mark_processed reset_info complete) ast; true
| None ->
sync
(fun _ -> self#insert_message ("Unsuccessfully tried: "^coqphrase))
@@ -1284,28 +1292,35 @@ object(self)
begin match t.reset_info with
| ResetAtSegmentStart (id, {contents=true}) ->
reset_to_mod id
- | ResetAtDecl (id, {contents=true}) ->
+ | ResetAtFrozenState (sp, {contents=true}) ->
if inproof then
- (prerr_endline ("Skipping "^Names.string_of_id id);
- synchro (Some id) inproof)
+ synchro (Some (ResetToState sp)) inproof
else
- reset_to (Option.default id oldest_decl_in_middle_of_proof)
- | ResetAtDecl (id, {contents=false}) ->
+ reset_to (ResetToState sp)
+ | ResetAtDecl (mark, {contents=true}) ->
+ if inproof then
+ synchro (Some mark) inproof
+ else
+ reset_to
+ (Option.default mark oldest_decl_in_middle_of_proof)
+ | ResetAtDecl (mark, {contents=false}) ->
if inproof then
if oldest_decl_in_middle_of_proof = None then
- synchro None false
+ match mark with
+ | ResetToId _ -> synchro None false
+ | ResetToState _ -> reset_to mark
else
(* reset oldest decl found before theorem started what *)
(* resets back just before the proof was started *)
reset_to (Option.get oldest_decl_in_middle_of_proof)
else
- (prerr_endline ("Skipping "^Names.string_of_id id);
- synchro (Some id) inproof)
+ synchro (Some mark) inproof
| _ ->
synchro oldest_decl_in_middle_of_proof inproof
end;
+ let reset_info = Coq.compute_reset_info (snd t.ast) in
interp_last t.ast;
- repush_phrase t
+ repush_phrase reset_info t
end
in
let add_undo t = match t with | Some n -> Some (succ n) | None -> None
@@ -1400,23 +1415,25 @@ Please restart and report NOW.";
in
begin match last_command with
| {ast=_,com} when is_vernac_tactic_command com ->
-prerr_endline "TACT";
begin
try Pfedit.undo 1; ignore (pop ()); sync update_input ()
with _ -> self#backtrack_to_no_lock start None
end
+ | {reset_info=ResetAtFrozenState (sp, {contents=true})} ->
+ ignore (pop ());
+ Lib.reset_to_state sp;
+ sync update_input ()
| {reset_info=ResetAtSegmentStart (id, {contents=true})} ->
-prerr_endline "SEG";
ignore (pop ());
reset_to_mod id;
sync update_input ()
- | {reset_info=ResetAtDecl (id, {contents=true})} ->
+ | {reset_info=ResetAtDecl (mark, {contents=true})} ->
if Pfedit.refining () then
- self#backtrack_to_no_lock start (Some id)
+ self#backtrack_to_no_lock start (Some mark)
else
- (ignore (pop ()); reset_to id; sync update_input ())
- | {reset_info=ResetAtDecl (id,{contents=false})} ->
+ (ignore (pop ()); reset_to mark; sync update_input ())
+ | {reset_info=ResetAtDecl (_, {contents=false})} ->
ignore (pop ());
(try
Pfedit.delete_current_proof ()
diff --git a/library/lib.ml b/library/lib.ml
index ae1a41ca1..5e22c4d22 100644
--- a/library/lib.ml
+++ b/library/lib.ml
@@ -584,6 +584,13 @@ let recache_context ctx =
let is_frozen_state = function (_,FrozenState _) -> true | _ -> false
+let has_top_frozen_state () =
+ let rec aux = function
+ | (sp, FrozenState _)::_ -> Some sp
+ | (sp, Leaf o)::t when object_tag o = "DOT" -> aux t
+ | _ -> None
+ in aux !lib_stk
+
let set_lib_stk new_lib_stk =
lib_stk := new_lib_stk;
recalc_path_prefix ();
@@ -603,6 +610,14 @@ let reset_to_gen test =
let reset_to sp = reset_to_gen (fun x -> (fst x) = sp)
+let reset_to_state sp =
+ let (_,eq,before) = split_lib sp in
+ (* if eq a frozen state, we'll reset to it *)
+ match eq with
+ | [_,FrozenState f] -> lib_stk := eq@before; unfreeze_summaries f
+ | _ -> error "Not a frozen state"
+
+
(* LEM: TODO
* We will need to muck with frozen states in after, too!
* Not only FrozenState, but also those embedded in Opened(Section|Module|Modtype)
diff --git a/library/lib.mli b/library/lib.mli
index da8ace048..f3fa9a4b3 100644
--- a/library/lib.mli
+++ b/library/lib.mli
@@ -145,6 +145,9 @@ val reset_to : object_name -> unit
val reset_name : identifier located -> unit
val remove_name : identifier located -> unit
val reset_mod : identifier located -> unit
+val reset_to_state : object_name -> unit
+
+val has_top_frozen_state : unit -> object_name option
(* [back n] resets to the place corresponding to the $n$-th call of
[mark_end_of_command] (counting backwards) *)