src/Pure/Tools/class_package.ML
changeset 18575 9ccfd1d1e874
parent 18550 59b89f625d68
child 18593 4ce4dba4af07
equal deleted inserted replaced
18574:46ed84a64cf6 18575:9ccfd1d1e874
     9 sig
     9 sig
    10   val add_class: bstring -> Locale.expr -> Element.context list -> theory
    10   val add_class: bstring -> Locale.expr -> Element.context list -> theory
    11     -> ProofContext.context * theory
    11     -> ProofContext.context * theory
    12   val add_class_i: bstring -> Locale.expr -> Element.context_i list -> theory
    12   val add_class_i: bstring -> Locale.expr -> Element.context_i list -> theory
    13     -> ProofContext.context * theory
    13     -> ProofContext.context * theory
       
    14   val add_instance_arity: (xstring * string list) * string
       
    15     -> ((bstring * string) * Attrib.src list) list
       
    16     -> theory -> Proof.state
       
    17   val add_instance_arity_i: (string * sort list) * sort
       
    18     -> ((bstring * term) * theory attribute list) list
       
    19     -> theory -> Proof.state
    14   val add_classentry: class -> xstring list -> xstring list -> theory -> theory
    20   val add_classentry: class -> xstring list -> xstring list -> theory -> theory
    15   val the_consts: theory -> class -> string list
    21   val the_consts: theory -> class -> string list
    16   val the_tycos: theory -> class -> (string * string) list
    22   val the_tycos: theory -> class -> (string * string) list
       
    23   val print_classes: theory -> unit
    17 
    24 
    18   val syntactic_sort_of: theory -> sort -> sort
    25   val syntactic_sort_of: theory -> sort -> sort
    19   val get_arities: theory -> sort -> string -> sort list
    26   val get_arities: theory -> sort -> string -> sort list
    20   val get_superclasses: theory -> class -> class list
    27   val get_superclasses: theory -> class -> class list
    21   val get_const_sign: theory -> string -> string -> typ
    28   val get_const_sign: theory -> string -> string -> typ
    35 
    42 
    36 
    43 
    37 (* data kind 'Pure/classes' *)
    44 (* data kind 'Pure/classes' *)
    38 
    45 
    39 type class_data = {
    46 type class_data = {
    40   locale_name: string,
    47   superclasses: class list,
    41   axclass_name: string,
    48   name_locale: string,
    42   consts: string list,
    49   name_axclass: string,
    43   tycos: (string * string) list
    50   var: string,
       
    51   consts: (string * typ) list,
       
    52   insts: (string * string) list
    44 };
    53 };
    45 
    54 
    46 structure ClassesData = TheoryDataFun (
    55 structure ClassData = TheoryDataFun (
    47   struct
    56   struct
    48     val name = "Pure/classes";
    57     val name = "Pure/classes";
    49     type T = class_data Symtab.table * class Symtab.table;
    58     type T = class_data Symtab.table * class Symtab.table;
    50     val empty = (Symtab.empty, Symtab.empty);
    59     val empty = (Symtab.empty, Symtab.empty);
    51     val copy = I;
    60     val copy = I;
    52     val extend = I;
    61     val extend = I;
    53     fun merge _ ((t1, r1), (t2, r2))=
    62     fun merge _ ((t1, r1), (t2, r2))=
    54       (Symtab.merge (op =) (t1, t2),
    63       (Symtab.merge (op =) (t1, t2),
    55        Symtab.merge (op =) (r1, r2));
    64        Symtab.merge (op =) (r1, r2));
    56     fun print _ (tab, _) = (Pretty.writeln o Pretty.chunks) (map Pretty.str (Symtab.keys tab));
    65     fun print thy (tab, _) =
       
    66       let
       
    67         fun pretty_class (name, {superclasses, name_locale, name_axclass, var, consts, insts}) =
       
    68           (Pretty.block o Pretty.fbreaks) [
       
    69             Pretty.str ("class " ^ name ^ ":"),
       
    70             (Pretty.block o Pretty.fbreaks) (
       
    71               Pretty.str "superclasses: "
       
    72               :: map Pretty.str superclasses
       
    73             ),
       
    74             Pretty.str ("locale: " ^ name_locale),
       
    75             Pretty.str ("axclass: " ^ name_axclass),
       
    76             Pretty.str ("class variable: " ^ var),
       
    77             (Pretty.block o Pretty.fbreaks) (
       
    78               Pretty.str "constants: "
       
    79               :: map (fn (c, ty) => Pretty.str (c ^ " :: " ^ Sign.string_of_typ thy ty)) consts
       
    80             ),
       
    81             (Pretty.block o Pretty.fbreaks) (
       
    82               Pretty.str "instances: "
       
    83               :: map (fn (tyco, thyname) => Pretty.str (tyco ^ ", in theory " ^ thyname)) insts
       
    84             )
       
    85           ]
       
    86       in
       
    87         (Pretty.writeln o Pretty.chunks o map pretty_class o Symtab.dest) tab
       
    88       end;
    57   end
    89   end
    58 );
    90 );
    59 
    91 
    60 val lookup_class_data = Symtab.lookup o fst o ClassesData.get;
    92 val print_classes = ClassData.print;
    61 val lookup_const_class = Symtab.lookup o snd o ClassesData.get;
    93 
       
    94 val lookup_class_data = Symtab.lookup o fst o ClassData.get;
       
    95 val lookup_const_class = Symtab.lookup o snd o ClassData.get;
    62 
    96 
    63 fun get_class_data thy class =
    97 fun get_class_data thy class =
    64   case lookup_class_data thy class
    98   case lookup_class_data thy class
    65     of NONE => error ("undeclared class " ^ quote class)
    99     of NONE => error ("undeclared class " ^ quote class)
    66      | SOME data => data;
   100      | SOME data => data;
    67 
   101 
    68 fun put_class_data class data =
   102 fun add_class_data (class, (superclasses, name_locale, name_axclass, classvar, consts)) =
    69   ClassesData.map (apfst (Symtab.update (class, data)));
   103   ClassData.map (fn (classtab, consttab) => (
    70 fun add_const class const =
   104     classtab 
    71   ClassesData.map (apsnd (Symtab.update (const, class)));
   105     |> Symtab.update (class, {
    72 val the_consts = #consts oo get_class_data;
   106          superclasses = superclasses,
    73 val the_tycos = #tycos oo get_class_data;
   107          name_locale = name_locale,
    74 
   108          name_axclass = name_axclass,
    75 
   109          var = classvar,
    76 (* name mangling *)
   110          consts = consts,
    77 
   111          insts = []
    78 fun get_locale_for_class thy class =
   112        }),
    79   #locale_name (get_class_data thy class);
   113     consttab
    80 
   114     |> fold (fn (c, _) => Symtab.update (c, class)) consts
    81 fun get_axclass_for_class thy class =
   115   ));
    82   #axclass_name (get_class_data thy class);
   116 
    83 
   117 fun add_inst_data (class, inst) =
    84 
   118   (ClassData.map o apfst o Symtab.map_entry class)
    85 (* classes *)
   119     (fn {superclasses, name_locale, name_axclass, var, consts, insts}
       
   120       => {
       
   121            superclasses = superclasses,
       
   122            name_locale = name_locale,
       
   123            name_axclass = name_axclass,
       
   124            var = var,
       
   125            consts = consts,
       
   126            insts = insts @ [inst]
       
   127           });
       
   128 
       
   129 val the_consts = map fst o #consts oo get_class_data;
       
   130 val the_tycos = #insts oo get_class_data;
       
   131 
       
   132 
       
   133 (* classes and instances *)
    86 
   134 
    87 local
   135 local
    88 
   136 
    89 open Element
   137 open Element
    90 
   138 
    91 fun gen_add_class add_locale bname raw_import raw_body thy =
   139 fun gen_add_class add_locale bname raw_import raw_body thy =
    92   let
   140   let
    93     fun extract_notes_consts thy elems =
   141     fun subst_clsvar v ty_subst =
    94       elems
   142       map_type_tfree (fn u as (w, _) =>
    95       |> Library.flat
   143         if w = v then ty_subst else TFree u);
    96       |> List.mapPartial
   144     fun extract_assumes c_adds elems =
    97            (fn (Notes notes) => SOME notes
   145       let
    98              | _ => NONE)
   146         fun subst_free ts =
    99       |> Library.flat
   147           let
   100       |> map (fn (_, facts) => map fst facts)
   148             val get_ty = the o AList.lookup (op =) (fold Term.add_frees ts []);
   101       |> Library.flat o Library.flat
   149             val subst_map = map (fn (c, (c', _)) =>
   102       |> map prop_of
   150               (Free (c, get_ty c), Const (c', get_ty c))) c_adds;
   103       |> (fn ts => fold (curry add_term_consts) ts [])
   151           in map (subst_atomic subst_map) ts end;
   104       |> tap (writeln o commas);
   152       in
       
   153         elems
       
   154         |> (map o List.mapPartial)
       
   155             (fn (Assumes asms) => (SOME o map (map fst o snd)) asms
       
   156               | _ => NONE)
       
   157         |> Library.flat o Library.flat o Library.flat
       
   158         |> subst_free
       
   159       end;
   105     fun extract_tyvar_name thy tys =
   160     fun extract_tyvar_name thy tys =
   106       fold (curry add_typ_tfrees) tys []
   161       fold (curry add_typ_tfrees) tys []
   107       |> (fn [(v, [])] => v
   162       |> (fn [(v, sort)] =>
   108            | [(v, sort)] =>
       
   109                 if Sorts.sort_eq (Sign.classes_of thy) (Sign.defaultS thy, sort)
   163                 if Sorts.sort_eq (Sign.classes_of thy) (Sign.defaultS thy, sort)
   110                 then v 
   164                 then v 
   111                 else error ("sort constraint on class type variable: " ^ Sign.string_of_sort thy sort)
   165                 else error ("illegal sort constraint on class type variable: " ^ Sign.string_of_sort thy sort)
   112            | [] => error ("no class type variable")
   166            | [] => error ("no class type variable")
   113            | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs))
   167            | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs))
   114     fun extract_tyvar_consts thy elems =
   168     fun extract_tyvar_consts thy elems =
   115       elems
   169       elems
   116       |> Library.flat
   170       |> Library.flat
   117       |> List.mapPartial
   171       |> List.mapPartial
   118            (fn (Fixes consts) => SOME consts
   172            (fn (Fixes consts) => SOME consts
   119              | _ => NONE)
   173              | _ => NONE)
   120       |> Library.flat
   174       |> Library.flat
   121       |> map (fn (c, ty, syn) => ((c, the ty), the syn))
   175       |> map (fn (c, ty, syn) =>
   122       |> `(fn consts => extract_tyvar_name thy (map (snd o fst) consts));
   176            ((c, the ty), (Syntax.unlocalize_mixfix o Syntax.fix_mixfix c o the) syn))
   123     (* fun remove_local_syntax ((c, ty), _) thy =
   177       |> `(fn consts => extract_tyvar_name thy (map (snd o fst) consts))
       
   178       |-> (fn v => map ((apfst o apsnd) (subst_clsvar v (TFree (v, []))))
       
   179          #> pair v);
       
   180     fun add_global_const v ((c, ty), syn) thy =
   124       thy
   181       thy
   125       |> Sign.add_syntax_i [(c, ty, Syntax.NoSyn)]; *)
   182       |> Sign.add_consts_i [(c, ty |> subst_clsvar v (TFree (v, Sign.defaultS thy)), syn)]
   126     fun add_global_const ((c, ty), syn) thy =
   183       |> `(fn thy => (c, (Sign.intern_const thy c, ty)))
       
   184     fun add_global_constraint v class (_, (c, ty)) thy =
   127       thy
   185       thy
   128       |> Sign.add_consts_i [(c, ty, syn)]
   186       |> Sign.add_const_constraint_i (c, subst_clsvar v (TVar ((v, 0), [class])) ty);
   129       |> `(fn thy => Sign.intern_const thy c)
       
   130     fun add_axclass bname_axiom locale_pred cs thy =
       
   131       thy
       
   132       |> AxClass.add_axclass_i (bname, Sign.defaultS thy)
       
   133            [Thm.no_attributes (bname_axiom,
       
   134               Const (ObjectLogic.judgment_name thy, dummyT) $
       
   135                 list_comb (Const (locale_pred, dummyT), map (fn c => Const (c, dummyT)) cs)
       
   136               |> curry (inferT_axm thy) "locale_pred" |> snd)]
       
   137       |-> (fn _ => `(fn thy => Sign.intern_class thy bname))
       
   138     fun print_ctxt ctxt elem = 
   187     fun print_ctxt ctxt elem = 
   139       map Pretty.writeln (Element.pretty_ctxt ctxt elem)
   188       map Pretty.writeln (Element.pretty_ctxt ctxt elem)
   140   in
   189   in
   141     thy
   190     thy
   142     |> add_locale bname raw_import raw_body
   191     |> add_locale bname raw_import raw_body
   143     |-> (fn ((_, elems : context_i list list), ctxt) =>
   192     |-> (fn ((import_elems, body_elems), ctxt) =>
   144        tap (fn _ => (map o map) (print_ctxt ctxt) elems)
   193        `(fn thy => Locale.intern thy bname)
   145     #> tap (fn thy => extract_notes_consts thy elems)
       
   146     #> `(fn thy => Locale.intern thy bname)
       
   147     #-> (fn name_locale =>
   194     #-> (fn name_locale =>
   148        `(fn thy => extract_tyvar_consts thy elems)
   195           `(fn thy => extract_tyvar_consts thy body_elems)
   149     #-> (fn (v, consts) =>
   196     #-> (fn (v, c_defs) =>
   150        fold_map add_global_const consts
   197           fold_map (add_global_const v) c_defs
   151     #-> (fn cs =>
   198     #-> (fn c_adds =>
   152        add_axclass (bname ^ "_intro") name_locale cs
   199           AxClass.add_axclass_i (bname, Sign.defaultS thy)
       
   200             (map (Thm.no_attributes o pair "") (extract_assumes c_adds (import_elems @ body_elems)))
       
   201     #-> (fn _ =>
       
   202           `(fn thy => Sign.intern_class thy bname)
   153     #-> (fn name_axclass =>
   203     #-> (fn name_axclass =>
   154        put_class_data name_locale {
   204           fold (add_global_constraint v name_axclass) c_adds
   155           locale_name = name_locale,
   205     #> add_class_data (name_locale, ([], name_locale, name_axclass, v, map snd c_adds))
   156           axclass_name = name_axclass,
   206     #> tap (fn _ => (map o map) (print_ctxt ctxt) import_elems)
   157           consts = cs,
   207     #> tap (fn _ => (map o map) (print_ctxt ctxt) body_elems)
   158           tycos = []
       
   159         })
       
   160     #> fold (add_const name_locale) cs
       
   161     #> pair ctxt
   208     #> pair ctxt
   162     ))))
   209     ))))))
   163   end;
   210   end;
   164 
   211 
   165 in
   212 in
   166 
   213 
   167 val add_class = gen_add_class (Locale.add_locale_context true);
   214 val add_class = gen_add_class (Locale.add_locale_context true);
   168 val add_class_i = gen_add_class (Locale.add_locale_context_i true);
   215 val add_class_i = gen_add_class (Locale.add_locale_context_i true);
   169 
   216 
   170 end; (* local *)
   217 end; (* local *)
       
   218 
       
   219 fun gen_instance_arity prep_arity add_defs tap_def raw_arity raw_defs thy = 
       
   220   let
       
   221     val dest_def = Theory.dest_def (Sign.pp thy) handle TERM (msg, _) => error msg;
       
   222     val arity as (tyco, asorts, sort) = prep_arity thy ((fn ((x, y), z) => (x, y, z)) raw_arity);
       
   223     val ty_inst = Type (tyco, map2 (curry TVar o rpair 0) (Term.invent_names [] "'a" (length asorts)) asorts)
       
   224     fun get_c_req class =
       
   225       let
       
   226         val data = get_class_data thy class;
       
   227         val subst_ty = map_type_tfree (fn (var as (v, _)) =>
       
   228           if #var data = v then ty_inst else TFree var)
       
   229       in (map (apsnd subst_ty) o #consts) data end;
       
   230     val c_req = (Library.flat o map get_c_req) sort;
       
   231     fun get_remove_contraint c thy =
       
   232       let
       
   233         val ty1 = Sign.the_const_constraint thy c;
       
   234         val ty2 = Sign.the_const_type thy c;
       
   235       in
       
   236         thy
       
   237         |> Sign.add_const_constraint_i (c, ty2)
       
   238         |> pair (c, ty1)
       
   239       end;
       
   240     fun get_c_given thy = map (fst o dest_def o snd o tap_def thy o fst) raw_defs;
       
   241     fun check_defs c_given c_req thy =
       
   242       let
       
   243         fun eq_c ((c1, ty1), (c2, ty2)) = c1 = c2 andalso Sign.typ_instance thy (ty1, ty2)
       
   244         val _ = case fold (remove eq_c) c_given c_req
       
   245          of [] => ()
       
   246           | cs => error ("no definition(s) given for"
       
   247                     ^ (commas o map (fn (c, ty) => quote (c ^ "::" ^ Sign.string_of_typ thy ty))) cs);
       
   248         val _ = case fold (remove eq_c) c_req c_given
       
   249          of [] => ()
       
   250           | cs => error ("superfluous definition(s) given for"
       
   251                     ^ (commas o map (fn (c, ty) => quote (c ^ "::" ^ Sign.string_of_typ thy ty))) cs);
       
   252       in thy end;
       
   253   in
       
   254     thy
       
   255     |> fold_map get_remove_contraint (map fst c_req)
       
   256     ||> tap (fn thy => check_defs (get_c_given thy) c_req)
       
   257     ||> add_defs (true, raw_defs)
       
   258     |-> (fn cs => fold Sign.add_const_constraint_i cs)
       
   259     |> AxClass.instance_arity_i arity
       
   260   end;
       
   261 
       
   262 val add_instance_arity = fn x => gen_instance_arity (AxClass.read_arity) IsarThy.add_defs read_axm x;
       
   263 val add_instance_arity_i = fn x => gen_instance_arity (AxClass.cert_arity) IsarThy.add_defs_i (K I) x;
   171 
   264 
   172 
   265 
   173 (* class queries *)
   266 (* class queries *)
   174 
   267 
   175 fun is_class thy cls = lookup_class_data thy cls |> Option.map (not o null o #consts) |> the_default false;
   268 fun is_class thy cls = lookup_class_data thy cls |> Option.map (not o null o #consts) |> the_default false;
   200     error ("no syntactic class: " ^ class);
   293     error ("no syntactic class: " ^ class);
   201 
   294 
   202 
   295 
   203 (* instance queries *)
   296 (* instance queries *)
   204 
   297 
   205 fun get_const_sign thy tvar const =
   298 fun mk_const_sign thy class tvar ty =
   206   let
   299   let
   207     val class = (the o lookup_const_class thy) const;
   300     val (ty', thaw) = Type.freeze_thaw_type ty;
   208     val (ty, thaw) = (Type.freeze_thaw_type o Sign.the_const_constraint thy) const;
   301     val tvars_used = Term.add_tfreesT ty' [];
   209     val tvars_used = Term.add_tfreesT ty [];
       
   210     val tvar_rename = hd (Term.invent_names (map fst tvars_used) tvar 1);
   302     val tvar_rename = hd (Term.invent_names (map fst tvars_used) tvar 1);
   211   in
   303   in
   212     ty
   304     ty'
   213     |> map_type_tfree (fn (tvar', sort) =>
   305     |> map_type_tfree (fn (tvar', sort) =>
   214           if Sorts.sort_eq (Sign.classes_of thy) ([class], sort)
   306           if Sorts.sort_eq (Sign.classes_of thy) ([class], sort)
   215           then TFree (tvar, [])
   307           then TFree (tvar, [])
   216           else if tvar' = tvar
   308           else if tvar' = tvar
   217           then TVar ((tvar_rename, 0), sort)
   309           then TVar ((tvar_rename, 0), sort)
   218           else TFree (tvar', sort))
   310           else TFree (tvar', sort))
   219     |> thaw
   311     |> thaw
   220   end;
   312   end;
       
   313 
       
   314 fun get_const_sign thy tvar const =
       
   315   let
       
   316     val class = (the o lookup_const_class thy) const;
       
   317     val ty = Sign.the_const_constraint thy const;
       
   318   in mk_const_sign thy class tvar ty end;
   221 
   319 
   222 fun get_inst_consts_sign thy (tyco, class) =
   320 fun get_inst_consts_sign thy (tyco, class) =
   223   let
   321   let
   224     val consts = the_consts thy class;
   322     val consts = the_consts thy class;
   225     val arities = get_arities thy [class] tyco;
   323     val arities = get_arities thy [class] tyco;
   232       map (typ_subst_TVars [(("'a", 0), typ_arity)]) const_signs;
   330       map (typ_subst_TVars [(("'a", 0), typ_arity)]) const_signs;
   233   in consts ~~ instmem_signs end;
   331   in consts ~~ instmem_signs end;
   234 
   332 
   235 fun get_classtab thy =
   333 fun get_classtab thy =
   236   Symtab.fold
   334   Symtab.fold
   237     (fn (class, { consts = consts, tycos = tycos, ... }) =>
   335     (fn (class, { consts = consts, insts = insts, ... }) =>
   238       Symtab.update_new (class, (consts, tycos)))
   336       Symtab.update_new (class, (map fst consts, insts)))
   239        (fst (ClassesData.get thy)) Symtab.empty;
   337        (fst (ClassData.get thy)) Symtab.empty;
   240 
   338 
   241 
   339 
   242 (* extracting dictionary obligations from types *)
   340 (* extracting dictionary obligations from types *)
   243 
   341 
   244 type sortcontext = (string * sort) list;
   342 type sortcontext = (string * sort) list;
   285   end;
   383   end;
   286 
   384 
   287 
   385 
   288 (* intermediate auxiliary *)
   386 (* intermediate auxiliary *)
   289 
   387 
   290 fun add_classentry raw_class raw_cs raw_tycos thy =
   388 fun add_classentry raw_class raw_cs raw_insts thy =
   291   let
   389   let
   292     val class = Sign.intern_class thy raw_class;
   390     val class = Sign.intern_class thy raw_class;
   293     val cs = map (Sign.intern_const thy) raw_cs;
   391     val cs = raw_cs |> map (Sign.intern_const thy);
   294     val tycos = map (rpair (Context.theory_name thy) o Sign.intern_type thy) raw_tycos;
   392     val insts = map (rpair (Context.theory_name thy) o Sign.intern_type thy) raw_insts;
   295   in
   393   in
   296     thy
   394     thy
   297     |> put_class_data class {
   395     |> add_class_data (class, ([], "", class, "", map (rpair dummyT) cs))
   298          locale_name = "",
   396     |> fold (curry add_inst_data class) insts
   299          axclass_name = class,
       
   300          consts = cs,
       
   301          tycos = tycos
       
   302        }
       
   303     |> fold (add_const class) cs
       
   304   end;
   397   end;
   305 
   398 
   306 
   399 
   307 (* toplevel interface *)
   400 (* toplevel interface *)
   308 
   401 
   311 structure P = OuterParse
   404 structure P = OuterParse
   312 and K = OuterKeyword
   405 and K = OuterKeyword
   313 
   406 
   314 in
   407 in
   315 
   408 
   316 val classK = "class"
   409 val (classK, instanceK) = ("class", "class_instance")
   317 
   410 
   318 val locale_val =
   411 val locale_val =
   319   (P.locale_expr --
   412   (P.locale_expr --
   320     Scan.optional (P.$$$ "+" |-- P.!!! (Scan.repeat1 P.context_element)) [] ||
   413     Scan.optional (P.$$$ "+" |-- P.!!! (Scan.repeat1 P.context_element)) [] ||
   321   Scan.repeat1 P.context_element >> pair Locale.empty);
   414   Scan.repeat1 P.context_element >> pair Locale.empty);
   322 
   415 
   323 val classP =
   416 val classP =
   324   OuterSyntax.command classK "operational type classes" K.thy_decl
   417   OuterSyntax.command classK "operational type classes" K.thy_decl
   325     (P.name -- Scan.optional (P.$$$ "=" |-- P.!!! locale_val) (Locale.empty, [])
   418     (P.name -- Scan.optional (P.$$$ "=" |-- P.!!! locale_val) (Locale.empty, [])
   326       >> (Toplevel.theory_context
   419       >> (Toplevel.theory_context
   327           o (fn f => swap o f) o (fn (name, (expr, elems)) => add_class name expr elems)));
   420           o (fn f => swap o f) o (fn (bname, (expr, elems)) => add_class bname expr elems)));
   328 
   421 
   329 val _ = OuterSyntax.add_parsers [classP];
   422 val instanceP =
       
   423   OuterSyntax.command instanceK "" K.thy_goal
       
   424     (P.xname -- (P.$$$ "::" |-- P.!!! P.arity)
       
   425       -- Scan.repeat1 P.spec_name
       
   426       >> (Toplevel.theory_theory_to_proof
       
   427           o (fn ((tyco, (asorts, sort)), defs) => add_instance_arity ((tyco, asorts), sort) defs)));
       
   428 
       
   429 val _ = OuterSyntax.add_parsers [classP, instanceP];
   330 
   430 
   331 end; (* local *)
   431 end; (* local *)
   332 
   432 
   333 
   433 
   334 (* setup *)
   434 (* setup *)
   335 
   435 
   336 val _ = Context.add_setup [ClassesData.init];
   436 val _ = Context.add_setup [ClassData.init];
   337 
   437 
   338 end; (* struct *)
   438 end; (* struct *)