19 |
19 |
20 (** locale targets **) |
20 (** locale targets **) |
21 |
21 |
22 (* context data *) |
22 (* context data *) |
23 |
23 |
|
24 datatype target = Target of {target: string, is_locale: bool, is_class: bool}; |
|
25 |
|
26 fun make_target target is_locale is_class = |
|
27 Target {target = target, is_locale = is_locale, is_class = is_class}; |
|
28 |
24 structure Data = ProofDataFun |
29 structure Data = ProofDataFun |
25 ( |
30 ( |
26 type T = string option; |
31 type T = target; |
27 fun init _ = NONE; |
32 fun init _ = make_target "" false false; |
28 ); |
33 ); |
29 |
34 |
30 val peek = Data.get; |
35 val peek = (fn Target args => args) o Data.get; |
31 |
36 |
32 |
37 |
33 (* pretty *) |
38 (* pretty *) |
34 |
39 |
35 fun pretty loc ctxt = |
40 fun pretty (Target {target, is_locale, is_class}) ctxt = |
36 let |
41 let |
37 val thy = ProofContext.theory_of ctxt; |
42 val thy = ProofContext.theory_of ctxt; |
38 val loc_kind = if is_some (Class.class_of_locale thy loc) then "class" else "locale"; |
43 val target_name = (if is_class then "class " else "locale ") ^ Locale.extern thy target; |
39 val loc_name = Locale.extern thy loc; |
|
40 |
44 |
41 val fixes = map (fn (x, T) => (x, SOME T, NoSyn)) (#1 (ProofContext.inferred_fixes ctxt)); |
45 val fixes = map (fn (x, T) => (x, SOME T, NoSyn)) (#1 (ProofContext.inferred_fixes ctxt)); |
42 val assumes = map (fn A => (("", []), [(A, [])])) (map Thm.term_of (Assumption.assms_of ctxt)); |
46 val assumes = map (fn A => (("", []), [(A, [])])) (map Thm.term_of (Assumption.assms_of ctxt)); |
43 val elems = |
47 val elems = |
44 (if null fixes then [] else [Element.Fixes fixes]) @ |
48 (if null fixes then [] else [Element.Fixes fixes]) @ |
45 (if null assumes then [] else [Element.Assumes assumes]); |
49 (if null assumes then [] else [Element.Assumes assumes]); |
46 in |
50 in |
47 Pretty.block [Pretty.str "theory", Pretty.brk 1, Pretty.str (Context.theory_name thy)] :: |
51 Pretty.block [Pretty.str "theory", Pretty.brk 1, Pretty.str (Context.theory_name thy)] :: |
48 (if loc = "" then [] |
52 (if target = "" then [] |
49 else if null elems then [Pretty.str (loc_kind ^ " " ^ loc_name)] |
53 else if null elems then [Pretty.str target_name] |
50 else [Pretty.big_list (loc_kind ^ " " ^ loc_name ^ " =") |
54 else [Pretty.big_list (target_name ^ " =") |
51 (map (Pretty.chunks o Element.pretty_ctxt ctxt) elems)]) |
55 (map (Pretty.chunks o Element.pretty_ctxt ctxt) elems)]) |
52 end; |
56 end; |
53 |
57 |
54 |
58 |
55 (* target declarations *) |
59 (* target declarations *) |
56 |
60 |
57 fun target_decl add loc d lthy = |
61 fun target_decl add (Target {target, ...}) d lthy = |
58 let |
62 let |
59 val d' = Morphism.transform (LocalTheory.target_morphism lthy) d; |
63 val d' = Morphism.transform (LocalTheory.target_morphism lthy) d; |
60 val d0 = Morphism.form d'; |
64 val d0 = Morphism.form d'; |
61 in |
65 in |
62 if loc = "" then |
66 if target = "" then |
63 lthy |
67 lthy |
64 |> LocalTheory.theory (Context.theory_map d0) |
68 |> LocalTheory.theory (Context.theory_map d0) |
65 |> LocalTheory.target (Context.proof_map d0) |
69 |> LocalTheory.target (Context.proof_map d0) |
66 else |
70 else |
67 lthy |
71 lthy |
68 |> LocalTheory.target (add loc d') |
72 |> LocalTheory.target (add target d') |
69 end; |
73 end; |
70 |
74 |
71 val type_syntax = target_decl Locale.add_type_syntax; |
75 val type_syntax = target_decl Locale.add_type_syntax; |
72 val term_syntax = target_decl Locale.add_term_syntax; |
76 val term_syntax = target_decl Locale.add_term_syntax; |
73 val declaration = target_decl Locale.add_declaration; |
77 val declaration = target_decl Locale.add_declaration; |
74 |
78 |
75 fun target_naming loc lthy = |
79 fun target_naming (Target {target, ...}) lthy = |
76 (if loc = "" then Sign.naming_of (ProofContext.theory_of lthy) |
80 (if target = "" then Sign.naming_of (ProofContext.theory_of lthy) |
77 else ProofContext.naming_of (LocalTheory.target_of lthy)) |
81 else ProofContext.naming_of (LocalTheory.target_of lthy)) |
78 |> NameSpace.qualified_names; |
82 |> NameSpace.qualified_names; |
79 |
83 |
80 |
84 |
81 |
85 |
129 |> Goal.norm_result |
133 |> Goal.norm_result |
130 |> PureThy.name_thm false false name; |
134 |> PureThy.name_thm false false name; |
131 |
135 |
132 in (result'', result) end; |
136 in (result'', result) end; |
133 |
137 |
134 fun local_notes loc kind facts lthy = |
138 fun local_notes (Target {target, is_locale, ...}) kind facts lthy = |
135 let |
139 let |
136 val is_loc = loc <> ""; |
|
137 val thy = ProofContext.theory_of lthy; |
140 val thy = ProofContext.theory_of lthy; |
138 val full = LocalTheory.full_name lthy; |
141 val full = LocalTheory.full_name lthy; |
139 |
142 |
140 val facts' = facts |
143 val facts' = facts |
141 |> map (fn (a, bs) => (a, PureThy.burrow_fact (PureThy.name_multi (full (fst a))) bs)) |
144 |> map (fn (a, bs) => (a, PureThy.burrow_fact (PureThy.name_multi (full (fst a))) bs)) |
142 |> PureThy.map_facts (import_export_proof lthy); |
145 |> PureThy.map_facts (import_export_proof lthy); |
143 val local_facts = PureThy.map_facts #1 facts' |
146 val local_facts = PureThy.map_facts #1 facts' |
144 |> Attrib.map_facts (Attrib.attribute_i thy); |
147 |> Attrib.map_facts (Attrib.attribute_i thy); |
145 val target_facts = PureThy.map_facts #1 facts' |
148 val target_facts = PureThy.map_facts #1 facts' |
146 |> is_loc ? Element.facts_map (Element.morph_ctxt (LocalTheory.target_morphism lthy)); |
149 |> is_locale ? Element.facts_map (Element.morph_ctxt (LocalTheory.target_morphism lthy)); |
147 val global_facts = PureThy.map_facts #2 facts' |
150 val global_facts = PureThy.map_facts #2 facts' |
148 |> Attrib.map_facts (if is_loc then K I else Attrib.attribute_i thy); |
151 |> Attrib.map_facts (if is_locale then K I else Attrib.attribute_i thy); |
149 in |
152 in |
150 lthy |> LocalTheory.theory |
153 lthy |> LocalTheory.theory |
151 (Sign.qualified_names |
154 (Sign.qualified_names |
152 #> PureThy.note_thmss_i kind global_facts #> snd |
155 #> PureThy.note_thmss_i kind global_facts #> snd |
153 #> Sign.restore_naming thy) |
156 #> Sign.restore_naming thy) |
154 |
157 |
155 |> is_loc ? LocalTheory.target (Locale.add_thmss loc kind target_facts) |
158 |> is_locale ? LocalTheory.target (Locale.add_thmss target kind target_facts) |
156 |
159 |
157 |> ProofContext.qualified_names |
160 |> ProofContext.qualified_names |
158 |> ProofContext.note_thmss_i kind local_facts |
161 |> ProofContext.note_thmss_i kind local_facts |
159 ||> ProofContext.restore_naming lthy |
162 ||> ProofContext.restore_naming lthy |
160 end; |
163 end; |
177 #-> (fn (lhs, _) => |
180 #-> (fn (lhs, _) => |
178 Type.similar_types (rhs, rhs') ? |
181 Type.similar_types (rhs, rhs') ? |
179 Morphism.form (ProofContext.target_notation true prmode [(lhs, mx)]))) |
182 Morphism.form (ProofContext.target_notation true prmode [(lhs, mx)]))) |
180 end; |
183 end; |
181 |
184 |
182 fun internal_abbrev loc prmode ((c, mx), t) lthy = lthy |
185 fun internal_abbrev ta prmode ((c, mx), t) lthy = lthy |
183 (* FIXME really permissive *) |
186 (* FIXME really permissive *) |
184 |> term_syntax loc (perhaps o try o target_abbrev prmode ((c, mx), t)) |
187 |> term_syntax ta (perhaps o try o target_abbrev prmode ((c, mx), t)) |
185 |> ProofContext.add_abbrev Syntax.internalM (ContextPosition.properties_of lthy) (c, t) |
188 |> ProofContext.add_abbrev Syntax.internalM (ContextPosition.properties_of lthy) (c, t) |
186 |> snd; |
189 |> snd; |
187 |
190 |
188 fun declare_consts loc depends decls lthy = |
191 fun declare_consts (ta as Target {target, is_locale, is_class}) depends decls lthy = |
189 let |
192 let |
190 val thy = ProofContext.theory_of lthy; |
193 val thy = ProofContext.theory_of lthy; |
191 val is_loc = loc <> ""; |
|
192 val some_class = Class.class_of_locale thy loc; |
|
193 |
|
194 val xs = filter depends (#1 (ProofContext.inferred_fixes (LocalTheory.target_of lthy))); |
194 val xs = filter depends (#1 (ProofContext.inferred_fixes (LocalTheory.target_of lthy))); |
195 |
195 |
196 fun const ((c, T), mx) thy = |
196 fun const ((c, T), mx) thy = |
197 let |
197 let |
198 val U = map #2 xs ---> T; |
198 val U = map #2 xs ---> T; |
199 val (mx1, mx2) = Class.fork_mixfix is_loc some_class mx; |
199 val (mx1, mx2) = Class.fork_mixfix is_locale is_class mx; |
200 val mx3 = if is_loc then NoSyn else mx1; |
200 val mx3 = if is_locale then NoSyn else mx1; |
201 val (const, thy') = Sign.declare_const (ContextPosition.properties_of lthy) (c, U, mx3) thy; |
201 val (const, thy') = Sign.declare_const (ContextPosition.properties_of lthy) (c, U, mx3) thy; |
202 val t = Term.list_comb (const, map Free xs); |
202 val t = Term.list_comb (const, map Free xs); |
203 in (((c, mx2), t), thy') end; |
203 in (((c, mx2), t), thy') end; |
204 fun const_class (SOME class) ((c, _), mx) (_, t) = |
204 fun const_class (SOME class) ((c, _), mx) (_, t) = |
205 LocalTheory.raw_theory_result (Class.add_const_in_class class ((c, t), mx)) |
205 LocalTheory.raw_theory_result (Class.add_const_in_class class ((c, t), mx)) |
206 #-> Class.remove_constraint class |
206 #-> Class.remove_constraint class |
207 | const_class NONE _ _ = I; |
207 | const_class NONE _ _ = I; |
208 fun hide_abbrev (SOME class) abbrs thy = |
|
209 let |
|
210 val raw_cs = map (fst o fst) abbrs; |
|
211 val prfx = (Logic.const_of_class o NameSpace.base) class; |
|
212 fun mk_name c = |
|
213 let |
|
214 val n1 = Sign.full_name thy c; |
|
215 val n2 = NameSpace.qualifier n1; |
|
216 val n3 = NameSpace.base n1; |
|
217 in NameSpace.implode [n2, prfx, prfx, n3] end; |
|
218 val cs = map mk_name raw_cs; |
|
219 in |
|
220 Sign.hide_consts_i true cs thy |
|
221 end |
|
222 | hide_abbrev NONE _ thy = thy; |
|
223 |
208 |
224 val (abbrs, lthy') = lthy |
209 val (abbrs, lthy') = lthy |
225 |> LocalTheory.theory_result (fold_map const decls) |
210 |> LocalTheory.theory_result (fold_map const decls) |
226 val defs = map (apsnd (pair ("", []))) abbrs; |
211 val defs = map (apsnd (pair ("", []))) abbrs; |
227 |
212 |
228 in |
213 in |
229 lthy' |
214 lthy' |
230 |> fold2 (const_class some_class) decls abbrs |
215 |> fold2 (const_class (if is_class then SOME target else NONE)) decls abbrs |
231 |> is_loc ? fold (internal_abbrev loc Syntax.mode_default) abbrs |
216 |> is_locale ? fold (internal_abbrev ta Syntax.mode_default) abbrs |
232 |> LocalTheory.raw_theory (hide_abbrev some_class abbrs) |
|
233 (*FIXME abbreviations should never occur*) |
|
234 |> LocalDefs.add_defs defs |
217 |> LocalDefs.add_defs defs |
235 |>> map (apsnd snd) |
218 |>> map (apsnd snd) |
236 end; |
219 end; |
237 |
220 |
238 |
221 |
252 Variable.declare_term rhs #> |
235 Variable.declare_term rhs #> |
253 Assumption.add_assms (K (K (I, Envir.expand_term_frees [((x', T), rhs)]))) [] #> snd #> |
236 Assumption.add_assms (K (K (I, Envir.expand_term_frees [((x', T), rhs)]))) [] #> snd #> |
254 pair (lhs, rhs) |
237 pair (lhs, rhs) |
255 end); |
238 end); |
256 |
239 |
257 fun abbrev loc prmode ((raw_c, mx), raw_t) lthy = |
240 fun abbrev (ta as Target {target, is_locale, is_class}) prmode ((raw_c, mx), raw_t) lthy = |
258 let |
241 let |
259 val thy = ProofContext.theory_of lthy; |
242 val thy = ProofContext.theory_of lthy; |
260 val is_loc = loc <> ""; |
|
261 val some_class = Class.class_of_locale thy loc; |
|
262 |
243 |
263 val thy_ctxt = ProofContext.init thy; |
244 val thy_ctxt = ProofContext.init thy; |
264 val target = LocalTheory.target_of lthy; |
245 val target_ctxt = LocalTheory.target_of lthy; |
265 val target_morphism = LocalTheory.target_morphism lthy; |
246 val target_morphism = LocalTheory.target_morphism lthy; |
266 |
247 |
267 val c = Morphism.name target_morphism raw_c; |
248 val c = Morphism.name target_morphism raw_c; |
268 val t = Morphism.term target_morphism raw_t; |
249 val t = Morphism.term target_morphism raw_t; |
269 val xs = map Free (occ_params target [t]); |
250 val xs = map Free (occ_params target_ctxt [t]); |
270 val u = fold_rev Term.lambda xs t; |
251 val u = fold_rev Term.lambda xs t; |
271 val U = Term.fastype_of u; |
252 val U = Term.fastype_of u; |
272 val u' = singleton (Variable.export_terms (Variable.declare_term u target) thy_ctxt) u; |
253 val u' = singleton (Variable.export_terms (Variable.declare_term u target_ctxt) thy_ctxt) u; |
273 val (mx1, mx2) = Class.fork_mixfix is_loc some_class mx; |
254 val (mx1, mx2) = Class.fork_mixfix is_locale is_class mx; |
274 val mx3 = if is_loc then NoSyn else mx1; |
255 val mx3 = if is_locale then NoSyn else mx1; |
275 fun add_abbrev_in_class (SOME class) abbr = |
256 fun add_abbrev_in_class abbr = |
276 LocalTheory.raw_theory_result (Class.add_abbrev_in_class class prmode abbr) |
257 LocalTheory.raw_theory_result (Class.add_abbrev_in_class target prmode abbr) |
277 #-> Class.remove_constraint class |
258 #-> Class.remove_constraint target; |
278 | add_abbrev_in_class NONE _ = I; |
|
279 in |
259 in |
280 lthy |
260 lthy |
281 |> LocalTheory.theory_result |
261 |> LocalTheory.theory_result |
282 (Sign.add_abbrev (#1 prmode) (ContextPosition.properties_of lthy) (c, u')) |
262 (Sign.add_abbrev (#1 prmode) (ContextPosition.properties_of lthy) (c, u')) |
283 |-> (fn (lhs as Const (full_c, _), rhs) => |
263 |-> (fn (lhs as Const (full_c, _), rhs) => |
284 LocalTheory.theory (Sign.notation true prmode [(lhs, mx3)]) |
264 LocalTheory.theory (Sign.notation true prmode [(lhs, mx3)]) |
285 #> is_loc ? internal_abbrev loc prmode ((c, mx2), Term.list_comb (Const (full_c, U), xs)) |
265 #> is_locale ? internal_abbrev ta prmode ((c, mx2), Term.list_comb (Const (full_c, U), xs)) |
286 #> add_abbrev_in_class some_class ((c, Term.list_comb (Const (full_c, U), xs)), mx1) |
266 #> is_class ? add_abbrev_in_class ((c, Term.list_comb (Const (full_c, U), xs)), mx1) |
287 #> local_abbrev (c, rhs)) |
267 #> local_abbrev (c, rhs)) |
288 end; |
268 end; |
289 |
269 |
290 |
270 |
291 (* defs *) |
271 (* defs *) |
292 |
272 |
293 fun local_def loc kind ((c, mx), ((name, atts), rhs)) lthy = |
273 fun local_def (ta as Target {target, is_locale, is_class}) |
|
274 kind ((c, mx), ((name, atts), rhs)) lthy = |
294 let |
275 let |
295 val thy = ProofContext.theory_of lthy; |
276 val thy = ProofContext.theory_of lthy; |
296 val thy_ctxt = ProofContext.init thy; |
277 val thy_ctxt = ProofContext.init thy; |
297 |
278 |
298 val (rhs', rhs_conv) = |
279 val (rhs', rhs_conv) = |
300 val xs = Variable.add_fixed (LocalTheory.target_of lthy) rhs' []; |
281 val xs = Variable.add_fixed (LocalTheory.target_of lthy) rhs' []; |
301 val T = Term.fastype_of rhs; |
282 val T = Term.fastype_of rhs; |
302 |
283 |
303 (*consts*) |
284 (*consts*) |
304 val ([(lhs, lhs_def)], lthy2) = lthy |
285 val ([(lhs, lhs_def)], lthy2) = lthy |
305 |> declare_consts loc (member (op =) xs) [((c, T), mx)]; |
286 |> declare_consts ta (member (op =) xs) [((c, T), mx)]; |
306 val (_, lhs') = Logic.dest_equals (Thm.prop_of lhs_def); |
287 val (_, lhs') = Logic.dest_equals (Thm.prop_of lhs_def); |
307 |
288 |
308 (*def*) |
289 (*def*) |
309 val name' = Thm.def_name_optional c name; |
290 val name' = Thm.def_name_optional c name; |
310 val (def, lthy3) = lthy2 |
291 val (def, lthy3) = lthy2 |
311 |> LocalTheory.theory_result (Thm.add_def false (name', Logic.mk_equals (lhs', rhs'))); |
292 |> LocalTheory.theory_result (Thm.add_def false (name', Logic.mk_equals (lhs', rhs'))); |
312 val eq = LocalDefs.trans_terms lthy3 |
293 val eq = LocalDefs.trans_terms lthy3 |
313 [(*c == loc.c xs*) lhs_def, |
294 [(*c == global.c xs*) lhs_def, |
314 (*lhs' == rhs'*) def, |
295 (*lhs' == rhs'*) def, |
315 (*rhs' == rhs*) Thm.symmetric rhs_conv]; |
296 (*rhs' == rhs*) Thm.symmetric rhs_conv]; |
316 |
297 |
317 (*notes*) |
298 (*notes*) |
318 val ([(res_name, [res])], lthy4) = lthy3 |
299 val ([(res_name, [res])], lthy4) = lthy3 |
319 |> local_notes loc kind [((name', atts), [([eq], [])])]; |
300 |> local_notes ta kind [((name', atts), [([eq], [])])]; |
320 in ((lhs, (res_name, res)), lthy4) end; |
301 in ((lhs, (res_name, res)), lthy4) end; |
321 |
302 |
322 |
303 |
323 (* axioms *) |
304 (* axioms *) |
324 |
305 |
325 fun local_axioms loc kind (vars, specs) lthy = |
306 fun local_axioms ta kind (vars, specs) lthy = |
326 let |
307 let |
327 val spec_frees = member (op =) (fold (fold Term.add_frees o snd) specs []); |
308 val spec_frees = member (op =) (fold (fold Term.add_frees o snd) specs []); |
328 val (consts, lthy') = declare_consts loc spec_frees vars lthy; |
309 val (consts, lthy') = declare_consts ta spec_frees vars lthy; |
329 val heads = map (Term.head_of o Thm.term_of o Thm.rhs_of o #2) consts; |
310 val heads = map (Term.head_of o Thm.term_of o Thm.rhs_of o #2) consts; |
330 |
311 |
331 val hyps = map Thm.term_of (Assumption.assms_of lthy'); |
312 val hyps = map Thm.term_of (Assumption.assms_of lthy'); |
332 fun axiom ((name, atts), props) thy = thy |
313 fun axiom ((name, atts), props) thy = thy |
333 |> fold_map (Thm.add_axiom hyps) (PureThy.name_multi name props) |
314 |> fold_map (Thm.add_axiom hyps) (PureThy.name_multi name props) |
335 in |
316 in |
336 lthy' |
317 lthy' |
337 |> LocalTheory.theory (Theory.add_finals_i false heads) |
318 |> LocalTheory.theory (Theory.add_finals_i false heads) |
338 |> fold (fold Variable.declare_term o snd) specs |
319 |> fold (fold Variable.declare_term o snd) specs |
339 |> LocalTheory.theory_result (fold_map axiom specs) |
320 |> LocalTheory.theory_result (fold_map axiom specs) |
340 |-> local_notes loc kind |
321 |-> local_notes ta kind |
341 |>> pair (map #1 consts) |
322 |>> pair (map #1 consts) |
342 end; |
323 end; |
343 |
324 |
344 |
325 |
345 (* init and exit *) |
326 (* init and exit *) |
346 |
327 |
347 fun begin loc ctxt = |
328 fun begin target ctxt = |
348 let |
329 let |
349 val thy = ProofContext.theory_of ctxt; |
330 val thy = ProofContext.theory_of ctxt; |
350 val is_loc = loc <> ""; |
331 val is_locale = target <> ""; |
|
332 val is_class = is_some (Class.class_of_locale thy target); |
|
333 val ta = Target {target = target, is_locale = is_locale, is_class = is_class}; |
351 in |
334 in |
352 ctxt |
335 ctxt |
353 |> Data.put (if is_loc then SOME loc else NONE) |
336 |> Data.put ta |
354 |> fold Class.init (the_list (Class.class_of_locale thy loc)) |
337 |> is_class ? Class.init target |
355 |> LocalTheory.init (NameSpace.base loc) |
338 |> LocalTheory.init (NameSpace.base target) |
356 {pretty = pretty loc, |
339 {pretty = pretty ta, |
357 axioms = local_axioms loc, |
340 axioms = local_axioms ta, |
358 abbrev = abbrev loc, |
341 abbrev = abbrev ta, |
359 def = local_def loc, |
342 def = local_def ta, |
360 notes = local_notes loc, |
343 notes = local_notes ta, |
361 type_syntax = type_syntax loc, |
344 type_syntax = type_syntax ta, |
362 term_syntax = term_syntax loc, |
345 term_syntax = term_syntax ta, |
363 declaration = declaration loc, |
346 declaration = declaration ta, |
364 target_naming = target_naming loc, |
347 target_naming = target_naming ta, |
365 reinit = fn _ => |
348 reinit = fn _ => |
366 (if is_loc then Locale.init loc else ProofContext.init) |
349 (if is_locale then Locale.init target else ProofContext.init) |
367 #> begin loc, |
350 #> begin target, |
368 exit = LocalTheory.target_of} |
351 exit = LocalTheory.target_of} |
369 end; |
352 end; |
370 |
353 |
371 fun init NONE thy = begin "" (ProofContext.init thy) |
354 fun init NONE thy = begin "" (ProofContext.init thy) |
372 | init (SOME loc) thy = begin loc (Locale.init loc thy); |
355 | init (SOME target) thy = begin target (Locale.init target thy); |
373 |
356 |
374 fun init_cmd (SOME "-") thy = init NONE thy |
357 fun init_cmd (SOME "-") thy = init NONE thy |
375 | init_cmd loc thy = init (Option.map (Locale.intern thy) loc) thy; |
358 | init_cmd target thy = init (Option.map (Locale.intern thy) target) thy; |
376 |
359 |
377 end; |
360 end; |