1 (* Title: Pure/Tools/class_package.ML |
1 (* Title: Pure/Tools/class_package.ML |
2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Florian Haftmann, TU Muenchen |
3 Author: Florian Haftmann, TU Muenchen |
4 |
4 |
5 Type classes, simulated by locales. |
5 Type classes derived from primitive axclasses and locales. |
6 *) |
6 *) |
7 |
7 |
8 signature CLASS_PACKAGE = |
8 signature CLASS_PACKAGE = |
9 sig |
9 sig |
10 val class: bstring -> class list -> Element.context list -> theory |
10 val class: bstring -> class list -> Element.context list -> theory |
110 :: map (fn (_, (c, ty)) => Pretty.str (c ^ " :: " ^ Sign.string_of_typ thy ty)) consts |
110 :: map (fn (_, (c, ty)) => Pretty.str (c ^ " :: " ^ Sign.string_of_typ thy ty)) consts |
111 ) |
111 ) |
112 ] |
112 ] |
113 in |
113 in |
114 (Pretty.writeln o Pretty.chunks o map (pretty_class gr) |
114 (Pretty.writeln o Pretty.chunks o map (pretty_class gr) |
115 o AList.make (Graph.get_node gr) o Library.flat o Graph.strong_conn) gr |
115 o AList.make (Graph.get_node gr) o flat o Graph.strong_conn) gr |
116 end; |
116 end; |
117 end |
117 end |
118 ); |
118 ); |
119 |
119 |
120 val _ = Context.add_setup ClassData.init; |
120 val _ = Context.add_setup ClassData.init; |
145 if is_operational_class thy class |
145 if is_operational_class thy class |
146 then [class] |
146 then [class] |
147 else operational_sort_of thy (Sign.super_classes thy class); |
147 else operational_sort_of thy (Sign.super_classes thy class); |
148 in |
148 in |
149 map get_sort sort |
149 map get_sort sort |
150 |> Library.flat |
150 |> flat |
151 |> Sign.certify_sort thy |
151 |> Sign.certify_sort thy |
152 end; |
152 end; |
153 |
153 |
154 fun the_superclasses thy class = |
154 fun the_superclasses thy class = |
155 if is_class thy class |
155 if is_class thy class |
191 fun the_consts_sign thy class = |
191 fun the_consts_sign thy class = |
192 let |
192 let |
193 val data = the_class_data thy class |
193 val data = the_class_data thy class |
194 in (#var data, (map snd o #consts) data) end; |
194 in (#var data, (map snd o #consts) data) end; |
195 |
195 |
196 fun mg_domain thy tyco class = |
|
197 Sorts.mg_domain (Sign.classes_of thy, Sign.arities_of thy) tyco [class]; |
|
198 |
|
199 fun the_inst_sign thy (class, tyco) = |
196 fun the_inst_sign thy (class, tyco) = |
200 let |
197 let |
201 val _ = if is_operational_class thy class then () else error ("no operational class: " ^ class); |
198 val _ = if is_operational_class thy class then () else error ("no operational class: " ^ class); |
202 val arity = mg_domain thy tyco class; |
199 val arity = Sign.arity_sorts thy tyco [class]; |
203 val clsvar = (#var o the_class_data thy) class; |
200 val clsvar = (#var o the_class_data thy) class; |
204 val const_sign = (snd o the_consts_sign thy) class; |
201 val const_sign = (snd o the_consts_sign thy) class; |
205 fun add_var sort used = |
202 fun add_var sort used = |
206 let |
203 let |
207 val v = hd (Term.invent_names used "'a" 1) |
204 val v = hd (Term.invent_names used "'a" 1) |
287 |
284 |
288 fun default_tac rules ctxt facts = |
285 fun default_tac rules ctxt facts = |
289 HEADGOAL (Method.some_rule_tac rules ctxt facts) ORELSE |
286 HEADGOAL (Method.some_rule_tac rules ctxt facts) ORELSE |
290 default_intro_classes_tac facts; |
287 default_intro_classes_tac facts; |
291 |
288 |
|
289 val _ = Context.add_setup (Method.add_methods |
|
290 [("intro_classes", Method.no_args (Method.METHOD intro_classes_tac), |
|
291 "back-chain introduction rules of classes"), |
|
292 ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac), |
|
293 "apply some intro/elim rule")]); |
|
294 |
292 |
295 |
293 (* axclass instances *) |
296 (* axclass instances *) |
294 |
297 |
295 local |
298 local |
296 |
299 |
323 in if expr = Locale.empty |
326 in if expr = Locale.empty |
324 then fish_thm name |
327 then fish_thm name |
325 else fish_thm (name ^ "_axioms") |
328 else fish_thm (name ^ "_axioms") |
326 end; |
329 end; |
327 |
330 |
328 fun add_locale opn name expr body thy = |
331 fun add_locale name expr body thy = |
329 thy |
332 thy |
330 |> Locale.add_locale opn name expr body |
333 |> Locale.add_locale true name expr body |
331 ||>> `(fn thy => intro_incr thy name expr) |
334 ||>> `(fn thy => intro_incr thy name expr) |
332 |-> (fn ((name, ctxt), intro) => pair ((name, intro), ctxt)); |
335 |-> (fn ((name, ctxt), intro) => pair ((name, intro), ctxt)); |
333 |
336 |
334 fun add_locale_i opn name expr body thy = |
337 fun add_locale_i name expr body thy = |
335 thy |
338 thy |
336 |> Locale.add_locale_i opn name expr body |
339 |> Locale.add_locale_i true name expr body |
337 ||>> `(fn thy => intro_incr thy name expr) |
340 ||>> `(fn thy => intro_incr thy name expr) |
338 |-> (fn ((name, ctxt), intro) => pair ((name, intro), ctxt)); |
341 |-> (fn ((name, ctxt), intro) => pair ((name, intro), ctxt)); |
339 |
342 |
340 fun add_axclass_i (name, supsort) axs thy = |
343 fun add_axclass_i (name, supsort) axs thy = |
341 let |
344 let |
370 let |
373 let |
371 val supclasses = map (prep_class thy) raw_supclasses; |
374 val supclasses = map (prep_class thy) raw_supclasses; |
372 val supsort = |
375 val supsort = |
373 supclasses |
376 supclasses |
374 |> map (#name_axclass o the_class_data thy) |
377 |> map (#name_axclass o the_class_data thy) |
375 |> Sorts.certify_sort (Sign.classes_of thy) |
378 |> Sign.certify_sort thy |
376 |> null ? K (Sign.defaultS thy); |
379 |> null ? K (Sign.defaultS thy); |
377 val expr = if null supclasses |
380 val expr = (Locale.Merge o map (Locale.Locale o #name_locale o the_class_data thy)) supclasses; |
378 then Locale.empty |
|
379 else |
|
380 (Locale.Merge o map (Locale.Locale o #name_locale o the_class_data thy)) supclasses; |
|
381 val mapp_sup = AList.make |
381 val mapp_sup = AList.make |
382 (the o AList.lookup (op =) ((Library.flat o map (the_parm_map thy) o the_ancestry thy) supclasses)) |
382 (the o AList.lookup (op =) ((flat o map (the_parm_map thy) o the_ancestry thy) supclasses)) |
383 ((map (fst o fst) o Locale.parameters_of_expr thy) expr); |
383 ((map (fst o fst) o Locale.parameters_of_expr thy) expr); |
384 fun extract_tyvar_consts thy name_locale = |
384 fun extract_tyvar_consts thy name_locale = |
385 let |
385 let |
386 fun extract_tyvar_name thy tys = |
386 fun extract_tyvar_name thy tys = |
387 fold (curry add_typ_tfrees) tys [] |
387 fold (curry add_typ_tfrees) tys [] |
388 |> (fn [(v, sort)] => |
388 |> (fn [(v, sort)] => |
389 if Sorts.sort_le (Sign.classes_of thy) (swap (sort, supsort)) |
389 if Sign.subsort thy (supsort, sort) |
390 then v |
390 then v |
391 else error ("illegal sort constraint on class type variable: " ^ Sign.string_of_sort thy sort) |
391 else error ("illegal sort constraint on class type variable: " ^ Sign.string_of_sort thy sort) |
392 | [] => error ("no class type variable") |
392 | [] => error ("no class type variable") |
393 | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs)) |
393 | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs)) |
394 val consts1 = |
394 val consts1 = |
499 let |
499 let |
500 val data = the_class_data theory class; |
500 val data = the_class_data theory class; |
501 val subst_ty = map_type_tfree (fn (var as (v, _)) => |
501 val subst_ty = map_type_tfree (fn (var as (v, _)) => |
502 if #var data = v then ty_inst else TFree var) |
502 if #var data = v then ty_inst else TFree var) |
503 in (map (apsnd subst_ty o snd) o #consts) data end; |
503 in (map (apsnd subst_ty o snd) o #consts) data end; |
504 val cs = (Library.flat o map get_consts) classes; |
504 val cs = (flat o map get_consts) classes; |
505 fun get_remove_contraint c thy = |
505 fun get_remove_contraint c thy = |
506 let |
506 let |
507 val ty = Sign.the_const_constraint thy c; |
507 val ty = Sign.the_const_constraint thy c; |
508 in |
508 in |
509 thy |
509 thy |
607 fun gen_instance_sort prep_class prep_sort do_proof (raw_class, raw_sort) theory = |
607 fun gen_instance_sort prep_class prep_sort do_proof (raw_class, raw_sort) theory = |
608 let |
608 let |
609 val class = prep_class theory raw_class; |
609 val class = prep_class theory raw_class; |
610 val sort = prep_sort theory raw_sort; |
610 val sort = prep_sort theory raw_sort; |
611 val loc_name = (#name_locale o the_class_data theory) class; |
611 val loc_name = (#name_locale o the_class_data theory) class; |
612 val loc_expr = if null sort |
612 val loc_expr = |
613 then Locale.empty |
613 (Locale.Merge o map (Locale.Locale o #name_locale o the_class_data theory)) sort; |
614 else |
|
615 (Locale.Merge o map (Locale.Locale o #name_locale o the_class_data theory)) sort; |
|
616 fun after_qed thmss thy = |
614 fun after_qed thmss thy = |
617 (writeln "---"; (Pretty.writeln o Display.pretty_thms o Library.flat) thmss; writeln "---"; fold (fn supclass => |
615 (writeln "---"; (Pretty.writeln o Display.pretty_thms o flat) thmss; writeln "---"; fold (fn supclass => |
618 AxClass.prove_classrel (class, supclass) |
616 AxClass.prove_classrel (class, supclass) |
619 (ALLGOALS (K (intro_classes_tac [])) THEN |
617 (ALLGOALS (K (intro_classes_tac [])) THEN |
620 (ALLGOALS o resolve_tac o Library.flat) thmss) |
618 (ALLGOALS o resolve_tac o flat) thmss) |
621 ) sort thy) |
619 ) sort thy) |
622 in |
620 in |
623 theory |
621 theory |
624 |> do_proof after_qed (loc_name, loc_expr) |
622 |> do_proof after_qed (loc_name, loc_expr) |
625 end; |
623 end; |
671 ) subclasses; |
669 ) subclasses; |
672 in (rev deriv, (i, length subclasses)) end; |
670 in (rev deriv, (i, length subclasses)) end; |
673 fun mk_lookup (sort_def, (Type (tyco, tys))) = |
671 fun mk_lookup (sort_def, (Type (tyco, tys))) = |
674 map (fn class => Instance ((class, tyco), |
672 map (fn class => Instance ((class, tyco), |
675 map2 (curry mk_lookup) |
673 map2 (curry mk_lookup) |
676 (map (operational_sort_of thy) (mg_domain thy tyco class)) |
674 (map (operational_sort_of thy) (Sign.arity_sorts thy tyco [class])) |
677 tys) |
675 tys) |
678 ) sort_def |
676 ) sort_def |
679 | mk_lookup (sort_def, TVar ((vname, _), sort_use)) = |
677 | mk_lookup (sort_def, TVar ((vname, _), sort_use)) = |
680 let |
678 let |
681 fun mk_look class = |
679 fun mk_look class = |
782 | (natts, (inst, defs)) => instance_arity inst natts defs) |
780 | (natts, (inst, defs)) => instance_arity inst natts defs) |
783 ) >> (Toplevel.print oo Toplevel.theory_to_proof)); |
781 ) >> (Toplevel.print oo Toplevel.theory_to_proof)); |
784 |
782 |
785 val _ = OuterSyntax.add_parsers [classP, instanceP]; |
783 val _ = OuterSyntax.add_parsers [classP, instanceP]; |
786 |
784 |
787 val _ = Context.add_setup (Method.add_methods |
|
788 [("intro_classes", Method.no_args (Method.METHOD intro_classes_tac), |
|
789 "back-chain introduction rules of classes"), |
|
790 ("default", Method.thms_ctxt_args (Method.METHOD oo default_tac), "apply some intro/elim rule")]); |
|
791 |
|
792 end; (* local *) |
785 end; (* local *) |
793 |
786 |
794 end; (* struct *) |
787 end; (* struct *) |