75 |
75 |
76 }; |
76 }; |
77 |
77 |
78 fun make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom), |
78 fun make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom), |
79 (defs, operations)) = |
79 (defs, operations)) = |
80 ClassData { consts = consts, base_sort = base_sort, |
80 Class_Data {consts = consts, base_sort = base_sort, |
81 base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro, |
81 base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro, |
82 of_class = of_class, axiom = axiom, defs = defs, operations = operations }; |
82 of_class = of_class, axiom = axiom, defs = defs, operations = operations}; |
83 fun map_class_data f (ClassData { consts, base_sort, base_morph, export_morph, assm_intro, |
83 fun map_class_data f (Class_Data {consts, base_sort, base_morph, export_morph, assm_intro, |
84 of_class, axiom, defs, operations }) = |
84 of_class, axiom, defs, operations}) = |
85 make_class_data (f ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom), |
85 make_class_data (f ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom), |
86 (defs, operations))); |
86 (defs, operations))); |
87 fun merge_class_data _ (ClassData { consts = consts, |
87 fun merge_class_data _ (Class_Data {consts = consts, |
88 base_sort = base_sort, base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro, |
88 base_sort = base_sort, base_morph = base_morph, export_morph = export_morph, assm_intro = assm_intro, |
89 of_class = of_class, axiom = axiom, defs = defs1, operations = operations1 }, |
89 of_class = of_class, axiom = axiom, defs = defs1, operations = operations1}, |
90 ClassData { consts = _, base_sort = _, base_morph = _, export_morph = _, assm_intro = _, |
90 Class_Data {consts = _, base_sort = _, base_morph = _, export_morph = _, assm_intro = _, |
91 of_class = _, axiom = _, defs = defs2, operations = operations2 }) = |
91 of_class = _, axiom = _, defs = defs2, operations = operations2}) = |
92 make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom), |
92 make_class_data ((consts, base_sort, base_morph, export_morph, assm_intro, of_class, axiom), |
93 (Thm.merge_thms (defs1, defs2), |
93 (Thm.merge_thms (defs1, defs2), |
94 AList.merge (op =) (K true) (operations1, operations2))); |
94 AList.merge (op =) (K true) (operations1, operations2))); |
95 |
95 |
96 structure ClassData = Theory_Data |
96 structure Class_Data = Theory_Data |
97 ( |
97 ( |
98 type T = class_data Graph.T |
98 type T = class_data Graph.T |
99 val empty = Graph.empty; |
99 val empty = Graph.empty; |
100 val extend = I; |
100 val extend = I; |
101 val merge = Graph.join merge_class_data; |
101 val merge = Graph.join merge_class_data; |
102 ); |
102 ); |
103 |
103 |
104 |
104 |
105 (* queries *) |
105 (* queries *) |
106 |
106 |
107 fun lookup_class_data thy class = case try (Graph.get_node (ClassData.get thy)) class |
107 fun lookup_class_data thy class = |
108 of SOME (ClassData data) => SOME data |
108 (case try (Graph.get_node (Class_Data.get thy)) class of |
109 | NONE => NONE; |
109 SOME (Class_Data data) => SOME data |
110 |
110 | NONE => NONE); |
111 fun the_class_data thy class = case lookup_class_data thy class |
111 |
112 of NONE => error ("Undeclared class " ^ quote class) |
112 fun the_class_data thy class = |
113 | SOME data => data; |
113 (case lookup_class_data thy class of |
|
114 NONE => error ("Undeclared class " ^ quote class) |
|
115 | SOME data => data); |
114 |
116 |
115 val is_class = is_some oo lookup_class_data; |
117 val is_class = is_some oo lookup_class_data; |
116 |
118 |
117 val ancestry = Graph.all_succs o ClassData.get; |
119 val ancestry = Graph.all_succs o Class_Data.get; |
118 val heritage = Graph.all_preds o ClassData.get; |
120 val heritage = Graph.all_preds o Class_Data.get; |
119 |
121 |
120 fun these_params thy = |
122 fun these_params thy = |
121 let |
123 let |
122 fun params class = |
124 fun params class = |
123 let |
125 let |
130 in maps params o ancestry thy end; |
132 in maps params o ancestry thy end; |
131 |
133 |
132 val base_sort = #base_sort oo the_class_data; |
134 val base_sort = #base_sort oo the_class_data; |
133 |
135 |
134 fun rules thy class = |
136 fun rules thy class = |
135 let val { axiom, of_class, ... } = the_class_data thy class |
137 let val {axiom, of_class, ...} = the_class_data thy class |
136 in (axiom, of_class) end; |
138 in (axiom, of_class) end; |
137 |
139 |
138 fun all_assm_intros thy = |
140 fun all_assm_intros thy = |
139 Graph.fold (fn (_, (ClassData { assm_intro, ... }, _)) => fold (insert Thm.eq_thm) |
141 Graph.fold (fn (_, (Class_Data {assm_intro, ...}, _)) => fold (insert Thm.eq_thm) |
140 (the_list assm_intro)) (ClassData.get thy) []; |
142 (the_list assm_intro)) (Class_Data.get thy) []; |
141 |
143 |
142 fun these_defs thy = maps (#defs o the_class_data thy) o ancestry thy; |
144 fun these_defs thy = maps (#defs o the_class_data thy) o ancestry thy; |
143 fun these_operations thy = maps (#operations o the_class_data thy) o ancestry thy; |
145 fun these_operations thy = maps (#operations o the_class_data thy) o ancestry thy; |
144 |
146 |
145 val base_morphism = #base_morph oo the_class_data; |
147 val base_morphism = #base_morph oo the_class_data; |
146 fun morphism thy class = case Element.eq_morphism thy (these_defs thy [class]) |
148 fun morphism thy class = |
147 of SOME eq_morph => base_morphism thy class $> eq_morph |
149 (case Element.eq_morphism thy (these_defs thy [class]) of |
148 | NONE => base_morphism thy class; |
150 SOME eq_morph => base_morphism thy class $> eq_morph |
|
151 | NONE => base_morphism thy class); |
149 val export_morphism = #export_morph oo the_class_data; |
152 val export_morphism = #export_morph oo the_class_data; |
150 |
153 |
151 fun print_classes ctxt = |
154 fun print_classes ctxt = |
152 let |
155 let |
153 val thy = Proof_Context.theory_of ctxt; |
156 val thy = Proof_Context.theory_of ctxt; |
192 (c, (class, (ty, Free v_ty)))) params; |
195 (c, (class, (ty, Free v_ty)))) params; |
193 val add_class = Graph.new_node (class, |
196 val add_class = Graph.new_node (class, |
194 make_class_data (((map o pairself) fst params, base_sort, |
197 make_class_data (((map o pairself) fst params, base_sort, |
195 base_morph, export_morph, assm_intro, of_class, axiom), ([], operations))) |
198 base_morph, export_morph, assm_intro, of_class, axiom), ([], operations))) |
196 #> fold (curry Graph.add_edge class) sups; |
199 #> fold (curry Graph.add_edge class) sups; |
197 in ClassData.map add_class thy end; |
200 in Class_Data.map add_class thy end; |
198 |
201 |
199 fun activate_defs class thms thy = case Element.eq_morphism thy thms |
202 fun activate_defs class thms thy = |
200 of SOME eq_morph => fold (fn cls => fn thy => |
203 (case Element.eq_morphism thy thms of |
|
204 SOME eq_morph => fold (fn cls => fn thy => |
201 Context.theory_map (Locale.amend_registration (cls, base_morphism thy cls) |
205 Context.theory_map (Locale.amend_registration (cls, base_morphism thy cls) |
202 (eq_morph, true) (export_morphism thy cls)) thy) (heritage thy [class]) thy |
206 (eq_morph, true) (export_morphism thy cls)) thy) (heritage thy [class]) thy |
203 | NONE => thy; |
207 | NONE => thy); |
204 |
208 |
205 fun register_operation class (c, (t, some_def)) thy = |
209 fun register_operation class (c, (t, some_def)) thy = |
206 let |
210 let |
207 val base_sort = base_sort thy class; |
211 val base_sort = base_sort thy class; |
208 val prep_typ = map_type_tfree |
212 val prep_typ = map_type_tfree |
210 then TFree (v, base_sort) else TVar ((v, 0), sort)); |
214 then TFree (v, base_sort) else TVar ((v, 0), sort)); |
211 val t' = map_types prep_typ t; |
215 val t' = map_types prep_typ t; |
212 val ty' = Term.fastype_of t'; |
216 val ty' = Term.fastype_of t'; |
213 in |
217 in |
214 thy |
218 thy |
215 |> (ClassData.map o Graph.map_node class o map_class_data o apsnd) |
219 |> (Class_Data.map o Graph.map_node class o map_class_data o apsnd) |
216 (fn (defs, operations) => |
220 (fn (defs, operations) => |
217 (fold cons (the_list some_def) defs, |
221 (fold cons (the_list some_def) defs, |
218 (c, (class, (ty', t'))) :: operations)) |
222 (c, (class, (ty', t'))) :: operations)) |
219 |> activate_defs class (the_list some_def) |
223 |> activate_defs class (the_list some_def) |
220 end; |
224 end; |
228 val classrel = Skip_Proof.prove_global thy [] [] (Logic.mk_classrel (sub, sup)) |
232 val classrel = Skip_Proof.prove_global thy [] [] (Logic.mk_classrel (sub, sup)) |
229 (K tac); |
233 (K tac); |
230 val diff_sort = Sign.complete_sort thy [sup] |
234 val diff_sort = Sign.complete_sort thy [sup] |
231 |> subtract (op =) (Sign.complete_sort thy [sub]) |
235 |> subtract (op =) (Sign.complete_sort thy [sub]) |
232 |> filter (is_class thy); |
236 |> filter (is_class thy); |
233 val add_dependency = case some_dep_morph |
237 val add_dependency = |
234 of SOME dep_morph => Locale.add_dependency sub |
238 (case some_dep_morph of |
|
239 SOME dep_morph => Locale.add_dependency sub |
235 (sup, dep_morph $> Element.satisfy_morphism (the_list some_wit)) NONE export |
240 (sup, dep_morph $> Element.satisfy_morphism (the_list some_wit)) NONE export |
236 | NONE => I |
241 | NONE => I); |
237 in |
242 in |
238 thy |
243 thy |
239 |> AxClass.add_classrel classrel |
244 |> AxClass.add_classrel classrel |
240 |> ClassData.map (Graph.add_edge (sub, sup)) |
245 |> Class_Data.map (Graph.add_edge (sub, sup)) |
241 |> activate_defs sub (these_defs thy diff_sort) |
246 |> activate_defs sub (these_defs thy diff_sort) |
242 |> add_dependency |
247 |> add_dependency |
243 end; |
248 end; |
244 |
249 |
245 |
250 |
262 fun subst_class_typ sort = map_type_tfree (K (TVar ((Name.aT, 0), sort))); |
267 fun subst_class_typ sort = map_type_tfree (K (TVar ((Name.aT, 0), sort))); |
263 val primary_constraints = |
268 val primary_constraints = |
264 (map o apsnd) (subst_class_typ base_sort o fst o snd) operations; |
269 (map o apsnd) (subst_class_typ base_sort o fst o snd) operations; |
265 val secondary_constraints = |
270 val secondary_constraints = |
266 (map o apsnd) (fn (class, (ty, _)) => subst_class_typ [class] ty) operations; |
271 (map o apsnd) (fn (class, (ty, _)) => subst_class_typ [class] ty) operations; |
267 fun improve (c, ty) = (case AList.lookup (op =) primary_constraints c |
272 fun improve (c, ty) = |
268 of SOME ty' => (case try (Type.raw_match (ty', ty)) Vartab.empty |
273 (case AList.lookup (op =) primary_constraints c of |
269 of SOME tyenv => (case Vartab.lookup tyenv (Name.aT, 0) |
274 SOME ty' => |
270 of SOME (_, ty' as TVar (vi, sort)) => |
275 (case try (Type.raw_match (ty', ty)) Vartab.empty of |
271 if Type_Infer.is_param vi |
276 SOME tyenv => |
272 andalso Sorts.sort_le algebra (base_sort, sort) |
277 (case Vartab.lookup tyenv (Name.aT, 0) of |
273 then SOME (ty', TFree (Name.aT, base_sort)) |
278 SOME (_, ty' as TVar (vi, sort)) => |
274 else NONE |
279 if Type_Infer.is_param vi andalso Sorts.sort_le algebra (base_sort, sort) |
|
280 then SOME (ty', TFree (Name.aT, base_sort)) |
|
281 else NONE |
275 | _ => NONE) |
282 | _ => NONE) |
276 | NONE => NONE) |
283 | NONE => NONE) |
277 | NONE => NONE) |
284 | NONE => NONE); |
278 fun subst (c, ty) = Option.map snd (AList.lookup (op =) operations c); |
285 fun subst (c, ty) = Option.map snd (AList.lookup (op =) operations c); |
279 val unchecks = these_unchecks thy sort; |
286 val unchecks = these_unchecks thy sort; |
280 in |
287 in |
281 ctxt |
288 ctxt |
282 |> fold (redeclare_const thy o fst) primary_constraints |
289 |> fold (redeclare_const thy o fst) primary_constraints |
395 (*(instantiation parameter, type constructor), (local instantiation parameter, typ)*) |
402 (*(instantiation parameter, type constructor), (local instantiation parameter, typ)*) |
396 } |
403 } |
397 |
404 |
398 structure Instantiation = Proof_Data |
405 structure Instantiation = Proof_Data |
399 ( |
406 ( |
400 type T = instantiation |
407 type T = instantiation; |
401 fun init _ = Instantiation { arities = ([], [], []), params = [] }; |
408 fun init _ = Instantiation {arities = ([], [], []), params = []}; |
402 ); |
409 ); |
403 |
410 |
404 fun mk_instantiation (arities, params) = |
411 fun mk_instantiation (arities, params) = |
405 Instantiation { arities = arities, params = params }; |
412 Instantiation {arities = arities, params = params}; |
406 fun get_instantiation lthy = case Instantiation.get (Local_Theory.target_of lthy) |
413 |
407 of Instantiation data => data; |
414 val get_instantiation = |
408 fun map_instantiation f = (Local_Theory.target o Instantiation.map) |
415 (fn Instantiation data => data) o Instantiation.get o Local_Theory.target_of; |
409 (fn Instantiation { arities, params } => mk_instantiation (f (arities, params))); |
416 |
410 |
417 fun map_instantiation f = |
411 fun the_instantiation lthy = case get_instantiation lthy |
418 (Local_Theory.target o Instantiation.map) |
412 of { arities = ([], [], []), ... } => error "No instantiation target" |
419 (fn Instantiation {arities, params} => mk_instantiation (f (arities, params))); |
413 | data => data; |
420 |
|
421 fun the_instantiation lthy = |
|
422 (case get_instantiation lthy of |
|
423 {arities = ([], [], []), ...} => error "No instantiation target" |
|
424 | data => data); |
414 |
425 |
415 val instantiation_params = #params o get_instantiation; |
426 val instantiation_params = #params o get_instantiation; |
416 |
427 |
417 fun instantiation_param lthy b = instantiation_params lthy |
428 fun instantiation_param lthy b = instantiation_params lthy |
418 |> find_first (fn (_, (v, _)) => Binding.name_of b = v) |
429 |> find_first (fn (_, (v, _)) => Binding.name_of b = v) |
431 |
442 |
432 (* syntax *) |
443 (* syntax *) |
433 |
444 |
434 fun synchronize_inst_syntax ctxt = |
445 fun synchronize_inst_syntax ctxt = |
435 let |
446 let |
436 val Instantiation { params, ... } = Instantiation.get ctxt; |
447 val Instantiation {params, ...} = Instantiation.get ctxt; |
437 |
448 |
438 val lookup_inst_param = AxClass.lookup_inst_param |
449 val lookup_inst_param = AxClass.lookup_inst_param |
439 (Sign.consts_of (Proof_Context.theory_of ctxt)) params; |
450 (Sign.consts_of (Proof_Context.theory_of ctxt)) params; |
440 fun subst (c, ty) = case lookup_inst_param (c, ty) |
451 fun subst (c, ty) = |
441 of SOME (v_ty as (_, ty)) => SOME (ty, Free v_ty) |
452 (case lookup_inst_param (c, ty) of |
442 | NONE => NONE; |
453 SOME (v_ty as (_, ty)) => SOME (ty, Free v_ty) |
|
454 | NONE => NONE); |
443 val unchecks = |
455 val unchecks = |
444 map (fn ((c, _), v_ty as (_, ty)) => (Free v_ty, Const (c, ty))) params; |
456 map (fn ((c, _), v_ty as (_, ty)) => (Free v_ty, Const (c, ty))) params; |
445 in |
457 in |
446 ctxt |
458 ctxt |
447 |> Overloading.map_improvable_syntax |
459 |> Overloading.map_improvable_syntax |
448 (fn (((primary_constraints, _), (((improve, _), _), _)), _) => |
460 (fn (((primary_constraints, _), (((improve, _), _), _)), _) => |
449 (((primary_constraints, []), (((improve, subst), false), unchecks)), false)) |
461 (((primary_constraints, []), (((improve, subst), false), unchecks)), false)) |
450 end; |
462 end; |
451 |
463 |
452 fun resort_terms ctxt algebra consts constraints ts = |
464 fun resort_terms ctxt algebra consts constraints ts = |
453 let |
465 let |
454 fun matchings (Const (c_ty as (c, _))) = |
466 fun matchings (Const (c_ty as (c, _))) = |
470 (AxClass.declare_overloaded (c, U) ##>> AxClass.define_overloaded b_def (c, rhs)) |
482 (AxClass.declare_overloaded (c, U) ##>> AxClass.define_overloaded b_def (c, rhs)) |
471 ##> (map_instantiation o apsnd) (filter_out (fn (_, (v', _)) => v' = v)) |
483 ##> (map_instantiation o apsnd) (filter_out (fn (_, (v', _)) => v' = v)) |
472 ##> Local_Theory.target synchronize_inst_syntax; |
484 ##> Local_Theory.target synchronize_inst_syntax; |
473 |
485 |
474 fun foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy = |
486 fun foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params) lthy = |
475 case instantiation_param lthy b |
487 (case instantiation_param lthy b of |
476 of SOME c => if mx <> NoSyn then error ("Illegal mixfix syntax for overloaded constant " ^ quote c) |
488 SOME c => |
477 else lthy |> define_overloaded (c, U) (Binding.name_of b) (b_def, rhs) |
489 if mx <> NoSyn then error ("Illegal mixfix syntax for overloaded constant " ^ quote c) |
478 | NONE => lthy |> |
490 else lthy |> define_overloaded (c, U) (Binding.name_of b) (b_def, rhs) |
479 Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params); |
491 | NONE => lthy |> |
|
492 Generic_Target.theory_foundation (((b, U), mx), (b_def, rhs)) (type_params, term_params)); |
480 |
493 |
481 fun pretty lthy = |
494 fun pretty lthy = |
482 let |
495 let |
483 val { arities = (tycos, vs, sort), params } = the_instantiation lthy; |
496 val {arities = (tycos, vs, sort), params} = the_instantiation lthy; |
484 fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort); |
497 fun pr_arity tyco = Syntax.pretty_arity lthy (tyco, map snd vs, sort); |
485 fun pr_param ((c, _), (v, ty)) = |
498 fun pr_param ((c, _), (v, ty)) = |
486 Pretty.block (Pretty.breaks |
499 Pretty.block (Pretty.breaks |
487 [Pretty.str v, Pretty.str "==", Pretty.str (Proof_Context.extern_const lthy c), |
500 [Pretty.str v, Pretty.str "==", Pretty.str (Proof_Context.extern_const lthy c), |
488 Pretty.str "::", Syntax.pretty_typ lthy ty]); |
501 Pretty.str "::", Syntax.pretty_typ lthy ty]); |