src/Pure/Tools/class_package.ML
changeset 19468 0afdd5023bfc
parent 19456 b5bfd2d17dd3
child 19482 9f11af8f7ef9
equal deleted inserted replaced
19467:d75570e8aa97 19468:0afdd5023bfc
     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 =
   443     )))))
   443     )))))
   444   end;
   444   end;
   445 
   445 
   446 in
   446 in
   447 
   447 
   448 val class = gen_class (add_locale true) intern_class;
   448 val class = gen_class add_locale intern_class;
   449 val class_i = gen_class (add_locale_i true) certify_class;
   449 val class_i = gen_class add_locale_i certify_class;
   450 
   450 
   451 end; (* local *)
   451 end; (* local *)
   452 
   452 
   453 local
   453 local
   454 
   454 
   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 *)