105 {empty: Object.T, |
105 {empty: Object.T, |
106 copy: Object.T -> Object.T, |
106 copy: Object.T -> Object.T, |
107 extend: Object.T -> Object.T, |
107 extend: Object.T -> Object.T, |
108 merge: Pretty.pp -> Object.T * Object.T -> Object.T}; |
108 merge: Pretty.pp -> Object.T * Object.T -> Object.T}; |
109 |
109 |
110 val kinds = ref (Datatab.empty: kind Datatab.table); |
110 val kinds = Unsynchronized.ref (Datatab.empty: kind Datatab.table); |
111 |
111 |
112 fun invoke f k = |
112 fun invoke f k = |
113 (case Datatab.lookup (! kinds) k of |
113 (case Datatab.lookup (! kinds) k of |
114 SOME kind => f kind |
114 SOME kind => f kind |
115 | NONE => sys_error "Invalid theory data identifier"); |
115 | NONE => sys_error "Invalid theory data identifier"); |
123 |
123 |
124 fun declare_theory_data empty copy extend merge = |
124 fun declare_theory_data empty copy extend merge = |
125 let |
125 let |
126 val k = serial (); |
126 val k = serial (); |
127 val kind = {empty = empty, copy = copy, extend = extend, merge = merge}; |
127 val kind = {empty = empty, copy = copy, extend = extend, merge = merge}; |
128 val _ = CRITICAL (fn () => change kinds (Datatab.update (k, kind))); |
128 val _ = CRITICAL (fn () => Unsynchronized.change kinds (Datatab.update (k, kind))); |
129 in k end; |
129 in k end; |
130 |
130 |
131 val copy_data = Datatab.map' invoke_copy; |
131 val copy_data = Datatab.map' invoke_copy; |
132 val extend_data = Datatab.map' invoke_extend; |
132 val extend_data = Datatab.map' invoke_extend; |
133 |
133 |
147 (** datatype theory **) |
147 (** datatype theory **) |
148 |
148 |
149 datatype theory = |
149 datatype theory = |
150 Theory of |
150 Theory of |
151 (*identity*) |
151 (*identity*) |
152 {self: theory ref option, (*dynamic self reference -- follows theory changes*) |
152 {self: theory Unsynchronized.ref option, (*dynamic self reference -- follows theory changes*) |
153 draft: bool, (*draft mode -- linear destructive changes*) |
153 draft: bool, (*draft mode -- linear destructive changes*) |
154 id: serial, (*identifier*) |
154 id: serial, (*identifier*) |
155 ids: unit Inttab.table} * (*cumulative identifiers of non-drafts -- symbolic body content*) |
155 ids: unit Inttab.table} * (*cumulative identifiers of non-drafts -- symbolic body content*) |
156 (*data*) |
156 (*data*) |
157 Object.T Datatab.table * (*body content*) |
157 Object.T Datatab.table * (*body content*) |
184 (* staleness *) |
184 (* staleness *) |
185 |
185 |
186 fun eq_id (i: int, j) = i = j; |
186 fun eq_id (i: int, j) = i = j; |
187 |
187 |
188 fun is_stale |
188 fun is_stale |
189 (Theory ({self = SOME (ref (Theory ({id = id', ...}, _, _, _))), id, ...}, _, _, _)) = |
189 (Theory ({self = |
|
190 SOME (Unsynchronized.ref (Theory ({id = id', ...}, _, _, _))), id, ...}, _, _, _)) = |
190 not (eq_id (id, id')) |
191 not (eq_id (id, id')) |
191 | is_stale (Theory ({self = NONE, ...}, _, _, _)) = true; |
192 | is_stale (Theory ({self = NONE, ...}, _, _, _)) = true; |
192 |
193 |
193 fun vitalize (thy as Theory ({self = SOME r, ...}, _, _, _)) = (r := thy; thy) |
194 fun vitalize (thy as Theory ({self = SOME r, ...}, _, _, _)) = (r := thy; thy) |
194 | vitalize (thy as Theory ({self = NONE, draft, id, ids}, data, ancestry, history)) = |
195 | vitalize (thy as Theory ({self = NONE, draft, id, ids}, data, ancestry, history)) = |
195 let |
196 let |
196 val r = ref thy; |
197 val r = Unsynchronized.ref thy; |
197 val thy' = Theory (make_identity (SOME r) draft id ids, data, ancestry, history); |
198 val thy' = Theory (make_identity (SOME r) draft id ids, data, ancestry, history); |
198 in r := thy'; thy' end; |
199 in r := thy'; thy' end; |
199 |
200 |
200 |
201 |
201 (* draft mode *) |
202 (* draft mode *) |
241 |
242 |
242 (*theory_ref provides a safe way to store dynamic references to a |
243 (*theory_ref provides a safe way to store dynamic references to a |
243 theory in external data structures -- a plain theory value would |
244 theory in external data structures -- a plain theory value would |
244 become stale as the self reference moves on*) |
245 become stale as the self reference moves on*) |
245 |
246 |
246 datatype theory_ref = TheoryRef of theory ref; |
247 datatype theory_ref = TheoryRef of theory Unsynchronized.ref; |
247 |
248 |
248 fun deref (TheoryRef (ref thy)) = thy; |
249 fun deref (TheoryRef (Unsynchronized.ref thy)) = thy; |
249 |
250 |
250 fun check_thy thy = (*thread-safe version*) |
251 fun check_thy thy = (*thread-safe version*) |
251 let val thy_ref = TheoryRef (the_self thy) in |
252 let val thy_ref = TheoryRef (the_self thy) in |
252 if is_stale thy then error ("Stale theory encountered:\n" ^ string_of_thy thy) |
253 if is_stale thy then error ("Stale theory encountered:\n" ^ string_of_thy thy) |
253 else thy_ref |
254 else thy_ref |