src/Pure/Tools/class_package.ML
changeset 19038 62c5f7591a43
parent 18963 3adfc9dfb30a
child 19102 db27ca6a6cd6
equal deleted inserted replaced
19037:3be721728a6c 19038:62c5f7591a43
    56 };
    56 };
    57 
    57 
    58 structure ClassData = TheoryDataFun (
    58 structure ClassData = TheoryDataFun (
    59   struct
    59   struct
    60     val name = "Pure/classes";
    60     val name = "Pure/classes";
    61     type T = class_data Symtab.table * class Symtab.table;
    61     type T = class_data Symtab.table * (class Symtab.table * string Symtab.table);
    62     val empty = (Symtab.empty, Symtab.empty);
    62     val empty = (Symtab.empty, (Symtab.empty, Symtab.empty));
    63     val copy = I;
    63     val copy = I;
    64     val extend = I;
    64     val extend = I;
    65     fun merge _ ((t1, r1), (t2, r2))=
    65     fun merge _ ((t1, (c1, l1)), (t2, (c2, l2)))=
    66       (Symtab.merge (op =) (t1, t2),
    66       (Symtab.merge (op =) (t1, t2),
    67        Symtab.merge (op =) (r1, r2));
    67        (Symtab.merge (op =) (c1, c2), Symtab.merge (op =) (l1, l2)));
    68     fun print thy (tab, _) =
    68     fun print thy (tab, _) =
    69       let
    69       let
    70         fun pretty_class (name, {superclasses, name_locale, name_axclass, var, consts, insts}) =
    70         fun pretty_class (name, {superclasses, name_locale, name_axclass, var, consts, insts}) =
    71           (Pretty.block o Pretty.fbreaks) [
    71           (Pretty.block o Pretty.fbreaks) [
    72             Pretty.str ("class " ^ name ^ ":"),
    72             Pretty.str ("class " ^ name ^ ":"),
    93 );
    93 );
    94 
    94 
    95 val _ = Context.add_setup ClassData.init;
    95 val _ = Context.add_setup ClassData.init;
    96 val print_classes = ClassData.print;
    96 val print_classes = ClassData.print;
    97 
    97 
       
    98 
       
    99 (* queries *)
       
   100 
    98 val lookup_class_data = Symtab.lookup o fst o ClassData.get;
   101 val lookup_class_data = Symtab.lookup o fst o ClassData.get;
    99 val lookup_const_class = Symtab.lookup o snd o ClassData.get;
   102 val lookup_const_class = Symtab.lookup o fst o snd o ClassData.get;
   100 
   103 val lookup_locale_class = Symtab.lookup o snd o snd o ClassData.get;
   101 fun get_class_data thy class =
   104 
       
   105 fun the_class_data thy class =
   102   case lookup_class_data thy class
   106   case lookup_class_data thy class
   103     of NONE => error ("undeclared operational class " ^ quote class)
   107     of NONE => error ("undeclared operational class " ^ quote class)
   104      | SOME data => data;
   108      | SOME data => data;
   105 
   109 
       
   110 fun is_class thy cls =
       
   111   lookup_class_data thy cls
       
   112   |> Option.map (not o null o #consts)
       
   113   |> the_default false;
       
   114 
       
   115 fun operational_sort_of thy sort =
       
   116   let
       
   117     val classes = Sign.classes_of thy;
       
   118     fun get_sort cls =
       
   119       if is_class thy cls
       
   120       then [cls]
       
   121       else operational_sort_of thy (Sorts.superclasses classes cls);
       
   122   in
       
   123     map get_sort sort
       
   124     |> Library.flat
       
   125     |> Sorts.norm_sort classes
       
   126   end;
       
   127 
       
   128 fun the_superclasses thy class =
       
   129   if is_class thy class
       
   130   then
       
   131     Sorts.superclasses (Sign.classes_of thy) class
       
   132     |> operational_sort_of thy
       
   133   else
       
   134     error ("no syntactic class: " ^ class);
       
   135 
       
   136 fun the_ancestry thy classes =
       
   137   let
       
   138     fun ancestry class anc =
       
   139       anc
       
   140       |> cons class
       
   141       |> fold ancestry (the_superclasses thy class);
       
   142   in fold ancestry classes [] end;
       
   143 
       
   144 fun subst_clsvar v ty_subst =
       
   145   map_type_tfree (fn u as (w, _) =>
       
   146     if w = v then ty_subst else TFree u);
       
   147 
       
   148 fun the_consts_sign thy class =
       
   149   let
       
   150     val data = the_class_data thy class
       
   151   in (#var data, #consts data) end;
       
   152 
       
   153 val the_instances =
       
   154   #insts oo the_class_data;
       
   155 
       
   156 fun the_inst_sign thy (class, tyco) =
       
   157   let
       
   158     val _ = if is_class thy class then () else error ("no syntactic class: " ^ class);
       
   159     val arity =
       
   160       Sorts.mg_domain (Sign.classes_arities_of thy) tyco [class]
       
   161       |> map (operational_sort_of thy);
       
   162     val clsvar = (#var o the_class_data thy) class;
       
   163     val const_sign = (snd o the_consts_sign thy) class;
       
   164     fun add_var sort used =
       
   165       let
       
   166         val v = hd (Term.invent_names used "'a" 1)
       
   167       in ((v, sort), v::used) end;
       
   168     val (vsorts, _) =
       
   169       []
       
   170       |> fold (fn (_, ty) => curry (gen_union (op =))
       
   171            ((map (fst o fst) o typ_tvars) ty @ (map fst o typ_tfrees) ty)) const_sign
       
   172       |> fold_map add_var arity;
       
   173     val ty_inst = Type (tyco, map (fn (v, sort) => TVar ((v, 0), sort)) vsorts);
       
   174     val inst_signs = map (apsnd (subst_clsvar clsvar ty_inst)) const_sign;
       
   175   in (vsorts, inst_signs) end;
       
   176 
       
   177 fun get_classtab thy =
       
   178   Symtab.fold
       
   179     (fn (class, { consts = consts, insts = insts, ... }) =>
       
   180       Symtab.update_new (class, (map fst consts, insts)))
       
   181        ((fst o ClassData.get) thy) Symtab.empty;
       
   182 
       
   183 
       
   184 (* updaters *)
       
   185 
   106 fun add_class_data (class, (superclasses, name_locale, name_axclass, classvar, consts)) =
   186 fun add_class_data (class, (superclasses, name_locale, name_axclass, classvar, consts)) =
   107   ClassData.map (fn (classtab, consttab) => (
   187   ClassData.map (fn (classtab, (consttab, loctab)) => (
   108     classtab 
   188     classtab
   109     |> Symtab.update (class, {
   189     |> Symtab.update (class, {
   110          superclasses = superclasses,
   190          superclasses = superclasses,
   111          name_locale = name_locale,
   191          name_locale = name_locale,
   112          name_axclass = name_axclass,
   192          name_axclass = name_axclass,
   113          var = classvar,
   193          var = classvar,
   114          consts = consts,
   194          consts = consts,
   115          insts = []
   195          insts = []
   116        }),
   196        }),
   117     consttab
   197     (consttab
   118     |> fold (fn (c, _) => Symtab.update (c, class)) consts
   198     |> fold (fn (c, _) => Symtab.update (c, class)) consts,
       
   199     loctab
       
   200     |> Symtab.update (name_locale, class))
   119   ));
   201   ));
   120 
   202 
   121 fun add_inst_data (class, inst) =
   203 fun add_inst_data (class, inst) =
   122   (ClassData.map o apfst o Symtab.map_entry class)
   204   (ClassData.map o apfst o Symtab.map_entry class)
   123     (fn {superclasses, name_locale, name_axclass, var, consts, insts}
   205     (fn {superclasses, name_locale, name_axclass, var, consts, insts}
   132 
   214 
   133 
   215 
   134 (* name handling *)
   216 (* name handling *)
   135 
   217 
   136 fun certify_class thy class =
   218 fun certify_class thy class =
   137   (get_class_data thy class; class);
   219   (the_class_data thy class; class);
   138 
   220 
   139 fun intern_class thy raw_class =
   221 fun intern_class thy raw_class =
   140   certify_class thy (Sign.intern_class thy raw_class);
   222   certify_class thy (Sign.intern_class thy raw_class);
   141 
   223 
   142 fun extern_class thy class =
   224 fun extern_class thy class =
   143   Sign.extern_class thy (certify_class thy class);
   225   Sign.extern_class thy (certify_class thy class);
   144 
   226 
   145 
   227 
   146 (* classes and instances *)
   228 (* classes and instances *)
   147 
   229 
   148 fun subst_clsvar v ty_subst =
       
   149   map_type_tfree (fn u as (w, _) =>
       
   150     if w = v then ty_subst else TFree u);
       
   151 
       
   152 local
   230 local
   153 
   231 
   154 fun gen_add_class add_locale prep_class do_proof bname raw_supclasses raw_body thy =
   232 fun intern_expr thy (Locale.Locale xname) = Locale.Locale (Locale.intern thy xname)
   155   let
   233   | intern_expr thy (Locale.Merge exprs) = Locale.Merge (map (intern_expr thy) exprs)
   156     val supclasses = map (prep_class thy) raw_supclasses;
   234   | intern_expr thy (Locale.Rename (expr, xs)) = Locale.Rename (intern_expr thy expr, xs);
   157     fun get_allcs class =
   235 
   158       let
   236 fun gen_add_class add_locale prep_expr eval_expr do_proof bname raw_expr raw_body thy =
   159         val data = get_class_data thy class 
   237   let
   160       in
   238     val ((import_asms, supclasses), locexpr) = (eval_expr thy o prep_expr thy) raw_expr;
   161         Library.flat (map get_allcs (#superclasses data) @ [#consts data])
   239     val supsort =
   162       end;
   240       supclasses
   163     val supcs = Library.flat (map get_allcs supclasses)
   241       |> map (#name_axclass o the_class_data thy)
   164     val supsort = case map (#name_axclass o get_class_data thy) supclasses
   242       |> Sorts.certify_sort (Sign.classes_of thy)
   165      of [] => Sign.defaultS thy
   243       |> null ? K (Sign.defaultS thy);
   166       | sort => Sorts.certify_sort (Sign.classes_of thy) sort;
   244     val _ = writeln ("got sort: " ^ Sign.string_of_sort thy supsort);
   167     val locexpr = case supclasses
   245     val _ = writeln ("got asms: " ^ (cat_lines o map (Sign.string_of_term thy) o Library.flat o map (snd o fst)) import_asms);
   168      of [] => Locale.empty
   246     val supcs = (Library.flat o map (snd o the_consts_sign thy) o the_ancestry thy) supclasses;
   169       | _ => (Locale.Merge o map (Locale.Locale o #name_locale o get_class_data thy))
       
   170                 supclasses;
       
   171     fun mk_c_lookup c_global supcs c_adds =
   247     fun mk_c_lookup c_global supcs c_adds =
   172       map2 (fn ((c, _), _) => pair c) c_global supcs @ c_adds
   248       map2 (fn ((c, _), _) => pair c) c_global supcs @ c_adds;
   173     fun extract_tyvar_consts thy name_locale =
   249     fun extract_tyvar_consts thy name_locale =
   174       let
   250       let
   175         fun extract_tyvar_name thy tys =
   251         fun extract_tyvar_name thy tys =
   176           fold (curry add_typ_tfrees) tys []
   252           fold (curry add_typ_tfrees) tys []
   177           |> (fn [(v, sort)] =>
   253           |> (fn [(v, sort)] =>
   178                     if Sorts.sort_le (Sign.classes_of thy) (swap (sort, supsort))
   254                     if Sorts.sort_le (Sign.classes_of thy) (swap (sort, supsort))
   179                     then v 
   255                     then v
   180                     else error ("illegal sort constraint on class type variable: " ^ Sign.string_of_sort thy sort)
   256                     else error ("illegal sort constraint on class type variable: " ^ Sign.string_of_sort thy sort)
   181                | [] => error ("no class type variable")
   257                | [] => error ("no class type variable")
   182                | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs))
   258                | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs))
   183         val raw_consts =
   259         val raw_consts =
   184           Locale.parameters_of thy name_locale
   260           Locale.parameters_of thy name_locale
   185           |> map (apsnd Syntax.unlocalize_mixfix)
   261           |> map (apsnd Syntax.unlocalize_mixfix)
   186           |> ((curry splitAt o length) supcs);
   262           |> Library.chop (length supcs);
   187         val v = (extract_tyvar_name thy o map (snd o fst) o op @) raw_consts;
   263         val v = (extract_tyvar_name thy o map (snd o fst) o op @) raw_consts;
   188         fun subst_ty cs =
   264         fun subst_ty cs =
   189           map ((apfst o apsnd) (subst_clsvar v (TFree (v, [])))) cs;
   265           map ((apfst o apsnd) (subst_clsvar v (TFree (v, [])))) cs;
   190         val consts = (subst_ty (fst raw_consts), subst_ty (snd raw_consts));
   266         val consts = (subst_ty (fst raw_consts), subst_ty (snd raw_consts));
   191         val _ = (writeln o commas o map (fst o fst)) (fst consts);
   267         (*val _ = (writeln o commas o map (fst o fst)) (fst consts);
   192         val _ = (writeln o commas o map (fst o fst)) (snd consts);
   268         val _ = (writeln o commas o map (fst o fst)) (snd consts);*)
   193       in (v, consts) end;
   269       in (v, consts) end;
   194     fun add_global_const v ((c, ty), syn) thy =
   270     fun add_global_const v ((c, ty), syn) thy =
   195       thy
   271       thy
   196       |> Sign.add_consts_i [(c, ty |> subst_clsvar v (TFree (v, Sign.defaultS thy)), syn)]
   272       |> Sign.add_consts_i [(c, ty |> subst_clsvar v (TFree (v, Sign.defaultS thy)), syn)]
   197       |> `(fn thy => (c, (Sign.intern_const thy c |> print, ty)))
   273       |> `(fn thy => (c, (Sign.intern_const thy c, ty)))
       
   274     fun subst_assume c_lookup renaming =
       
   275       map_aterms (fn Free (c, ty) => Const ((fst o the o AList.lookup (op =) c_lookup o perhaps (AList.lookup (op =) renaming)) c, ty)
       
   276                    | t => t)
   198     fun extract_assumes thy name_locale c_lookup =
   277     fun extract_assumes thy name_locale c_lookup =
   199       Locale.local_asms_of thy name_locale
   278       map (rpair []) (Locale.local_asms_of thy name_locale) @ import_asms
   200       |> map snd
   279       |> map (fn (((name, atts), ts), renaming) => ((name, map (Attrib.attribute thy) atts), (map (subst_assume c_lookup renaming)) ts));
   201       |> Library.flat
   280     fun rearrange_assumes ((name, atts), ts) =
   202       |> (map o map_aterms) (fn Free (c, ty) => Const ((fst o the o AList.lookup (op =) c_lookup) c, ty)
   281       map (rpair atts o pair "") ts
   203                              | t => t)
       
   204       |> tap (fn ts => writeln ("(1) axclass axioms: " ^
       
   205           (commas o map (Sign.string_of_term thy)) ts));
       
   206     fun add_global_constraint v class (_, (c, ty)) thy =
   282     fun add_global_constraint v class (_, (c, ty)) thy =
   207       thy
   283       thy
   208       |> Sign.add_const_constraint_i (c, subst_clsvar v (TVar ((v, 0), [class])) ty);
   284       |> Sign.add_const_constraint_i (c, subst_clsvar v (TVar ((v, 0), [class])) ty);
   209     fun interpret name_locale cs ax_axioms thy =
   285     fun ad_hoc_const thy class v (c, ty) =
       
   286       let
       
   287         val ty' = subst_clsvar v (TFree (v, [class])) ty;
       
   288         val s_ty = setmp print_mode [] (setmp show_types true (setmp show_sorts true (Sign.string_of_typ thy))) ty';
       
   289         val s = c ^ "::" ^ enclose "(" ")" s_ty;
       
   290         val _ = writeln ("our constant: " ^ s);
       
   291       in SOME s end;
       
   292     fun interpret name_locale name_axclass v cs ax_axioms thy =
   210       thy
   293       thy
   211       |> Locale.interpretation (NameSpace.base name_locale, [])
   294       |> Locale.interpretation (NameSpace.base name_locale, [])
   212            (Locale.Locale name_locale) (map (SOME o fst) cs)
   295            (Locale.Locale name_locale) (map (ad_hoc_const thy name_axclass v) cs)
   213       |> do_proof ax_axioms;
   296       |> do_proof ax_axioms;
   214   in
   297   in
   215     thy
   298     thy
   216     |> add_locale bname locexpr raw_body
   299     |> add_locale bname locexpr raw_body
   217     |-> (fn ctxt =>
   300     |-> (fn ctxt =>
   221     #-> (fn (v, (c_global, c_defs)) =>
   304     #-> (fn (v, (c_global, c_defs)) =>
   222           fold_map (add_global_const v) c_defs
   305           fold_map (add_global_const v) c_defs
   223     #-> (fn c_adds =>
   306     #-> (fn c_adds =>
   224        `(fn thy => extract_assumes thy name_locale (mk_c_lookup c_global supcs c_adds))
   307        `(fn thy => extract_assumes thy name_locale (mk_c_lookup c_global supcs c_adds))
   225     #-> (fn assumes =>
   308     #-> (fn assumes =>
   226           AxClass.add_axclass_i (bname, supsort) (map (Thm.no_attributes o pair "") assumes))
   309           AxClass.add_axclass_i (bname, supsort) ((Library.flat o map rearrange_assumes) assumes))
   227     #-> (fn { axioms = ax_axioms : thm list, ...} =>
   310     #-> (fn { axioms = ax_axioms : thm list, ...} =>
   228           `(fn thy => Sign.intern_class thy bname)
   311           `(fn thy => Sign.intern_class thy bname)
   229     #-> (fn name_axclass =>
   312     #-> (fn name_axclass =>
   230           fold (add_global_constraint v name_axclass) c_adds
   313           fold (add_global_constraint v name_axclass) c_adds
   231     #> add_class_data (name_locale, (supclasses, name_locale, name_axclass, v, map snd c_adds))
   314     #> add_class_data (name_locale, (supclasses, name_locale, name_axclass, v, map snd c_adds))
   232     #> interpret name_locale (supcs @ (map (fn ((c, ty), _) => (Sign.intern_const thy c, ty)) c_defs)) ax_axioms
   315     #> interpret name_locale name_axclass v (supcs @ map snd c_adds) ax_axioms
   233     ))))))
   316     ))))))
   234   end;
   317   end;
   235 
   318 
       
   319 fun eval_expr_supclasses thy [] = (([], []), Locale.empty)
       
   320   | eval_expr_supclasses thy supclasses =
       
   321       (([], supclasses),
       
   322         (Locale.Merge o map (Locale.Locale o #name_locale o the_class_data thy)) supclasses);
       
   323 
   236 in
   324 in
   237 
   325 
   238 val add_class = gen_add_class (Locale.add_locale true) intern_class
   326 val add_class = gen_add_class (Locale.add_locale true) (map o intern_class)
   239   (fn ax_axioms => Proof.global_terminal_proof (Method.Basic (Method.fact ax_axioms), NONE));
   327   eval_expr_supclasses (fn ax_axioms => Proof.global_terminal_proof (Method.Basic (Method.fact ax_axioms), NONE));
   240 val add_class_i = gen_add_class (Locale.add_locale_i true) certify_class
   328 val add_class_i = gen_add_class (Locale.add_locale_i true) (map o certify_class)
   241   (fn ax_axioms => Proof.global_terminal_proof (Method.Basic (Method.fact ax_axioms), NONE));
   329   eval_expr_supclasses (fn ax_axioms => Proof.global_terminal_proof (Method.Basic (Method.fact ax_axioms), NONE));
   242 val add_class_exp = gen_add_class (Locale.add_locale true) intern_class
   330 val add_class_exp = gen_add_class (Locale.add_locale true) (map o intern_class)
   243   (K I);
   331   eval_expr_supclasses (K I);
   244 
   332 
   245 end; (* local *)
   333 end; (* local *)
   246 
   334 
   247 fun gen_instance_arity prep_arity add_defs tap_def raw_arity raw_defs thy = 
   335 fun gen_instance_arity prep_arity add_defs tap_def raw_arity raw_defs thy =
   248   let
   336   let
   249     val pp = Sign.pp thy;
   337     val pp = Sign.pp thy;
   250     val arity as (tyco, asorts, sort) = prep_arity thy ((fn ((x, y), z) => (x, y, z)) raw_arity);
   338     val arity as (tyco, asorts, sort) = prep_arity thy ((fn ((x, y), z) => (x, y, z)) raw_arity);
   251     val ty_inst = Type (tyco, map2 (curry TVar o rpair 0) (Term.invent_names [] "'a" (length asorts)) asorts)
   339     val ty_inst = Type (tyco, map2 (curry TVar o rpair 0) (Term.invent_names [] "'a" (length asorts)) asorts)
   252     fun get_c_req class =
   340     fun get_c_req class =
   253       let
   341       let
   254         val data = get_class_data thy class;
   342         val data = the_class_data thy class;
   255         val subst_ty = map_type_tfree (fn (var as (v, _)) =>
   343         val subst_ty = map_type_tfree (fn (var as (v, _)) =>
   256           if #var data = v then ty_inst else TFree var)
   344           if #var data = v then ty_inst else TFree var)
   257       in (map (apsnd subst_ty) o #consts) data end;
   345       in (map (apsnd subst_ty) o #consts) data end;
   258     val c_req = (Library.flat o map get_c_req) sort;
   346     val c_req = (Library.flat o map get_c_req) sort;
   259     fun get_remove_contraint c thy =
   347     fun get_remove_contraint c thy =
   270         val thy' = thy |> Theory.copy |> Sign.add_arities_i [(tyco, asorts, sort)];
   358         val thy' = thy |> Theory.copy |> Sign.add_arities_i [(tyco, asorts, sort)];
   271         fun get_c raw_def =
   359         fun get_c raw_def =
   272           (fst o Sign.cert_def pp o snd o tap_def thy' o fst) raw_def;
   360           (fst o Sign.cert_def pp o snd o tap_def thy' o fst) raw_def;
   273         val c_given = map get_c raw_defs;
   361         val c_given = map get_c raw_defs;
   274 (*         spec_opt_name   *)
   362 (*         spec_opt_name   *)
   275         fun eq_c ((c1, ty1), (c2, ty2)) = 
   363         fun eq_c ((c1, ty1), (c2, ty2)) =
   276           let
   364           let
   277             val ty1' = Type.varifyT ty1;
   365             val ty1' = Type.varifyT ty1;
   278             val ty2' = Type.varifyT ty2;
   366             val ty2' = Type.varifyT ty2;
   279           in
   367           in
   280             c1 = c2
   368             c1 = c2
   283           end;
   371           end;
   284         val _ = case fold (remove eq_c) c_req c_given
   372         val _ = case fold (remove eq_c) c_req c_given
   285          of [] => ()
   373          of [] => ()
   286           | cs => error ("superfluous definition(s) given for "
   374           | cs => error ("superfluous definition(s) given for "
   287                     ^ (commas o map (fn (c, ty) => quote (c ^ "::" ^ Sign.string_of_typ thy ty))) cs);
   375                     ^ (commas o map (fn (c, ty) => quote (c ^ "::" ^ Sign.string_of_typ thy ty))) cs);
   288         val _ = case fold (remove eq_c) c_given c_req
   376         (*val _ = case fold (remove eq_c) c_given c_req
   289          of [] => ()
   377       of [] => ()
   290           | cs => error ("no definition(s) given for "
   378           | cs => error ("no definition(s) given for "
   291                     ^ (commas o map (fn (c, ty) => quote (c ^ "::" ^ Sign.string_of_typ thy ty))) cs);
   379                     ^ (commas o map (fn (c, ty) => quote (c ^ "::" ^ Sign.string_of_typ thy ty))) cs);*)
   292       in thy end;
   380       in thy end;
   293     fun after_qed cs =
   381     fun after_qed cs =
   294       fold Sign.add_const_constraint_i cs
   382       fold Sign.add_const_constraint_i cs
   295       #> fold (fn class => add_inst_data (class, (tyco, Context.theory_name thy))) sort;
   383       #> fold (fn class => add_inst_data (class, (tyco, Context.theory_name thy))) sort;
   296   in
   384   in
   301     |-> (fn cs => AxClass.instance_arity_i (after_qed cs) arity)
   389     |-> (fn cs => AxClass.instance_arity_i (after_qed cs) arity)
   302   end;
   390   end;
   303 
   391 
   304 val add_instance_arity = gen_instance_arity (AxClass.read_arity) IsarThy.add_defs read_axm;
   392 val add_instance_arity = gen_instance_arity (AxClass.read_arity) IsarThy.add_defs read_axm;
   305 val add_instance_arity_i = gen_instance_arity (AxClass.cert_arity) IsarThy.add_defs_i (K I);
   393 val add_instance_arity_i = gen_instance_arity (AxClass.cert_arity) IsarThy.add_defs_i (K I);
   306 
       
   307 
       
   308 (* queries *)
       
   309 
       
   310 fun is_class thy cls =
       
   311   lookup_class_data thy cls
       
   312   |> Option.map (not o null o #consts)
       
   313   |> the_default false;
       
   314 
       
   315 fun operational_sort_of thy sort =
       
   316   let
       
   317     val classes = Sign.classes_of thy;
       
   318     fun get_sort cls =
       
   319       if is_class thy cls
       
   320       then [cls]
       
   321       else operational_sort_of thy (Sorts.superclasses classes cls);
       
   322   in
       
   323     map get_sort sort
       
   324     |> Library.flat
       
   325     |> Sorts.norm_sort classes
       
   326   end;
       
   327 
       
   328 fun the_superclasses thy class =
       
   329   if is_class thy class
       
   330   then
       
   331     Sorts.superclasses (Sign.classes_of thy) class
       
   332     |> operational_sort_of thy
       
   333   else
       
   334     error ("no syntactic class: " ^ class);
       
   335 
       
   336 fun the_consts_sign thy class =
       
   337   let
       
   338     val data = (the oo Symtab.lookup) ((fst o ClassData.get) thy) class
       
   339   in (#var data, #consts data) end;
       
   340 
       
   341 fun lookup_const_class thy =
       
   342   Symtab.lookup ((snd o ClassData.get) thy);
       
   343 
       
   344 fun the_instances thy class =
       
   345   (#insts o the o Symtab.lookup ((fst o ClassData.get) thy)) class;
       
   346 
       
   347 fun the_inst_sign thy (class, tyco) =
       
   348   let
       
   349     val _ = if is_class thy class then () else error ("no syntactic class: " ^ class);
       
   350     val arity = 
       
   351       Sorts.mg_domain (Sign.classes_arities_of thy) tyco [class]
       
   352       |> map (operational_sort_of thy);
       
   353     val clsvar = (#var o the o Symtab.lookup ((fst o ClassData.get) thy)) class;
       
   354     val const_sign = (snd o the_consts_sign thy) class;
       
   355     fun add_var sort used =
       
   356       let
       
   357         val v = hd (Term.invent_names used "'a" 1)
       
   358       in ((v, sort), v::used) end;
       
   359     val (vsorts, _) =
       
   360       []
       
   361       |> fold (fn (_, ty) => curry (gen_union (op =))
       
   362            ((map (fst o fst) o typ_tvars) ty @ (map fst o typ_tfrees) ty)) const_sign
       
   363       |> fold_map add_var arity;
       
   364     val ty_inst = Type (tyco, map (fn (v, sort) => TVar ((v, 0), sort)) vsorts);
       
   365     val inst_signs = map (apsnd (subst_clsvar clsvar ty_inst)) const_sign;
       
   366   in (vsorts, inst_signs) end;
       
   367 
       
   368 fun get_classtab thy =
       
   369   Symtab.fold
       
   370     (fn (class, { consts = consts, insts = insts, ... }) =>
       
   371       Symtab.update_new (class, (map fst consts, insts)))
       
   372        ((fst o ClassData.get) thy) Symtab.empty;
       
   373 
   394 
   374 
   395 
   375 (* extracting dictionary obligations from types *)
   396 (* extracting dictionary obligations from types *)
   376 
   397 
   377 type sortcontext = (string * sort) list;
   398 type sortcontext = (string * sort) list;
   432     fun reorder_sortctxt ctxt =
   453     fun reorder_sortctxt ctxt =
   433       case lookup_const_class thy c
   454       case lookup_const_class thy c
   434        of NONE => ctxt
   455        of NONE => ctxt
   435         | SOME class =>
   456         | SOME class =>
   436             let
   457             let
   437               val data = (the o Symtab.lookup ((fst o ClassData.get) thy)) class;
   458               val data = the_class_data thy class;
   438               val sign = (Type.varifyT o the o AList.lookup (op =) (#consts data)) c;
   459               val sign = (Type.varifyT o the o AList.lookup (op =) (#consts data)) c;
   439               val match_tab = Sign.typ_match thy (sign, typ_def) Vartab.empty;
   460               val match_tab = Sign.typ_match thy (sign, typ_def) Vartab.empty;
   440               val v : string = case Vartab.lookup match_tab (#var data, 0)
   461               val v : string = case Vartab.lookup match_tab (#var data, 0)
   441                 of SOME (_, TVar ((v, _), _)) => v;
   462                 of SOME (_, TVar ((v, _), _)) => v;
   442             in
   463             in
   465     val class = Sign.intern_class thy raw_class;
   486     val class = Sign.intern_class thy raw_class;
   466     val cs_proto =
   487     val cs_proto =
   467       raw_cs
   488       raw_cs
   468       |> map (Sign.intern_const thy)
   489       |> map (Sign.intern_const thy)
   469       |> map (fn c => (c, Sign.the_const_constraint thy c));
   490       |> map (fn c => (c, Sign.the_const_constraint thy c));
   470     val used = 
   491     val used =
   471       []
   492       []
   472       |> fold (fn (_, ty) => curry (gen_union (op =))
   493       |> fold (fn (_, ty) => curry (gen_union (op =))
   473            ((map (fst o fst) o typ_tvars) ty @ (map fst o typ_tfrees) ty)) cs_proto
   494            ((map (fst o fst) o typ_tvars) ty @ (map fst o typ_tfrees) ty)) cs_proto
   474     val v = hd (Term.invent_names used "'a" 1);
   495     val v = hd (Term.invent_names used "'a" 1);
   475     val cs =
   496     val cs =
   509     Scan.repeat P.sort --| P.$$$ "::" -- P.sort
   530     Scan.repeat P.sort --| P.$$$ "::" -- P.sort
   510     || P.$$$ "::" |-- P.!!! P.arity
   531     || P.$$$ "::" |-- P.!!! P.arity
   511   )
   532   )
   512   >> (fn (tyco, (asorts, sort)) => ((tyco, asorts), sort))
   533   >> (fn (tyco, (asorts, sort)) => ((tyco, asorts), sort))
   513 
   534 
       
   535 val locale_val =
       
   536   (P.locale_expr --
       
   537     Scan.optional (P.$$$ "+" |-- P.!!! (Scan.repeat1 P.context_element)) [] ||
       
   538   Scan.repeat1 P.context_element >> pair Locale.empty);
       
   539 
   514 val classP =
   540 val classP =
   515   OuterSyntax.command classK "operational type classes" K.thy_decl (
   541   OuterSyntax.command classK "operational type classes" K.thy_decl (
   516     P.name --| P.$$$ "="
   542     P.name --| P.$$$ "="
   517     -- Scan.optional (Scan.repeat1 (P.name --| P.$$$ "+")) []
   543     -- Scan.optional (Scan.repeat1 (P.name --| P.$$$ "+")) []
   518     -- Scan.optional (P.!!! (Scan.repeat1 P.context_element)) []
   544     -- Scan.optional (P.!!! (Scan.repeat1 P.context_element)) []
   522 val classP_exp =
   548 val classP_exp =
   523   OuterSyntax.command (classK ^ "_exp") "operational type classes" K.thy_goal (
   549   OuterSyntax.command (classK ^ "_exp") "operational type classes" K.thy_goal (
   524     P.name --| P.$$$ "="
   550     P.name --| P.$$$ "="
   525     -- Scan.optional (Scan.repeat1 (P.name --| P.$$$ "+")) []
   551     -- Scan.optional (Scan.repeat1 (P.name --| P.$$$ "+")) []
   526     -- Scan.optional (P.!!! (Scan.repeat1 P.context_element)) []
   552     -- Scan.optional (P.!!! (Scan.repeat1 P.context_element)) []
   527       >> (Toplevel.print oo Toplevel.theory_to_proof
   553       >> ((Toplevel.print oo Toplevel.theory_to_proof)
   528           o (fn ((bname, supclasses), elems) => add_class_exp bname supclasses elems)));
   554           o (fn ((bname, supclasses), elems) => add_class_exp bname supclasses elems)));
   529 
   555 
   530 val instanceP =
   556 val instanceP =
   531   OuterSyntax.command instanceK "prove type arity or subclass relation" K.thy_goal ((
   557   OuterSyntax.command instanceK "prove type arity or subclass relation" K.thy_goal ((
   532       P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname) >> AxClass.instance_subclass
   558       P.xname -- ((P.$$$ "\\<subseteq>" || P.$$$ "<") |-- P.!!! P.xname) >> AxClass.instance_subclass