| author | wenzelm | 
| Sat, 07 Jan 2006 12:26:28 +0100 | |
| changeset 18604 | 4000f368dc7f | 
| parent 18593 | 4ce4dba4af07 | 
| child 18670 | c3f445b92aff | 
| permissions | -rw-r--r-- | 
| 18168 | 1 | (* Title: Pure/Tools/class_package.ML | 
| 2 | ID: $Id$ | |
| 3 | Author: Florian Haftmann, TU Muenchen | |
| 4 | ||
| 5 | Haskell98-like operational view on type classes. | |
| 6 | *) | |
| 7 | ||
| 8 | signature CLASS_PACKAGE = | |
| 9 | sig | |
| 18515 | 10 | val add_class: bstring -> Locale.expr -> Element.context list -> theory | 
| 11 | -> ProofContext.context * theory | |
| 12 | val add_class_i: bstring -> Locale.expr -> Element.context_i list -> theory | |
| 13 | -> ProofContext.context * theory | |
| 18575 | 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 | |
| 18515 | 20 | val add_classentry: class -> xstring list -> xstring list -> theory -> theory | 
| 18168 | 21 | val the_consts: theory -> class -> string list | 
| 22 | val the_tycos: theory -> class -> (string * string) list | |
| 18575 | 23 | val print_classes: theory -> unit | 
| 18168 | 24 | |
| 18360 | 25 | val syntactic_sort_of: theory -> sort -> sort | 
| 18168 | 26 | val get_arities: theory -> sort -> string -> sort list | 
| 27 | val get_superclasses: theory -> class -> class list | |
| 18304 | 28 | val get_const_sign: theory -> string -> string -> typ | 
| 18168 | 29 | val get_inst_consts_sign: theory -> string * class -> (string * typ) list | 
| 30 | val lookup_const_class: theory -> string -> class option | |
| 31 | val get_classtab: theory -> (string list * (string * string) list) Symtab.table | |
| 32 | ||
| 33 | type sortcontext = (string * sort) list | |
| 34 | datatype sortlookup = Instance of (class * string) * sortlookup list list | |
| 35 | | Lookup of class list * (string * int) | |
| 36 | val extract_sortctxt: theory -> typ -> sortcontext | |
| 37 | val extract_sortlookup: theory -> typ * typ -> sortlookup list list | |
| 38 | end; | |
| 39 | ||
| 40 | structure ClassPackage: CLASS_PACKAGE = | |
| 41 | struct | |
| 42 | ||
| 43 | ||
| 44 | (* data kind 'Pure/classes' *) | |
| 45 | ||
| 46 | type class_data = {
 | |
| 18575 | 47 | superclasses: class list, | 
| 48 | name_locale: string, | |
| 49 | name_axclass: string, | |
| 50 | var: string, | |
| 51 | consts: (string * typ) list, | |
| 52 | insts: (string * string) list | |
| 18168 | 53 | }; | 
| 54 | ||
| 18575 | 55 | structure ClassData = TheoryDataFun ( | 
| 18168 | 56 | struct | 
| 57 | val name = "Pure/classes"; | |
| 58 | type T = class_data Symtab.table * class Symtab.table; | |
| 59 | val empty = (Symtab.empty, Symtab.empty); | |
| 60 | val copy = I; | |
| 61 | val extend = I; | |
| 62 | fun merge _ ((t1, r1), (t2, r2))= | |
| 63 | (Symtab.merge (op =) (t1, t2), | |
| 64 | Symtab.merge (op =) (r1, r2)); | |
| 18575 | 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; | |
| 18168 | 89 | end | 
| 90 | ); | |
| 91 | ||
| 18575 | 92 | val print_classes = ClassData.print; | 
| 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; | |
| 18168 | 96 | |
| 97 | fun get_class_data thy class = | |
| 98 | case lookup_class_data thy class | |
| 99 |     of NONE => error ("undeclared class " ^ quote class)
 | |
