39 val typ_morph = Element.inst_morphism thy |
39 val typ_morph = Element.inst_morphism thy |
40 (Symtab.empty |> Symtab.update (Name.aT, TFree (Name.aT, [class])), Symtab.empty); |
40 (Symtab.empty |> Symtab.update (Name.aT, TFree (Name.aT, [class])), Symtab.empty); |
41 val (([raw_props], [(_, raw_inst_morph)], export_morph), _) = empty_ctxt |
41 val (([raw_props], [(_, raw_inst_morph)], export_morph), _) = empty_ctxt |
42 |> Expression.cert_goal_expression ([(class, (("", false), |
42 |> Expression.cert_goal_expression ([(class, (("", false), |
43 Expression.Named param_map_const))], []); |
43 Expression.Named param_map_const))], []); |
44 val (props, inst_morph) = if null param_map |
44 val (props, inst_morph) = |
|
45 if null param_map |
45 then (raw_props |> map (Morphism.term typ_morph), |
46 then (raw_props |> map (Morphism.term typ_morph), |
46 raw_inst_morph $> typ_morph) |
47 raw_inst_morph $> typ_morph) |
47 else (raw_props, raw_inst_morph); (*FIXME proper handling in |
48 else (raw_props, raw_inst_morph); (*FIXME proper handling in |
48 locale.ML / expression.ML would be desirable*) |
49 locale.ML / expression.ML would be desirable*) |
49 |
50 |
50 (* witness for canonical interpretation *) |
51 (* witness for canonical interpretation *) |
51 val prop = try the_single props; |
52 val prop = try the_single props; |
52 val wit = Option.map (fn prop => let |
53 val wit = Option.map (fn prop => |
|
54 let |
53 val sup_axioms = map_filter (fst o Class.rules thy) sups; |
55 val sup_axioms = map_filter (fst o Class.rules thy) sups; |
54 val loc_intro_tac = case Locale.intros_of thy class |
56 val loc_intro_tac = |
55 of (_, NONE) => all_tac |
57 (case Locale.intros_of thy class of |
56 | (_, SOME intro) => ALLGOALS (Tactic.rtac intro); |
58 (_, NONE) => all_tac |
|
59 | (_, SOME intro) => ALLGOALS (Tactic.rtac intro)); |
57 val tac = loc_intro_tac |
60 val tac = loc_intro_tac |
58 THEN ALLGOALS (Proof_Context.fact_tac (sup_axioms @ the_list assm_axiom)) |
61 THEN ALLGOALS (Proof_Context.fact_tac (sup_axioms @ the_list assm_axiom)); |
59 in Element.prove_witness empty_ctxt prop tac end) prop; |
62 in Element.prove_witness empty_ctxt prop tac end) prop; |
60 val axiom = Option.map Element.conclude_witness wit; |
63 val axiom = Option.map Element.conclude_witness wit; |
61 |
64 |
62 (* canonical interpretation *) |
65 (* canonical interpretation *) |
63 val base_morph = inst_morph |
66 val base_morph = inst_morph |
67 |
70 |
68 (* assm_intro *) |
71 (* assm_intro *) |
69 fun prove_assm_intro thm = |
72 fun prove_assm_intro thm = |
70 let |
73 let |
71 val ((_, [thm']), _) = Variable.import true [thm] empty_ctxt; |
74 val ((_, [thm']), _) = Variable.import true [thm] empty_ctxt; |
72 val const_eq_morph = case eq_morph |
75 val const_eq_morph = |
73 of SOME eq_morph => const_morph $> eq_morph |
76 (case eq_morph of |
74 | NONE => const_morph |
77 SOME eq_morph => const_morph $> eq_morph |
|
78 | NONE => const_morph); |
75 val thm'' = Morphism.thm const_eq_morph thm'; |
79 val thm'' = Morphism.thm const_eq_morph thm'; |
76 val tac = ALLGOALS (Proof_Context.fact_tac [thm'']); |
80 val tac = ALLGOALS (Proof_Context.fact_tac [thm'']); |
77 in Skip_Proof.prove_global thy [] [] (Thm.prop_of thm'') (K tac) end; |
81 in Skip_Proof.prove_global thy [] [] (Thm.prop_of thm'') (K tac) end; |
78 val assm_intro = Option.map prove_assm_intro |
82 val assm_intro = Option.map prove_assm_intro |
79 (fst (Locale.intros_of thy class)); |
83 (fst (Locale.intros_of thy class)); |
80 |
84 |
81 (* of_class *) |
85 (* of_class *) |
82 val of_class_prop_concl = Logic.mk_of_class (aT, class); |
86 val of_class_prop_concl = Logic.mk_of_class (aT, class); |
83 val of_class_prop = case prop of NONE => of_class_prop_concl |
87 val of_class_prop = |
|
88 (case prop of |
|
89 NONE => of_class_prop_concl |
84 | SOME prop => Logic.mk_implies (Morphism.term const_morph |
90 | SOME prop => Logic.mk_implies (Morphism.term const_morph |
85 ((map_types o map_atyps) (K aT) prop), of_class_prop_concl); |
91 ((map_types o map_atyps) (K aT) prop), of_class_prop_concl)); |
86 val sup_of_classes = map (snd o Class.rules thy) sups; |
92 val sup_of_classes = map (snd o Class.rules thy) sups; |
87 val loc_axiom_intros = map Drule.export_without_context_open (Locale.axioms_of thy class); |
93 val loc_axiom_intros = map Drule.export_without_context_open (Locale.axioms_of thy class); |
88 val axclass_intro = #intro (AxClass.get_info thy class); |
94 val axclass_intro = #intro (AxClass.get_info thy class); |
89 val base_sort_trivs = Thm.of_sort (Thm.ctyp_of thy aT, base_sort); |
95 val base_sort_trivs = Thm.of_sort (Thm.ctyp_of thy aT, base_sort); |
90 val tac = REPEAT (SOMEGOAL |
96 val tac = |
91 (Tactic.match_tac (axclass_intro :: sup_of_classes |
97 REPEAT (SOMEGOAL |
92 @ loc_axiom_intros @ base_sort_trivs) |
98 (Tactic.match_tac (axclass_intro :: sup_of_classes @ loc_axiom_intros @ base_sort_trivs) |
93 ORELSE' Tactic.assume_tac)); |
99 ORELSE' Tactic.assume_tac)); |
94 val of_class = Skip_Proof.prove_global thy [] [] of_class_prop (K tac); |
100 val of_class = Skip_Proof.prove_global thy [] [] of_class_prop (K tac); |
95 |
101 |
96 in (base_morph, eq_morph, export_morph, axiom, assm_intro, of_class) end; |
102 in (base_morph, eq_morph, export_morph, axiom, assm_intro, of_class) end; |
97 |
103 |
98 |
104 |
108 if null sups then Sign.defaultS thy |
114 if null sups then Sign.defaultS thy |
109 else fold inter_sort (map (Class.base_sort thy) sups) []; |
115 else fold inter_sort (map (Class.base_sort thy) sups) []; |
110 val base_constraints = (map o apsnd) |
116 val base_constraints = (map o apsnd) |
111 (map_type_tfree (K (TVar ((Name.aT, 0), proto_base_sort))) o fst o snd) |
117 (map_type_tfree (K (TVar ((Name.aT, 0), proto_base_sort))) o fst o snd) |
112 (Class.these_operations thy sups); |
118 (Class.these_operations thy sups); |
113 val reject_bcd_etc = (map o map_atyps) (fn T as TFree (v, sort) => |
119 val reject_bcd_etc = (map o map_atyps) (fn T as TFree (a, _) => |
114 if v = Name.aT then T |
120 if a = Name.aT then T |
115 else error ("No type variable other than " ^ Name.aT ^ " allowed in class specification") |
121 else error ("No type variable other than " ^ Name.aT ^ " allowed in class specification") |
116 | T => T); |
122 | T => T); |
117 fun singleton_fixate Ts = |
123 fun singleton_fixate Ts = |
118 let |
124 let |
119 fun extract f = (fold o fold_atyps) f Ts []; |
125 fun extract f = (fold o fold_atyps) f Ts []; |
121 val inferred_sort = extract (fn TVar (_, sort) => inter_sort sort | _ => I); |
127 val inferred_sort = extract (fn TVar (_, sort) => inter_sort sort | _ => I); |
122 val fixate_sort = |
128 val fixate_sort = |
123 if null tfrees then inferred_sort |
129 if null tfrees then inferred_sort |
124 else |
130 else |
125 (case tfrees of |
131 (case tfrees of |
126 [(_, a_sort)] => if Sorts.sort_le algebra (a_sort, inferred_sort) |
132 [(_, a_sort)] => |
127 then inter_sort a_sort inferred_sort |
133 if Sorts.sort_le algebra (a_sort, inferred_sort) then |
128 else error ("Type inference imposes additional sort constraint " |
134 inter_sort a_sort inferred_sort |
129 ^ Syntax.string_of_sort_global thy inferred_sort |
135 else |
130 ^ " of type parameter " ^ Name.aT ^ " of sort " |
136 error ("Type inference imposes additional sort constraint " ^ |
131 ^ Syntax.string_of_sort_global thy a_sort) |
137 Syntax.string_of_sort_global thy inferred_sort ^ |
|
138 " of type parameter " ^ Name.aT ^ " of sort " ^ |
|
139 Syntax.string_of_sort_global thy a_sort) |
132 | _ => error "Multiple type variables in class specification"); |
140 | _ => error "Multiple type variables in class specification"); |
133 in (map o map_atyps) (K (TFree (Name.aT, fixate_sort))) Ts end; |
141 in (map o map_atyps) (K (TFree (Name.aT, fixate_sort))) Ts end; |
134 fun after_infer_fixate Ts = |
142 fun after_infer_fixate Ts = |
135 let |
143 let |
136 val sort' = (fold o fold_atyps) (fn T as TFree _ => I | T as TVar (vi, sort) => |
144 val S' = |
137 if Type_Infer.is_param vi then inter_sort sort else I) Ts []; |
145 (fold o fold_atyps) |
|
146 (fn TVar (xi, S) => if Type_Infer.is_param xi then inter_sort S else I | _ => I) Ts []; |
138 in |
147 in |
139 (map o map_atyps) |
148 (map o map_atyps) |
140 (fn T as TFree _ => T | T as TVar (vi, _) => |
149 (fn T as TVar (xi, _) => |
141 if Type_Infer.is_param vi then Type_Infer.param 0 (Name.aT, sort') else T) Ts |
150 if Type_Infer.is_param xi then Type_Infer.param 0 (Name.aT, S') else T |
|
151 | T => T) Ts |
142 end; |
152 end; |
143 |
153 |
144 (* preprocessing elements, retrieving base sort from type-checked elements *) |
154 (* preprocessing elements, retrieving base sort from type-checked elements *) |
145 val raw_supexpr = |
155 val raw_supexpr = |
146 (map (fn sup => (sup, (("", false), Expression.Positional []))) sups, []); |
156 (map (fn sup => (sup, (("", false), Expression.Positional []))) sups, []); |
191 fun prep_class_spec prep_class prep_class_elems thy raw_supclasses raw_elems = |
201 fun prep_class_spec prep_class prep_class_elems thy raw_supclasses raw_elems = |
192 let |
202 let |
193 |
203 |
194 (* prepare import *) |
204 (* prepare import *) |
195 val inter_sort = curry (Sorts.inter_sort (Sign.classes_of thy)); |
205 val inter_sort = curry (Sorts.inter_sort (Sign.classes_of thy)); |
196 val sups = map (prep_class thy) raw_supclasses |
206 val sups = Sign.minimize_sort thy (map (prep_class thy) raw_supclasses); |
197 |> Sign.minimize_sort thy; |
207 val _ = |
198 val _ = case filter_out (Class.is_class thy) sups |
208 (case filter_out (Class.is_class thy) sups of |
199 of [] => () |
209 [] => () |
200 | no_classes => error ("No (proper) classes: " ^ commas (map quote no_classes)); |
210 | no_classes => error ("No (proper) classes: " ^ commas_quote no_classes)); |
201 val raw_supparams = (map o apsnd) (snd o snd) (Class.these_params thy sups); |
211 val raw_supparams = (map o apsnd) (snd o snd) (Class.these_params thy sups); |
202 val raw_supparam_names = map fst raw_supparams; |
212 val raw_supparam_names = map fst raw_supparams; |
203 val _ = if has_duplicates (op =) raw_supparam_names |
213 val _ = |
204 then error ("Duplicate parameter(s) in superclasses: " |
214 if has_duplicates (op =) raw_supparam_names then |
205 ^ (commas o map quote o duplicates (op =)) raw_supparam_names) |
215 error ("Duplicate parameter(s) in superclasses: " ^ |
|
216 (commas_quote (duplicates (op =) raw_supparam_names))) |
206 else (); |
217 else (); |
207 |
218 |
208 (* infer types and base sort *) |
219 (* infer types and base sort *) |
209 val (base_sort, supparam_names, supexpr, inferred_elems) = |
220 val (base_sort, supparam_names, supexpr, inferred_elems) = prep_class_elems thy sups raw_elems; |
210 prep_class_elems thy sups raw_elems; |
|
211 val sup_sort = inter_sort base_sort sups; |
221 val sup_sort = inter_sort base_sort sups; |
212 |
222 |
213 (* process elements as class specification *) |
223 (* process elements as class specification *) |
214 val class_ctxt = Class.begin sups base_sort (Proof_Context.init_global thy); |
224 val class_ctxt = Class.begin sups base_sort (Proof_Context.init_global thy); |
215 val ((_, _, syntax_elems), _) = class_ctxt |
225 val ((_, _, syntax_elems), _) = class_ctxt |
216 |> Expression.cert_declaration supexpr I inferred_elems; |
226 |> Expression.cert_declaration supexpr I inferred_elems; |
217 fun check_vars e vs = if null vs |
227 fun check_vars e vs = |
218 then error ("No type variable in part of specification element " |
228 if null vs then |
219 ^ (Pretty.string_of o Pretty.chunks) (Element.pretty_ctxt class_ctxt e)) |
229 error ("No type variable in part of specification element " ^ |
|
230 Pretty.string_of (Pretty.chunks (Element.pretty_ctxt class_ctxt e))) |
220 else (); |
231 else (); |
221 fun check_element (e as Element.Fixes fxs) = |
232 fun check_element (e as Element.Fixes fxs) = |
222 map (fn (_, SOME T, _) => check_vars e (Term.add_tfreesT T [])) fxs |
233 List.app (fn (_, SOME T, _) => check_vars e (Term.add_tfreesT T [])) fxs |
223 | check_element (e as Element.Assumes assms) = |
234 | check_element (e as Element.Assumes assms) = |
224 maps (fn (_, ts_pss) => map |
235 List.app (fn (_, ts_pss) => |
225 (fn (t, _) => check_vars e (Term.add_tfrees t [])) ts_pss) assms |
236 List.app (fn (t, _) => check_vars e (Term.add_tfrees t [])) ts_pss) assms |
226 | check_element e = [()]; |
237 | check_element _ = (); |
227 val _ = map check_element syntax_elems; |
238 val _ = List.app check_element syntax_elems; |
228 fun fork_syn (Element.Fixes xs) = |
239 fun fork_syn (Element.Fixes xs) = |
229 fold_map (fn (c, ty, syn) => cons (c, syn) #> pair (c, ty, NoSyn)) xs |
240 fold_map (fn (c, ty, syn) => cons (c, syn) #> pair (c, ty, NoSyn)) xs |
230 #>> Element.Fixes |
241 #>> Element.Fixes |
231 | fork_syn x = pair x; |
242 | fork_syn x = pair x; |
232 val (elems, global_syntax) = fold_map fork_syn syntax_elems []; |
243 val (elems, global_syntax) = fold_map fork_syn syntax_elems []; |
276 (fn Free (v, ty) => Const ((fst o the o AList.lookup (op =) param_map) v, ty) |
287 (fn Free (v, ty) => Const ((fst o the o AList.lookup (op =) param_map) v, ty) |
277 | t => t); |
288 | t => t); |
278 val raw_pred = Locale.intros_of thy class |
289 val raw_pred = Locale.intros_of thy class |
279 |> fst |
290 |> fst |
280 |> Option.map (Logic.unvarify_global o Logic.strip_imp_concl o Thm.prop_of); |
291 |> Option.map (Logic.unvarify_global o Logic.strip_imp_concl o Thm.prop_of); |
281 fun get_axiom thy = case (#axioms o AxClass.get_info thy) class |
292 fun get_axiom thy = |
282 of [] => NONE |
293 (case #axioms (AxClass.get_info thy class) of |
283 | [thm] => SOME thm; |
294 [] => NONE |
|
295 | [thm] => SOME thm); |
284 in |
296 in |
285 thy |
297 thy |
286 |> add_consts class base_sort sups supparam_names global_syntax |
298 |> add_consts class base_sort sups supparam_names global_syntax |
287 |-> (fn (param_map, params) => AxClass.define_class (bname, supsort) |
299 |-> (fn (param_map, params) => AxClass.define_class (bname, supsort) |
288 (map (fst o snd) params) |
300 (map (fst o snd) params) |
329 |
341 |
330 fun gen_subclass prep_class do_proof before_exit raw_sup lthy = |
342 fun gen_subclass prep_class do_proof before_exit raw_sup lthy = |
331 let |
343 let |
332 val thy = Proof_Context.theory_of lthy; |
344 val thy = Proof_Context.theory_of lthy; |
333 val proto_sup = prep_class thy raw_sup; |
345 val proto_sup = prep_class thy raw_sup; |
334 val proto_sub = case Named_Target.peek lthy |
346 val proto_sub = |
335 of SOME {target, is_class = true, ...} => target |
347 (case Named_Target.peek lthy of |
336 | _ => error "Not in a class target"; |
348 SOME {target, is_class = true, ...} => target |
|
349 | _ => error "Not in a class target"); |
337 val (sub, sup) = AxClass.cert_classrel thy (proto_sub, proto_sup); |
350 val (sub, sup) = AxClass.cert_classrel thy (proto_sub, proto_sup); |
338 |
351 |
339 val expr = ([(sup, (("", false), Expression.Positional []))], []); |
352 val expr = ([(sup, (("", false), Expression.Positional []))], []); |
340 val (([props], deps, export), goal_ctxt) = |
353 val (([props], deps, export), goal_ctxt) = |
341 Expression.cert_goal_expression expr lthy; |
354 Expression.cert_goal_expression expr lthy; |