removed slightly odd Isar_Document.init;
authorwenzelm
Tue, 29 Dec 2009 20:30:40 +0100
changeset 34206 c29264a16ad8
parent 34205 f69cd974bc4e
child 34207 88300168baf8
removed slightly odd Isar_Document.init; simplified begin_document: associate empty command/state with no_id, which is implicit start; replaced make_id by create_id (cf. Scala version); eliminated CRITICAL/Unsynchronized.ref in favour of Synchronized.var; tuned;
src/Pure/Isar/isar_document.ML
src/Pure/System/isabelle_process.ML
--- a/src/Pure/Isar/isar_document.ML	Tue Dec 29 16:20:39 2009 +0100
+++ b/src/Pure/Isar/isar_document.ML	Tue Dec 29 20:30:40 2009 +0100
@@ -9,11 +9,12 @@
   type state_id = string
   type command_id = string
   type document_id = string
+  val no_id: string
+  val create_id: unit -> string
   val define_command: command_id -> Toplevel.transition -> unit
   val begin_document: document_id -> Path.T -> unit
   val end_document: document_id -> unit
   val edit_document: document_id -> document_id -> (command_id * command_id option) list -> unit
-  val init: unit -> unit
 end;
 
 structure Isar_Document: ISAR_DOCUMENT =
@@ -25,10 +26,20 @@
 type command_id = string;
 type document_id = string;
 
-fun make_id () = "i" ^ serial_string ();
+val no_id = "";
+
+local
+  val id_count = Synchronized.var "id" 0;
+in
+  fun create_id () =
+    Synchronized.change_result id_count
+      (fn i =>
+        let val i' = i + 1
+        in ("i" ^ string_of_int i', i') end);
+end;
 
 fun err_dup kind id = error ("Duplicate " ^ kind ^ ": " ^ quote id);
-fun err_undef kind id = error ("Unknown " ^ kind ^ ": " ^ quote id);
+fun err_undef kind id = error ("Undefined " ^ kind ^ ": " ^ quote id);
 
 
 
@@ -57,16 +68,15 @@
 (* document *)
 
 datatype document = Document of
- {dir: Path.T,                    (*master directory*)
-  name: string,                   (*theory name*)
-  start: command_id,              (*empty start command*)
-  entries: entry Symtab.table};   (*unique command entries indexed by command_id*)
+ {dir: Path.T,                   (*master directory*)
+  name: string,                  (*theory name*)
+  entries: entry Symtab.table};  (*unique command entries indexed by command_id, start with no_id*)
 
-fun make_document dir name start entries =
-  Document {dir = dir, name = name, start = start, entries = entries};
+fun make_document dir name entries =
+  Document {dir = dir, name = name, entries = entries};
 
-fun map_entries f (Document {dir, name, start, entries}) =
-  make_document dir name start (f entries);
+fun map_entries f (Document {dir, name, entries}) =
+  make_document dir name (f entries);
 
 
 (* iterate entries *)