| 100 | | SOME data => data; | |
| 101 | ||
| 18575 | 102 | fun add_class_data (class, (superclasses, name_locale, name_axclass, classvar, consts)) = | 
| 103 | ClassData.map (fn (classtab, consttab) => ( | |
| 104 | classtab | |
| 105 |     |> Symtab.update (class, {
 | |
| 106 | superclasses = superclasses, | |
| 107 | name_locale = name_locale, | |
| 108 | name_axclass = name_axclass, | |
| 109 | var = classvar, | |
| 110 | consts = consts, | |
| 111 | insts = [] | |
| 112 | }), | |
| 113 | consttab | |
| 114 | |> fold (fn (c, _) => Symtab.update (c, class)) consts | |
| 115 | )); | |
| 116 | ||
| 117 | fun add_inst_data (class, inst) = | |
| 118 | (ClassData.map o apfst o Symtab.map_entry class) | |
| 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; | |
| 18168 | 131 | |
| 132 | ||
| 18575 | 133 | (* classes and instances *) | 
| 18168 | 134 | |
| 135 | local | |
| 136 | ||
| 18515 | 137 | open Element | 
| 138 | ||
| 139 | fun gen_add_class add_locale bname raw_import raw_body thy = | |
| 18168 | 140 | let | 
| 18575 | 141 | fun subst_clsvar v ty_subst = | 
| 142 | map_type_tfree (fn u as (w, _) => | |
| 143 | if w = v then ty_subst else TFree u); | |
| 144 | fun extract_assumes c_adds elems = | |
| 145 | let | |
| 146 | fun subst_free ts = | |
| 147 | let | |
| 148 | val get_ty = the o AList.lookup (op =) (fold Term.add_frees ts []); | |
| 149 | val subst_map = map (fn (c, (c', _)) => | |
| 150 | (Free (c, get_ty c), Const (c', get_ty c))) c_adds; | |
| 151 | in map (subst_atomic subst_map) ts end; | |
| 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; | |
| 18515 | 160 | fun extract_tyvar_name thy tys = | 
| 161 | fold (curry add_typ_tfrees) tys [] | |
| 18575 | 162 | |> (fn [(v, sort)] => | 
| 18515 | 163 | if Sorts.sort_eq (Sign.classes_of thy) (Sign.defaultS thy, sort) | 
| 164 | then v | |
| 18575 | 165 |                 else error ("illegal sort constraint on class type variable: " ^ Sign.string_of_sort thy sort)
 | 
| 18515 | 166 |            | [] => error ("no class type variable")
 | 
| 167 |            | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs))
 | |
| 168 | fun extract_tyvar_consts thy elems = | |
| 169 | elems | |
| 18550 
59b89f625d68
add_local_context now yields imported and body elements seperatly; additional slight clenup in code
 haftmann parents: 
18515diff
changeset | 170 | |> Library.flat | 
| 18515 | 171 | |> List.mapPartial | 
| 172 | (fn (Fixes consts) => SOME consts | |
| 173 | | _ => NONE) | |
| 174 | |> Library.flat | |
| 18575 | 175 | |> map (fn (c, ty, syn) => | 
| 176 | ((c, the ty), (Syntax.unlocalize_mixfix o Syntax.fix_mixfix c o the) syn)) | |
| 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 = | |
| 18515 | 181 | thy | 
| 18575 | 182 | |> Sign.add_consts_i [(c, ty |> subst_clsvar v (TFree (v, Sign.defaultS thy)), syn)] | 
| 183 | |> `(fn thy => (c, (Sign.intern_const thy c, ty))) | |
| 184 | fun add_global_constraint v class (_, (c, ty)) thy = | |
| 18515 | 185 | thy | 
| 18575 | 186 | |> Sign.add_const_constraint_i (c, subst_clsvar v (TVar ((v, 0), [class])) ty); | 
| 18515 | 187 | fun print_ctxt ctxt elem = | 
| 188 | map Pretty.writeln (Element.pretty_ctxt ctxt elem) | |
| 18168 | 189 | in | 
| 190 | thy | |
| 18515 | 191 | |> add_locale bname raw_import raw_body | 
| 18575 | 192 | |-> (fn ((import_elems, body_elems), ctxt) => | 
| 193 | `(fn thy => Locale.intern thy bname) | |
| 18515 | 194 | #-> (fn name_locale => | 
| 18575 | 195 | `(fn thy => extract_tyvar_consts thy body_elems) | 
| 196 | #-> (fn (v, c_defs) => | |
| 197 | fold_map (add_global_const v) c_defs | |
| 198 | #-> (fn c_adds => | |
| 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) | |
| 18515 | 203 | #-> (fn name_axclass => | 
| 18575 | 204 | fold (add_global_constraint v name_axclass) c_adds | 
| 205 | #> add_class_data (name_locale, ([], name_locale, name_axclass, v, map snd c_adds)) | |
| 206 | #> tap (fn _ => (map o map) (print_ctxt ctxt) import_elems) | |
| 207 | #> tap (fn _ => (map o map) (print_ctxt ctxt) body_elems) | |
| 18515 | 208 | #> pair ctxt | 
| 18575 | 209 | )))))) | 
| 18168 | 210 | end; | 
| 211 | ||
| 212 | in | |
| 213 | ||
| 18515 | 214 | val add_class = gen_add_class (Locale.add_locale_context true); | 
| 215 | val add_class_i = gen_add_class (Locale.add_locale_context_i true); | |
| 18168 | 216 | |
| 217 | end; (* local *) | |
| 218 | ||
| 18575 | 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; | |
| 264 | ||
| 18168 | 265 | |
| 266 | (* class queries *) | |
| 267 | ||
| 18360 | 268 | fun is_class thy cls = lookup_class_data thy cls |> Option.map (not o null o #consts) |> the_default false; | 
| 18168 | 269 | |
| 18360 | 270 | fun syntactic_sort_of thy sort = | 
| 271 | let | |
| 272 | val classes = Sign.classes_of thy; | |
| 273 | fun get_sort cls = | |
| 274 | if is_class thy cls | |
| 275 | then [cls] | |
| 276 | else syntactic_sort_of thy (Sorts.superclasses classes cls); | |
| 277 | in | |
| 278 | map get_sort sort | |
| 279 | |> Library.flat | |
| 280 | |> Sorts.norm_sort classes | |
| 281 | end; | |
| 18168 | 282 | |
| 283 | fun get_arities thy sort tycon = | |
| 18515 | 284 | Sorts.mg_domain (Sign.classes_arities_of thy) tycon (syntactic_sort_of thy sort) | 
| 18360 | 285 | |> map (syntactic_sort_of thy); | 
| 18168 | 286 | |
| 287 | fun get_superclasses thy class = | |
| 18515 | 288 | if is_class thy class | 
| 289 | then | |
| 290 | Sorts.superclasses (Sign.classes_of thy) class | |
| 291 | |> syntactic_sort_of thy | |
| 292 | else | |
| 293 |     error ("no syntactic class: " ^ class);
 | |
| 18168 | 294 | |
| 295 | ||
| 296 | (* instance queries *) | |
| 297 | ||
| 18575 | 298 | fun mk_const_sign thy class tvar ty = | 
| 18168 | 299 | let | 
| 18575 | 300 | val (ty', thaw) = Type.freeze_thaw_type ty; | 
| 301 | val tvars_used = Term.add_tfreesT ty' []; | |
| 18304 | 302 | val tvar_rename = hd (Term.invent_names (map fst tvars_used) tvar 1); | 
| 303 | in | |
| 18575 | 304 | ty' | 
| 18304 | 305 | |> map_type_tfree (fn (tvar', sort) => | 
| 306 | if Sorts.sort_eq (Sign.classes_of thy) ([class], sort) | |
| 307 | then TFree (tvar, []) | |
| 308 | else if tvar' = tvar | |
| 18335 | 309 | then TVar ((tvar_rename, 0), sort) | 
| 18304 | 310 | else TFree (tvar', sort)) | 
| 18335 | 311 | |> thaw | 
| 18304 | 312 | end; | 
| 18168 | 313 | |
| 18575 | 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; | |
| 319 | ||
| 18168 | 320 | fun get_inst_consts_sign thy (tyco, class) = | 
| 321 | let | |
| 322 | val consts = the_consts thy class; | |
| 323 | val arities = get_arities thy [class] tyco; | |
| 18304 | 324 | val const_signs = map (get_const_sign thy "'a") consts; | 
| 325 | val vars_used = fold (fn ty => curry (gen_union (op =)) | |
| 326 | (map fst (typ_tfrees ty) |> remove (op =) "'a")) const_signs []; | |
| 18168 | 327 | val vars_new = Term.invent_names vars_used "'a" (length arities); | 
| 18330 | 328 | val typ_arity = Type (tyco, map2 (curry TFree) vars_new arities); | 
| 18168 | 329 | val instmem_signs = | 
| 18335 | 330 |       map (typ_subst_TVars [(("'a", 0), typ_arity)]) const_signs;
 | 
| 18168 | 331 | in consts ~~ instmem_signs end; | 
| 332 | ||
| 333 | fun get_classtab thy = | |
| 334 | Symtab.fold | |
| 18575 | 335 |     (fn (class, { consts = consts, insts = insts, ... }) =>
 | 
| 336 | Symtab.update_new (class, (map fst consts, insts))) | |
| 337 | (fst (ClassData.get thy)) Symtab.empty; | |
| 18168 | 338 | |
| 339 | ||
| 340 | (* extracting dictionary obligations from types *) | |
| 341 | ||
| 342 | type sortcontext = (string * sort) list; | |
| 343 | ||
| 18335 | 344 | fun extract_sortctxt thy ty = | 
| 345 | (typ_tfrees o Type.no_tvars) ty | |
| 18360 | 346 | |> map (apsnd (syntactic_sort_of thy)) | 
| 18168 | 347 | |> filter (not o null o snd); | 
| 348 | ||
| 349 | datatype sortlookup = Instance of (class * string) * sortlookup list list | |
| 350 | | Lookup of class list * (string * int) | |
| 351 | ||
| 352 | fun extract_sortlookup thy (raw_typ_def, raw_typ_use) = | |
| 353 | let | |
| 354 | val typ_def = Type.varifyT raw_typ_def; | |
| 355 | val typ_use = Type.varifyT raw_typ_use; | |
| 356 | val match_tab = Sign.typ_match thy (typ_def, typ_use) Vartab.empty; | |
| 357 | fun tab_lookup vname = (the o Vartab.lookup match_tab) (vname, 0); | |
| 358 | fun get_superclass_derivation (subclasses, superclass) = | |
| 359 | (the oo get_first) (fn subclass => | |
| 360 | Sorts.class_le_path (Sign.classes_of thy) (subclass, superclass) | |
| 361 | ) subclasses; | |
| 362 | fun mk_class_deriv thy subclasses superclass = | |
| 363 | case get_superclass_derivation (subclasses, superclass) | |
| 18515 | 364 | of (subclass::deriv) => | 
| 365 | ((rev o filter (is_class thy)) deriv, find_index_eq subclass subclasses); | |
| 18168 | 366 | fun mk_lookup (sort_def, (Type (tycon, tys))) = | 
| 367 | let | |
| 18330 | 368 | val arity_lookup = map2 (curry mk_lookup) | 
| 18360 | 369 | (map (syntactic_sort_of thy) (Sorts.mg_domain (Sign.classes_arities_of thy) tycon sort_def)) tys | 
| 18168 | 370 | in map (fn class => Instance ((class, tycon), arity_lookup)) sort_def end | 
| 371 | | mk_lookup (sort_def, TVar ((vname, _), sort_use)) = | |
| 372 | let | |
| 373 | fun mk_look class = | |
| 18515 | 374 | let val (deriv, classindex) = mk_class_deriv thy (syntactic_sort_of thy sort_use) class | 
| 18168 | 375 | in Lookup (deriv, (vname, classindex)) end; | 
| 376 | in map mk_look sort_def end; | |
| 377 | in | |
| 18335 | 378 | extract_sortctxt thy ((fst o Type.freeze_thaw_type) raw_typ_def) | 
| 18168 | 379 | |> map (tab_lookup o fst) | 
| 18360 | 380 | |> map (apfst (syntactic_sort_of thy)) | 
| 18168 | 381 | |> filter (not o null o fst) | 
| 382 | |> map mk_lookup | |
| 383 | end; | |
| 384 | ||
| 385 | ||
| 18335 | 386 | (* intermediate auxiliary *) | 
| 18168 | 387 | |
| 18575 | 388 | fun add_classentry raw_class raw_cs raw_insts thy = | 
| 18168 | 389 | let | 
| 390 | val class = Sign.intern_class thy raw_class; | |
| 18575 | 391 | val cs = raw_cs |> map (Sign.intern_const thy); | 
| 392 | val insts = map (rpair (Context.theory_name thy) o Sign.intern_type thy) raw_insts; | |
| 18168 | 393 | in | 
| 394 | thy | |
| 18575 | 395 | |> add_class_data (class, ([], "", class, "", map (rpair dummyT) cs)) | 
| 396 | |> fold (curry add_inst_data class) insts | |
| 18335 | 397 | end; | 
| 18515 | 398 | |
| 399 | ||
| 400 | (* toplevel interface *) | |
| 401 | ||
| 402 | local | |
| 403 | ||
| 404 | structure P = OuterParse | |
| 405 | and K = OuterKeyword | |
| 406 | ||
| 407 | in | |
| 408 | ||
| 18575 | 409 | val (classK, instanceK) = ("class", "class_instance")
 | 
| 18515 | 410 | |
| 411 | val locale_val = | |
| 412 | (P.locale_expr -- | |
| 413 | Scan.optional (P.$$$ "+" |-- P.!!! (Scan.repeat1 P.context_element)) [] || | |
| 414 | Scan.repeat1 P.context_element >> pair Locale.empty); | |
| 415 | ||
| 416 | val classP = | |
| 417 | OuterSyntax.command classK "operational type classes" K.thy_decl | |
| 418 | (P.name -- Scan.optional (P.$$$ "=" |-- P.!!! locale_val) (Locale.empty, []) | |
| 419 | >> (Toplevel.theory_context | |
| 18575 | 420 | o (fn f => swap o f) o (fn (bname, (expr, elems)) => add_class bname expr elems))); | 
| 18515 | 421 | |
| 18575 | 422 | val instanceP = | 
| 423 | OuterSyntax.command instanceK "" K.thy_goal | |
| 424 | (P.xname -- (P.$$$ "::" |-- P.!!! P.arity) | |
| 425 | -- Scan.repeat1 P.spec_name | |
| 18593 | 426 | >> (Toplevel.theory_to_proof | 
| 18575 | 427 | o (fn ((tyco, (asorts, sort)), defs) => add_instance_arity ((tyco, asorts), sort) defs))); | 
| 428 | ||
| 429 | val _ = OuterSyntax.add_parsers [classP, instanceP]; | |
| 18515 | 430 | |
| 431 | end; (* local *) | |
| 432 | ||
| 18168 | 433 | |
| 434 | (* setup *) | |
| 435 | ||
| 18575 | 436 | val _ = Context.add_setup [ClassData.init]; | 
| 18168 | 437 | |
| 438 | end; (* struct *) |