34 type 'att element |
35 type 'att element |
35 type 'att element_i |
36 type 'att element_i |
36 type locale |
37 type locale |
37 val intern: Sign.sg -> xstring -> string |
38 val intern: Sign.sg -> xstring -> string |
38 val cond_extern: Sign.sg -> string -> xstring |
39 val cond_extern: Sign.sg -> string -> xstring |
39 val intern_att: ('att -> context attribute) -> |
40 val attribute: ('att -> context attribute) -> |
40 ('typ, 'term, 'thm, 'att) elem -> ('typ, 'term, 'thm, context attribute) elem |
41 ('typ, 'term, 'thm, 'att) elem -> ('typ, 'term, 'thm, context attribute) elem |
41 val activate_elements: context attribute element list -> context -> context |
42 val activate_elements: context attribute element list -> context -> context |
42 val activate_elements_i: context attribute element_i list -> context -> context |
43 val activate_elements_i: context attribute element_i list -> context -> context |
43 val activate_locale: xstring -> context -> context |
44 val activate_locale: xstring -> context -> context |
44 val activate_locale_i: string -> context -> context |
45 val activate_locale_i: string -> context -> context |
45 (* |
46 val add_locale: bstring -> xstring list -> context attribute element list -> theory -> theory |
46 val add_locale: bstring -> xstring option -> (string * string * mixfix) list -> |
47 val add_locale_i: bstring -> xstring list -> context attribute element_i list -> theory -> theory |
47 ((string * context attribute list) * string) list -> |
48 val store_thm: string -> (string * thm) * context attribute list -> theory -> theory |
48 ((string * context attribute list) * string) list -> theory -> theory |
|
49 val add_locale_i: bstring -> xstring option -> (string * typ * mixfix) list -> |
|
50 ((string * context attribute list) * term) list -> |
|
51 ((string * context attribute list) * term) list -> theory -> theory |
|
52 val read_prop_schematic: Sign.sg -> string -> cterm |
|
53 *) |
|
54 val setup: (theory -> theory) list |
49 val setup: (theory -> theory) list |
55 end; |
50 end; |
56 |
51 |
57 structure Locale: LOCALE = |
52 structure Locale: LOCALE = |
58 struct |
53 struct |
71 Notes of ((string * 'att list) * ('fact * 'att list) list) list | |
66 Notes of ((string * 'att list) * ('fact * 'att list) list) list | |
72 Uses of expression; |
67 Uses of expression; |
73 |
68 |
74 type 'att element = (string, string, string, 'att) elem; |
69 type 'att element = (string, string, string, 'att) elem; |
75 type 'att element_i = (typ, term, thm list, 'att) elem; |
70 type 'att element_i = (typ, term, thm list, 'att) elem; |
76 type locale = (thm -> string) * string list * context attribute element_i list; |
71 type locale = {imports: string list, elements: context attribute element_i list, closed: bool}; |
|
72 |
|
73 fun make_locale imports elements closed = |
|
74 {imports = imports, elements = elements, closed = closed}: locale; |
77 |
75 |
78 |
76 |
79 fun fixes_of_elem (Fixes fixes) = map #1 fixes |
77 fun fixes_of_elem (Fixes fixes) = map #1 fixes |
80 | fixes_of_elem _ = []; |
78 | fixes_of_elem _ = []; |
81 |
79 |
82 fun frees_of_elem _ = []; (* FIXME *) |
80 fun frees_of_elem _ = []; (* FIXME *) |
83 |
81 |
|
82 (*fun close_locale {imports, elements, closed = _} = make_locale imports elements true;*) |
|
83 fun close_locale x = x; (* FIXME tmp *) |
|
84 |
84 |
85 |
85 |
86 |
86 (** theory data **) |
87 (** theory data **) |
87 |
88 |
88 (* data kind 'Pure/locales' *) |
89 (* data kind 'Pure/locales' *) |
89 |
|
90 type locale_data = |
|
91 {space: NameSpace.T, |
|
92 locales: locale Symtab.table, |
|
93 scope: ((string * locale) list * context option) ref}; |
|
94 |
|
95 fun make_locale_data space locales scope = |
|
96 {space = space, locales = locales, scope = scope}: locale_data; |
|
97 |
|
98 val empty_scope = ([], None); |
|
99 |
90 |
100 structure LocalesArgs = |
91 structure LocalesArgs = |
101 struct |
92 struct |
102 val name = "Isar/locales"; |
93 val name = "Isar/locales"; |
103 type T = locale_data; |
94 type T = NameSpace.T * locale Symtab.table; |
104 |
95 |
105 val empty = make_locale_data NameSpace.empty Symtab.empty (ref empty_scope); |
96 val empty = (NameSpace.empty, Symtab.empty); |
106 fun copy {space, locales, scope = ref r} = make_locale_data space locales (ref r); |
97 val copy = I; |
107 fun prep_ext {space, locales, scope = _} = make_locale_data space locales (ref empty_scope); |
98 fun prep_ext (space, locales) = (space, Symtab.map close_locale locales); |
108 fun merge ({space = space1, locales = locales1, scope = _}, |
99 fun merge ((space1, locales1), (space2, locales2)) = |
109 {space = space2, locales = locales2, scope = _}) = |
100 (NameSpace.merge (space1, space2), Symtab.merge (K true) (locales1, locales2)); |
110 make_locale_data (NameSpace.merge (space1, space2)) |
101 |
111 (Symtab.merge (K true) (locales1, locales2)) (ref empty_scope); |
102 fun print _ (space, locales) = |
112 |
|
113 fun print _ {space, locales, scope = _} = |
|
114 Pretty.strs ("locales:" :: map (NameSpace.cond_extern space o #1) (Symtab.dest locales)) |
103 Pretty.strs ("locales:" :: map (NameSpace.cond_extern space o #1) (Symtab.dest locales)) |
115 |> Pretty.writeln; |
104 |> Pretty.writeln; |
116 end; |
105 end; |
117 |
106 |
118 structure LocalesData = TheoryDataFun(LocalesArgs); |
107 structure LocalesData = TheoryDataFun(LocalesArgs); |
119 val print_locales = LocalesData.print; |
108 val print_locales = LocalesData.print; |
120 |
109 |
121 val intern = NameSpace.intern o #space o LocalesData.get_sg; |
110 val intern = NameSpace.intern o #1 o LocalesData.get_sg; |
122 val cond_extern = NameSpace.cond_extern o #space o LocalesData.get_sg; |
111 val cond_extern = NameSpace.cond_extern o #1 o LocalesData.get_sg; |
123 |
112 |
124 |
113 |
125 (* access locales *) |
114 (* access locales *) |
126 |
115 |
127 fun get_locale_sg sg name = Symtab.lookup (#locales (LocalesData.get_sg sg), name); |
116 fun declare_locale name = |
128 val get_locale = get_locale_sg o Theory.sign_of; |
117 LocalesData.map (apfst (fn space => (NameSpace.extend (space, [name])))); |
129 |
118 |
130 fun put_locale (name, locale) = LocalesData.map (fn {space, locales, scope} => |
119 fun put_locale name locale = |
131 make_locale_data (NameSpace.extend (space, [name])) |
120 LocalesData.map (apsnd (fn locales => Symtab.update ((name, locale), locales))); |
132 (Symtab.update ((name, locale), locales)) scope); |
121 |
|
122 fun get_locale thy name = Symtab.lookup (#2 (LocalesData.get thy), name); |
133 |
123 |
134 fun the_locale thy name = |
124 fun the_locale thy name = |
135 (case get_locale thy name of |
125 (case get_locale thy name of |
136 Some loc => loc |
126 Some loc => loc |
137 | None => error ("Unknown locale " ^ quote name)); |
127 | None => error ("Unknown locale " ^ quote name)); |
138 |
128 |
139 |
129 |
140 (* access scope *) |
|
141 |
|
142 fun get_scope_sg sg = |
|
143 if Sign.eq_sg (sg, Theory.sign_of ProtoPure.thy) then empty_scope |
|
144 else ! (#scope (LocalesData.get_sg sg)); |
|
145 |
|
146 val get_scope = get_scope_sg o Theory.sign_of; |
|
147 val nonempty_scope_sg = not o null o #1 o get_scope_sg; |
|
148 |
|
149 fun change_scope f thy = |
|
150 let val {scope, ...} = LocalesData.get thy |
|
151 in scope := f (! scope); thy end; |
|
152 |
|
153 fun print_scope thy = |
|
154 Pretty.writeln (Pretty.strs ("current scope:" :: |
|
155 rev (map (cond_extern (Theory.sign_of thy) o #1) (#1 (get_scope thy))))); |
|
156 |
|
157 |
|
158 (* print locales *) (* FIXME activate local syntax *) |
130 (* print locales *) (* FIXME activate local syntax *) |
159 |
131 |
160 fun pretty_locale thy xname = |
132 fun pretty_locale thy xname = |
161 let |
133 let |
162 val sg = Theory.sign_of thy; |
134 val sg = Theory.sign_of thy; |
163 val name = intern sg xname; |
135 val name = intern sg xname; |
164 val (_, ancestors, elements) = the_locale thy name; |
136 val {imports, elements, closed = _} = the_locale thy name; |
165 |
137 |
166 val prt_typ = Pretty.quote o Sign.pretty_typ sg; |
138 val prt_typ = Pretty.quote o Sign.pretty_typ sg; |
167 val prt_term = Pretty.quote o Sign.pretty_term sg; |
139 val prt_term = Pretty.quote o Sign.pretty_term sg; |
168 |
140 |
169 fun prt_syn syn = |
141 fun prt_syn syn = |
189 | prt_elem (Defines defs) = Pretty.big_list "defines" (map prt_def defs) |
161 | prt_elem (Defines defs) = Pretty.big_list "defines" (map prt_def defs) |
190 | prt_elem (Notes facts) = Pretty.big_list "notes" (map prt_fact facts) |
162 | prt_elem (Notes facts) = Pretty.big_list "notes" (map prt_fact facts) |
191 | prt_elem (Uses _) = Pretty.str "FIXME"; |
163 | prt_elem (Uses _) = Pretty.str "FIXME"; |
192 |
164 |
193 val prt_header = Pretty.block (Pretty.str ("locale " ^ cond_extern sg name ^ " =") :: |
165 val prt_header = Pretty.block (Pretty.str ("locale " ^ cond_extern sg name ^ " =") :: |
194 (if null ancestors then [] else |
166 (if null imports then [] else |
195 (flat (separate [Pretty.str "+", Pretty.brk 1] (map (single o Pretty.str) ancestors)) @ |
167 (flat (separate [Pretty.str "+", Pretty.brk 1] (map (single o Pretty.str) imports)) @ |
196 [Pretty.str "+"]))); |
168 [Pretty.str "+"]))); |
197 in Pretty.block (Pretty.fbreaks (prt_header :: map prt_elem elements)) end; |
169 in Pretty.block (Pretty.fbreaks (prt_header :: map prt_elem elements)) end; |
198 |
170 |
199 val print_locale = Pretty.writeln oo pretty_locale; |
171 val print_locale = Pretty.writeln oo pretty_locale; |
200 |
172 |
201 |
173 |
202 (** internalization of theorems and attributes **) |
174 |
203 |
175 (** internalize elements **) |
204 fun int_att attrib (x, srcs) = (x, map attrib srcs); |
176 |
205 |
177 (* read_elem *) |
206 fun intern_att _ (Fixes fixes) = Fixes fixes |
|
207 | intern_att attrib (Assumes asms) = Assumes (map (apfst (int_att attrib)) asms) |
|
208 | intern_att attrib (Defines defs) = Defines (map (apfst (int_att attrib)) defs) |
|
209 | intern_att attrib (Notes facts) = |
|
210 Notes (map (apfst (int_att attrib) o apsnd (map (int_att attrib))) facts) |
|
211 | intern_att _ (Uses FIXME) = Uses FIXME; |
|
212 |
|
213 |
|
214 |
|
215 (** activate locales **) |
|
216 |
|
217 fun close_frees ctxt t = |
|
218 let val frees = rev (filter_out (ProofContext.is_fixed ctxt o #1) (Drule.add_frees ([], t))) |
|
219 in Term.list_all_free (frees, t) end; |
|
220 |
178 |
221 fun read_elem ctxt = |
179 fun read_elem ctxt = |
222 fn (Fixes fixes) => |
180 fn Fixes fixes => |
223 let val vars = |
181 let val vars = |
224 #2 (foldl_map ProofContext.read_vars (ctxt, map (fn (x, T, _) => ([x], T)) fixes)) |
182 #2 (foldl_map ProofContext.read_vars (ctxt, map (fn (x, T, _) => ([x], T)) fixes)) |
225 in Fixes (map2 (fn (([x'], T'), (_, _, mx)) => (x', T', mx)) (vars, fixes)) end |
183 in Fixes (map2 (fn (([x'], T'), (_, _, mx)) => (x', T', mx)) (vars, fixes)) end |
226 | (Assumes asms) => |
184 | Assumes asms => |
227 Assumes (map #1 asms ~~ #2 (ProofContext.read_propp (ctxt, map #2 asms))) |
185 Assumes (map #1 asms ~~ #2 (ProofContext.read_propp (ctxt, map #2 asms))) |
228 | (Defines defs) => |
186 | Defines defs => |
229 let val propps = |
187 let val propps = |
230 #2 (ProofContext.read_propp (ctxt, map (fn (_, (t, ps)) => [(t, (ps, []))]) defs)) |
188 #2 (ProofContext.read_propp (ctxt, map (fn (_, (t, ps)) => [(t, (ps, []))]) defs)) |
231 in Defines (map #1 defs ~~ map (fn [(t', (ps', []))] => (t', ps')) propps) end |
189 in Defines (map #1 defs ~~ map (fn [(t', (ps', []))] => (t', ps')) propps) end |
232 | (Notes facts) => |
190 | Notes facts => |
233 Notes (map (apsnd (map (apfst (ProofContext.get_thms ctxt)))) facts) |
191 Notes (map (apsnd (map (apfst (ProofContext.get_thms ctxt)))) facts) |
234 | (Uses FIXME) => Uses FIXME; |
192 | Uses FIXME => Uses FIXME; |
235 |
193 |
|
194 |
|
195 (* prepare attributes *) |
|
196 |
|
197 local fun int_att attrib (x, srcs) = (x, map attrib srcs) in |
|
198 |
|
199 fun attribute _ (Fixes fixes) = Fixes fixes |
|
200 | attribute attrib (Assumes asms) = Assumes (map (apfst (int_att attrib)) asms) |
|
201 | attribute attrib (Defines defs) = Defines (map (apfst (int_att attrib)) defs) |
|
202 | attribute attrib (Notes facts) = |
|
203 Notes (map (apfst (int_att attrib) o apsnd (map (int_att attrib))) facts) |
|
204 | attribute _ (Uses FIXME) = Uses FIXME; |
|
205 |
|
206 end; |
|
207 |
|
208 |
|
209 |
|
210 (** activate locales **) |
|
211 |
|
212 (* activatation primitive *) |
236 |
213 |
237 fun activate (ctxt, Fixes fixes) = |
214 fun activate (ctxt, Fixes fixes) = |
238 ProofContext.fix_direct (map (fn (x, T, FIXME) => ([x], T)) fixes) ctxt |
215 ProofContext.fix_direct (map (fn (x, T, FIXME) => ([x], T)) fixes) ctxt |
239 | activate (ctxt, Assumes asms) = |
216 | activate (ctxt, Assumes asms) = |
240 ctxt |> ProofContext.fix_frees (flat (map (map #1 o #2) asms)) |
217 ctxt |> ProofContext.fix_frees (flat (map (map #1 o #2) asms)) |
242 | activate (ctxt, Defines defs) = #1 (ProofContext.assume_i ProofContext.export_def |
219 | activate (ctxt, Defines defs) = #1 (ProofContext.assume_i ProofContext.export_def |
243 (map (fn (a, (t, ps)) => (a, [(ProofContext.cert_def ctxt t, (ps, []))])) defs) ctxt) |
220 (map (fn (a, (t, ps)) => (a, [(ProofContext.cert_def ctxt t, (ps, []))])) defs) ctxt) |
244 | activate (ctxt, Notes facts) = #1 (ProofContext.have_thmss facts ctxt) |
221 | activate (ctxt, Notes facts) = #1 (ProofContext.have_thmss facts ctxt) |
245 | activate (ctxt, Uses FIXME) = ctxt; |
222 | activate (ctxt, Uses FIXME) = ctxt; |
246 |
223 |
247 fun read_activate (ctxt, elem) = |
224 |
248 let val elem' = read_elem ctxt elem |
225 (* activate operations *) |
249 in (activate (ctxt, elem'), elem') end; |
|
250 |
226 |
251 fun activate_elements_i elems ctxt = foldl activate (ctxt, elems); |
227 fun activate_elements_i elems ctxt = foldl activate (ctxt, elems); |
252 fun activate_elements elems ctxt = foldl (#1 o read_activate) (ctxt, elems); |
228 fun activate_elements elems ctxt = |
253 |
229 foldl ((fn (ctxt, elem) => activate (ctxt, read_elem ctxt elem))) (ctxt, elems); |
254 fun with_locale f name ctxt = |
230 |
|
231 fun activate_locale_elements (ctxt, name) = |
255 let |
232 let |
256 val thy = ProofContext.theory_of ctxt; |
233 val thy = ProofContext.theory_of ctxt; |
257 val locale = the_locale thy name; |
234 val {elements, ...} = the_locale thy name; (*exception ERROR*) |
258 in |
235 in |
259 f locale ctxt handle ProofContext.CONTEXT (msg, c) => |
236 activate_elements_i elements ctxt handle ProofContext.CONTEXT (msg, c) => |
260 raise ProofContext.CONTEXT (msg ^ "\nThe error(s) above occurred in locale " ^ |
237 raise ProofContext.CONTEXT (msg ^ "\nThe error(s) above occurred in locale " ^ |
261 quote (cond_extern (Theory.sign_of thy) name), c) |
238 quote (cond_extern (Theory.sign_of thy) name), c) |
262 end; |
239 end; |
263 |
240 |
264 val activate_locale_elements = with_locale (activate_elements_i o #3); |
|
265 |
|
266 fun activate_locale_ancestors name ctxt = |
|
267 foldl (fn (c, es) => activate_locale_elements es c) |
|
268 (ctxt, #2 (the_locale (ProofContext.theory_of ctxt) name)); |
|
269 |
|
270 fun activate_locale_i name ctxt = |
241 fun activate_locale_i name ctxt = |
271 ctxt |> activate_locale_ancestors name |> activate_locale_elements name; |
242 activate_locale_elements (foldl activate_locale_elements |
|
243 (ctxt, #imports (the_locale (ProofContext.theory_of ctxt) name)), name); |
272 |
244 |
273 fun activate_locale xname ctxt = |
245 fun activate_locale xname ctxt = |
274 activate_locale_i (intern (ProofContext.sign_of ctxt) xname) ctxt; |
246 activate_locale_i (intern (ProofContext.sign_of ctxt) xname) ctxt; |
275 |
247 |
276 |
248 |
277 |
249 |
278 (* FIXME |
|
279 (** define locales **) |
250 (** define locales **) |
280 |
251 |
281 (* concrete syntax *) |
252 (* closeup dangling frees *) |
282 |
253 |
283 fun mark_syn c = "\\<^locale>" ^ c; |
254 fun close_frees_wrt ctxt t = |
284 |
255 let val frees = rev (filter_out (ProofContext.is_fixed ctxt o #1) (Drule.add_frees ([], t))) |
285 fun mk_loc_tr c ts = list_comb (Free (c, dummyT), ts); |
256 in curry Term.list_all_free frees end; |
286 |
257 |
287 |
258 fun closeup ctxt (Assumes asms) = Assumes (asms |> map (fn (a, propps) => |
288 (* add_locale *) |
259 (a, propps |> map (fn (t, (ps1, ps2)) => |
289 |
260 let val close = close_frees_wrt ctxt t in (close t, (map close ps1, map close ps2)) end)))) |
290 fun gen_add_locale prep_typ prep_term bname bpar raw_fixes raw_assumes raw_defs thy = |
261 | closeup ctxt (Defines defs) = Defines (defs |> map (fn (a, (t, ps)) => |
291 let val sign = Theory.sign_of thy; |
262 let |
292 |
263 val t' = ProofContext.cert_def ctxt t; |
|
264 val close = close_frees_wrt ctxt t'; |
|
265 in (a, (close t', map close ps)) end)) |
|
266 | closeup ctxt elem = elem; |
|
267 |
|
268 |
|
269 (* add_locale(_i) *) |
|
270 |
|
271 fun gen_add_locale prep_locale prep_elem bname raw_imports raw_elems thy = |
|
272 let |
|
273 val sign = Theory.sign_of thy; |
293 val name = Sign.full_name sign bname; |
274 val name = Sign.full_name sign bname; |
294 |
275 val _ = |
295 val (envSb, old_loc_fixes, _) = |
276 if is_none (get_locale thy name) then () else |
296 case bpar of |
277 error ("Duplicate definition of locale " ^ quote name); |
297 Some loc => (get_defaults thy loc) |
278 |
298 | None => ([],[],[]); |
279 val imports = map (prep_locale sign) raw_imports; |
299 |
280 val imports_ctxt = foldl activate_locale_elements (ProofContext.init thy, imports); |
300 val old_nosyn = case bpar of |
281 fun prep (ctxt, raw_elem) = |
301 Some loc => #nosyn(#2(the_locale thy loc)) |
282 let val elem = closeup ctxt (prep_elem ctxt raw_elem) |
302 | None => []; |
283 in (activate (ctxt, elem), elem) end; |
303 |
284 val (locale_ctxt, elems) = foldl_map prep (imports_ctxt, raw_elems); |
304 (* Get the full name of the parent *) |
285 in |
305 val parent = case bparent of |
286 thy |
306 Some loc => Some(#1(the_locale thy loc)) |
287 |> declare_locale name |
307 | None => None; |
288 |> put_locale name (make_locale imports elems false) |
308 |
289 end; |
309 (* prepare locale fixes *) |
290 |
310 |
291 val add_locale = gen_add_locale intern read_elem; |
311 fun prep_const (envS, (raw_c, raw_T, raw_mx)) = |
292 val add_locale_i = gen_add_locale (K I) (K I); |
312 let |
293 |
313 val c = Syntax.const_name raw_c raw_mx; |
294 |
314 val c_syn = mark_syn c; |
295 |
|
296 (** store results **) (* FIXME test atts!? *) |
|
297 |
|
298 fun store_thm name ((a, th), atts) thy = |
|
299 let |
|
300 val note = Notes [((a, atts), [([Thm.name_thm (a, th)], [])])]; |
|
301 val {imports, elements, closed} = the_locale thy name; |
|
302 in |
|
303 if closed then error ("Cannot store results in closed locale: " ^ quote name) |
|
304 else thy |> put_locale name (make_locale imports (elements @ [note]) closed) |
|
305 end; |
|
306 |
|
307 |
|
308 (* FIXME old |
|
309 |
315 val mx = Syntax.fix_mixfix raw_c raw_mx; |
310 val mx = Syntax.fix_mixfix raw_c raw_mx; |
316 val (envS', T) = prep_typ sign (envS, raw_T) handle ERROR => |
311 val (envS', T) = prep_typ sign (envS, raw_T) handle ERROR => |
317 error ("The error(s) above occured in locale constant " ^ quote c); |
312 error ("The error(s) above occured in locale constant " ^ quote c); |
318 val trfun = if mx = Syntax.NoSyn then None else Some (c_syn, mk_loc_tr c); |
313 val trfun = if mx = Syntax.NoSyn then None else Some (c_syn, mk_loc_tr c); |
319 in (envS', ((c, T), (c_syn, T, mx), trfun)) end; |
314 in (envS', ((c, T), (c_syn, T, mx), trfun)) end; |
323 val loc_fixes = old_loc_fixes @ loc_fixes; |
318 val loc_fixes = old_loc_fixes @ loc_fixes; |
324 val loc_syn = map #2 loc_fixes_syn; |
319 val loc_syn = map #2 loc_fixes_syn; |
325 val nosyn = old_nosyn @ (map (#1 o #1) (filter (fn x => (#3(#2 x)) = NoSyn) loc_fixes_syn)); |
320 val nosyn = old_nosyn @ (map (#1 o #1) (filter (fn x => (#3(#2 x)) = NoSyn) loc_fixes_syn)); |
326 val loc_trfuns = mapfilter #3 loc_fixes_syn; |
321 val loc_trfuns = mapfilter #3 loc_fixes_syn; |
327 |
322 |
328 |
|
329 (* 1st stage: syntax_thy *) |
|
330 |
|
331 val syntax_thy = |
323 val syntax_thy = |
332 thy |
324 thy |
333 |> Theory.add_modesyntax_i ("", true) loc_syn |
325 |> Theory.add_modesyntax_i ("", true) loc_syn |
334 |> Theory.add_trfuns ([], loc_trfuns, [], []); |
326 |> Theory.add_trfuns ([], loc_trfuns, [], []); |
335 |
|
336 val syntax_sign = Theory.sign_of syntax_thy; |
|
337 |
|
338 |
|
339 (* prepare assumes and defs *) |
|
340 |
|
341 fun prep_axiom (env, (a, raw_t)) = |
|
342 let |
|
343 val (env', t) = prep_term syntax_sign (env, (a, raw_t)) handle ERROR => |
|
344 error ("The error(s) above occured in locale rule / definition " ^ quote a); |
|
345 in (env', (a, t)) end; |
|
346 |
|
347 val ((envS1, envT1, used1), loc_assumes) = |
|
348 foldl_map prep_axiom ((envS0, loc_fixes, map fst envS0), raw_assumes); |
|
349 val (defaults, loc_defs) = |
|
350 foldl_map prep_axiom ((envS1, envT1, used1), raw_defs); |
|
351 |
|
352 val old_loc_fixes = collect_fixes syntax_sign; |
|
353 val new_loc_fixes = (map #1 loc_fixes); |
|
354 val all_loc_fixes = old_loc_fixes @ new_loc_fixes; |
|
355 |
|
356 val (defaults, loc_defs_terms) = |
|
357 foldl_map (abs_over_free all_loc_fixes) (defaults, loc_defs); |
|
358 val loc_defs_thms = |
|
359 map (apsnd (prep_hyps (map #1 loc_fixes) syntax_sign)) loc_defs_terms; |
|
360 val (defaults, loc_thms_terms) = |
|
361 foldl_map (abs_over_free all_loc_fixes) (defaults, loc_assumes); |
|
362 val loc_thms = map (apsnd (prep_hyps (map #1 loc_fixes) syntax_sign)) |
|
363 (loc_thms_terms) |
|
364 @ loc_defs_thms; |
|
365 |
|
366 |
|
367 (* error messages *) |
|
368 |
|
369 fun locale_error msg = error (msg ^ "\nFor locale " ^ quote name); |
|
370 |
|
371 val err_dup_locale = |
|
372 if is_none (get_locale thy name) then [] |
|
373 else ["Duplicate definition of locale " ^ quote name]; |
|
374 |
327 |
375 (* check if definientes are locale constants |
328 (* check if definientes are locale constants |
376 (in the same locale, so no redefining!) *) |
329 (in the same locale, so no redefining!) *) |
377 val err_def_head = |
330 val err_def_head = |
378 let fun peal_appl t = |
331 let fun peal_appl t = |
399 locale_error ("Definitions must use the == relation") |
352 locale_error ("Definitions must use the == relation") |
400 val check = foldl compare_var_sides (true, loc_defs) |
353 val check = foldl compare_var_sides (true, loc_defs) |
401 in if check then [] |
354 in if check then [] |
402 else ["nonfixed variable on right hand side of a locale definition in locale " ^ quote name] |
355 else ["nonfixed variable on right hand side of a locale definition in locale " ^ quote name] |
403 end; |
356 end; |
404 |
|
405 val errs = err_dup_locale @ err_def_head @ err_var_rhs; |
|
406 in |
|
407 if null errs then () |
|
408 else error (cat_lines errs); |
|
409 |
|
410 syntax_thy |
|
411 |> put_locale (name, |
|
412 make_locale parent loc_fixes nosyn loc_thms_terms |
|
413 loc_defs_terms loc_thms defaults) |
|
414 end; |
|
415 |
|
416 |
|
417 val add_locale = gen_add_locale read_typ read_axm; |
|
418 val add_locale_i = gen_add_locale cert_typ cert_axm; |
|
419 |
|
420 |
|
421 |
|
422 (* |
|
423 (** support for legacy proof scripts (cf. goals.ML) **) (* FIXME move to goals.ML (!?) *) |
|
424 |
|
425 (* hyps_in_scope *) |
|
426 |
|
427 fun hyps_in_scope sg hyps = |
|
428 let val locs = map #2 (#1 (get_scope_sg sg)) |
|
429 in gen_subset Term.aconv (hyps, map #2 (flat (map #assumes locs @ map #defines locs))) end; |
|
430 |
|
431 |
|
432 (* get theorems *) |
|
433 |
|
434 fun thmx get_local get_global name = |
|
435 let val thy = Context.the_context () in |
|
436 (case #2 (get_scope thy) of |
|
437 None => get_global thy name |
|
438 | Some ctxt => get_local ctxt name) |
|
439 end; |
|
440 |
|
441 val thm = thmx ProofContext.get_thm PureThy.get_thm; |
|
442 val thms = thmx ProofContext.get_thms PureThy.get_thms; |
|
443 |
|
444 |
|
445 (** scope operations -- for old-style goals **) (* FIXME move to goals.ML (!?) *) |
|
446 |
|
447 (* open *) |
|
448 |
|
449 local |
|
450 |
|
451 fun is_open thy name = exists (equal name o #1) (#1 (get_scope thy)); |
|
452 |
|
453 fun open_loc thy name = |
|
454 let |
|
455 val (ancestors, elements) = the_locale thy name; |
|
456 in |
|
457 (case #parent locale of None => thy |
|
458 | Some par => |
|
459 if is_open thy par then thy |
|
460 else (writeln ("Opening locale " ^ quote par ^ "(required by " ^ quote name ^ ")"); |
|
461 open_loc name thy)) |
|
462 |> change_scope (fn (locs, _) => ((name, locale) :: locs, None)) |
|
463 end; |
|
464 |
|
465 in |
|
466 |
|
467 fun open_locale xname thy = |
|
468 let val name = intern (Theory.sign_of thy) xname in |
|
469 if is_open thy name then (warning ("Locale " ^ quote name ^ " already open"); thy) |
|
470 else open_loc name thy |
|
471 end; |
|
472 |
|
473 end; |
|
474 |
|
475 |
|
476 (* close *) |
|
477 |
|
478 fun close_locale xname thy = |
|
479 let val name = intern_locale (Theory.sign_of thy) xname in |
|
480 thy |> change_scope (fn ([], _) => error "Currently no open locales" |
|
481 | ((name', _) :: locs, _) => |
|
482 if name <> name' then error ("Locale " ^ quote name ^ " not at top of scope") |
|
483 else (locs, None)) |
|
484 end; |
|
485 |
|
486 |
|
487 (* implicit context versions *) |
|
488 |
|
489 fun Open_locale xname = (open_locale xname (Context.the_context ()); ()); |
|
490 fun Close_locale xname = (close_locale xname (Context.the_context ()); ()); |
|
491 fun Print_scope () = (print_scope (Context.the_context ()); ()); |
|
492 *) |
357 *) |
493 |
358 |
494 |
359 |
495 (** locale theory setup **) |
360 (** locale theory setup **) |
496 *) |
361 |
497 val setup = |
362 val setup = |
498 [LocalesData.init]; |
363 [LocalesData.init]; |
499 |
364 |
500 end; |
365 end; |
501 |
366 |