@@ -79,13 +89,13 @@
           in apply (#next entry) (f (id, entry) x) end;
   in if Symtab.defined entries id0 then apply (SOME id0) else I end;
 
-fun first_entry P (Document {start, entries, ...}) =
+fun first_entry P (Document {entries, ...}) =
   let
     fun first _ NONE = NONE
       | first prev (SOME id) =
           let val entry = the_entry entries id
           in if P (id, entry) then SOME (prev, id, entry) else first (SOME id) (#next entry) end;
-  in first NONE (SOME start) end;
+  in first NONE (SOME no_id) end;
 
 
 (* modify entries *)
@@ -112,81 +122,85 @@
 
 (** global configuration **)
 
+(* states *)
+
+val empty_state = Future.value (SOME Toplevel.toplevel);
+
 local
-  val global_states = Unsynchronized.ref (Symtab.empty: Toplevel.state option future Symtab.table);
-  val global_commands = Unsynchronized.ref (Symtab.empty: Toplevel.transition Symtab.table);
-  val global_documents = Unsynchronized.ref (Symtab.empty: document Symtab.table);
+
+val global_states =
+  Synchronized.var "global_states" (Symtab.make [(no_id, empty_state)]);
+
 in
 
-fun change_states f = NAMED_CRITICAL "Isar" (fn () => Unsynchronized.change global_states f);
-fun get_states () = ! global_states;
-
-fun change_commands f = NAMED_CRITICAL "Isar" (fn () => Unsynchronized.change global_commands f);
-fun get_commands () = ! global_commands;
+fun define_state (id: state_id) =
+  Synchronized.change global_states (Symtab.update_new (id, empty_state))
+    handle Symtab.DUP dup => err_dup "state" dup;
 
-fun change_documents f = NAMED_CRITICAL "Isar" (fn () => Unsynchronized.change global_documents f);
-fun get_documents () = ! global_documents;
+fun put_state (id: state_id) state =
+  Synchronized.change global_states (Symtab.update (id, state));
 
-fun init () = NAMED_CRITICAL "Isar" (fn () =>
- (global_states := Symtab.empty;
-  global_commands := Symtab.empty;
-  global_documents := Symtab.empty));
+fun the_state (id: state_id) =
+  (case Symtab.lookup (Synchronized.value global_states) id of
+    NONE => err_undef "state" id
+  | SOME state => state);
 
 end;
 
 
-(* state *)
-
-val empty_state = Future.value (SOME Toplevel.toplevel);
+(* commands *)
 
-fun define_state (id: state_id) =
-  change_states (Symtab.update_new (id, empty_state))
-    handle Symtab.DUP dup => err_dup "state" dup;
+local
 
-fun put_state (id: state_id) state = change_states (Symtab.update (id, state));
+val global_commands =
+  Synchronized.var "global_commands" (Symtab.make [(no_id, Toplevel.empty)]);
 
-fun the_state (id: state_id) =
-  (case Symtab.lookup (get_states ()) id of
-    NONE => err_undef "state" id
-  | SOME state => state);
-
-
-(* command *)
+in
 
 fun define_command id tr =
-  change_commands (Symtab.update_new (id, Toplevel.put_id id tr))
+  Synchronized.change global_commands (Symtab.update_new (id, Toplevel.put_id id tr))
     handle Symtab.DUP dup => err_dup "command" dup;
 
 fun the_command (id: command_id) =
-  (case Symtab.lookup (get_commands ()) id of
+  (case Symtab.lookup (Synchronized.value global_commands) id of
     NONE => err_undef "command" id
   | SOME tr => tr);
 
+end;
 
-(* document *)
+
+(* documents *)
+
+local
+
+val global_documents =
+  Synchronized.var "global_documents" (Symtab.empty: document Symtab.table);
+
+in
 
 fun define_document (id: document_id) document =
-  change_documents (Symtab.update_new (id, document))
+  Synchronized.change global_documents (Symtab.update_new (id, document))
     handle Symtab.DUP dup => err_dup "document" dup;
 
 fun the_document (id: document_id) =
-  (case Symtab.lookup (get_documents ()) id of
+  (case Symtab.lookup (Synchronized.value global_documents) id of
     NONE => err_undef "document" id
   | SOME document => document);
 
+end;
+
 
 
 (** main operations **)
 
 (* begin/end document *)
 
+val no_entries = Symtab.make [(no_id, make_entry NONE (SOME no_id))];
+
 fun begin_document (id: document_id) path =
   let
     val (dir, name) = ThyLoad.split_thy_path path;
-    val _ = define_command id Toplevel.empty;
-    val _ = define_state id;
-    val entries = Symtab.make [(id, make_entry NONE (SOME id))];
-    val _ = define_document id (make_document dir name id entries);
+    val _ = define_document id (make_document dir name no_entries);
   in () end;
 
 fun end_document (id: document_id) =
@@ -217,7 +231,7 @@
 
 fun new_state name (id, _) (state_id, updates) =
   let
-    val state_id' = make_id ();
+    val state_id' = create_id ();
     val _ = define_state state_id';
     val tr = Toplevel.put_id state_id' (the_command id);
     fun make_state' () =
--- a/src/Pure/System/isabelle_process.ML	Tue Dec 29 16:20:39 2009 +0100
+++ b/src/Pure/System/isabelle_process.ML	Tue Dec 29 20:30:40 2009 +0100
@@ -95,7 +95,6 @@
  (Unsynchronized.change print_mode (update (op =) isabelle_processN);
   setup_channels out |> init_message;
   OuterKeyword.report ();
-  Isar_Document.init ();
   Output.status (Markup.markup Markup.ready "");
   Isar.toplevel_loop {init = true, welcome = false, sync = true, secure = true});