src/Pure/Tools/class_package.ML
author haftmann
Wed, 30 Nov 2005 18:13:31 +0100
changeset 18304 684832c9fa62
parent 18168 d35daf321b8a
child 18330 444f16d232a2
permissions -rw-r--r--
minor improvements
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     1
(*  Title:      Pure/Tools/class_package.ML
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     2
    ID:         $Id$
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     4
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     5
Haskell98-like operational view on type classes.
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     6
*)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     7
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     8
signature CLASS_PACKAGE =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
     9
sig
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    10
  val add_consts: class * xstring list -> theory -> theory
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    11
  val add_consts_i: class * string list -> theory -> theory
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    12
  val add_tycos: class * xstring list -> theory -> theory
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    13
  val add_tycos_i: class * (string * string) list -> theory -> theory
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    14
  val the_consts: theory -> class -> string list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    15
  val the_tycos: theory -> class -> (string * string) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    16
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    17
  val is_class: theory -> class -> bool
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    18
  val get_arities: theory -> sort -> string -> sort list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    19
  val get_superclasses: theory -> class -> class list
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
    20
  val get_const_sign: theory -> string -> string -> typ
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    21
  val get_inst_consts_sign: theory -> string * class -> (string * typ) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    22
  val lookup_const_class: theory -> string -> class option
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    23
  val get_classtab: theory -> (string list * (string * string) list) Symtab.table
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    24
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    25
  type sortcontext = (string * sort) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    26
  datatype sortlookup = Instance of (class * string) * sortlookup list list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    27
                      | Lookup of class list * (string * int)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    28
  val extract_sortctxt: theory -> typ -> sortcontext
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    29
  val extract_sortlookup: theory -> typ * typ -> sortlookup list list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    30
end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    31
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    32
structure ClassPackage: CLASS_PACKAGE =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    33
struct
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    34
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    35
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    36
(* data kind 'Pure/classes' *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    37
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    38
type class_data = {
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    39
  locale_name: string,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    40
  axclass_name: string,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    41
  consts: string list,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    42
  tycos: (string * string) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    43
};
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    44
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    45
structure ClassesData = TheoryDataFun (
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    46
  struct
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    47
    val name = "Pure/classes";
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    48
    type T = class_data Symtab.table * class Symtab.table;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    49
    val empty = (Symtab.empty, Symtab.empty);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    50
    val copy = I;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    51
    val extend = I;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    52
    fun merge _ ((t1, r1), (t2, r2))=
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    53
      (Symtab.merge (op =) (t1, t2),
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    54
       Symtab.merge (op =) (r1, r2));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    55
    fun print _ (tab, _) = (Pretty.writeln o Pretty.chunks) (map Pretty.str (Symtab.keys tab));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    56
  end
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    57
);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    58
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    59
val lookup_class_data = Symtab.lookup o fst o ClassesData.get;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    60
val lookup_const_class = Symtab.lookup o snd o ClassesData.get;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    61
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    62
fun get_class_data thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    63
  case lookup_class_data thy class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    64
    of NONE => error ("undeclared class " ^ quote class)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    65
     | SOME data => data;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    66
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    67
fun put_class_data class data =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    68
  ClassesData.map (apfst (Symtab.update (class, data)));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    69
fun add_const class const =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    70
  ClassesData.map (apsnd (Symtab.update (const, class)));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    71
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    72
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    73
(* name mangling *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    74
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    75
fun get_locale_for_class thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    76
  #locale_name (get_class_data thy class);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    77
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    78
fun get_axclass_for_class thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    79
  #axclass_name (get_class_data thy class);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    80
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    81
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    82
(* assign consts to type classes *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    83
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    84
local
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    85
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    86
fun gen_add_consts prep_class prep_const (raw_class, raw_consts_new) thy =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    87
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    88
    val class = prep_class thy raw_class;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    89
    val consts_new = map (prep_const thy) raw_consts_new;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    90
    val {locale_name, axclass_name, consts, tycos} =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    91
      get_class_data thy class;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    92
  in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    93
    thy
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    94
    |> put_class_data class {
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    95
         locale_name = locale_name,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    96
         axclass_name = axclass_name,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    97
         consts = consts @ consts_new,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    98
         tycos = tycos
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    99
       }
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   100
    |> fold (add_const class) consts_new
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   101
  end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   102
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   103
in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   104
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   105
val add_consts = gen_add_consts Sign.intern_class Sign.intern_const;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   106
val add_consts_i = gen_add_consts (K I) (K I);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   107
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   108
end; (* local *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   109
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   110
val the_consts = #consts oo get_class_data;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   111
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   112
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   113
(* assign type constructors to type classes *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   114
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   115
local
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   116
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   117
fun gen_add_tycos prep_class prep_type (raw_class, raw_tycos_new) thy =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   118
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   119
    val class = prep_class thy raw_class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   120
    val tycos_new = map (prep_type thy) raw_tycos_new
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   121
    val {locale_name, axclass_name, consts, tycos} =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   122
      get_class_data thy class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   123
  in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   124
    thy
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   125
    |> put_class_data class {
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   126
         locale_name = locale_name,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   127
         axclass_name = axclass_name,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   128
         consts = consts,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   129
         tycos = tycos @ tycos_new
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   130
       }
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   131
  end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   132
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   133
in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   134
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   135
fun add_tycos xs thy =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   136
  gen_add_tycos Sign.intern_class (rpair (Context.theory_name thy) oo Sign.intern_type) xs thy;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   137
val add_tycos_i = gen_add_tycos (K I) (K I);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   138
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   139
end; (* local *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   140
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   141
val the_tycos = #tycos oo get_class_data;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   142
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   143
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   144
(* class queries *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   145
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   146
fun is_class thy = is_some o lookup_class_data thy;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   147
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   148
fun filter_class thy = filter (is_class thy);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   149
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   150
fun assert_class thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   151
  if is_class thy class then class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   152
  else error ("not a class: " ^ quote class);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   153
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   154
fun get_arities thy sort tycon =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   155
  Sorts.mg_domain (Sign.classes_arities_of thy) tycon sort
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   156
  |> (map o map) (assert_class thy);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   157
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   158
fun get_superclasses thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   159
  Sorts.superclasses (Sign.classes_of thy) class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   160
  |> filter_class thy;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   161
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   162
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   163
(* instance queries *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   164
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   165
fun get_const_sign thy tvar const =
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   166
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   167
    val class = (the o lookup_const_class thy) const;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   168
    val ty = (Type.unvarifyT o Sign.the_const_constraint thy) const;
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   169
    val tvars_used = Term.add_tfreesT ty [];
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   170
    val tvar_rename = hd (Term.invent_names (map fst tvars_used) tvar 1);
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   171
  in
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   172
    ty
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   173
    |> map_type_tfree (fn (tvar', sort) =>
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   174
          if Sorts.sort_eq (Sign.classes_of thy) ([class], sort)
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   175
          then TFree (tvar, [])
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   176
          else if tvar' = tvar
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   177
          then TFree (tvar_rename, sort)
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   178
          else TFree (tvar', sort))
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   179
  end;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   180
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   181
fun get_inst_consts_sign thy (tyco, class) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   182
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   183
    val consts = the_consts thy class;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   184
    val arities = get_arities thy [class] tyco;
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   185
    val const_signs = map (get_const_sign thy "'a") consts;
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   186
    val vars_used = fold (fn ty => curry (gen_union (op =))
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   187
      (map fst (typ_tfrees ty) |> remove (op =) "'a")) const_signs [];
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   188
    val vars_new = Term.invent_names vars_used "'a" (length arities);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   189
    val typ_arity = Type (tyco, map2 TFree (vars_new, arities));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   190
    val instmem_signs =
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   191
      map (typ_subst_atomic [(TFree ("'a", []), typ_arity)]) const_signs;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   192
  in consts ~~ instmem_signs end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   193
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   194
fun get_classtab thy =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   195
  Symtab.fold
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   196
    (fn (class, { consts = consts, tycos = tycos, ... }) =>
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   197
      Symtab.update_new (class, (consts, tycos)))
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   198
       (fst (ClassesData.get thy)) Symtab.empty;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   199
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   200
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   201
(* extracting dictionary obligations from types *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   202
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   203
type sortcontext = (string * sort) list;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   204
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   205
fun extract_sortctxt thy typ =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   206
  (typ_tfrees o Type.unvarifyT) typ
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   207
  |> map (apsnd (filter_class thy))
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   208
  |> filter (not o null o snd);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   209
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   210
datatype sortlookup = Instance of (class * string) * sortlookup list list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   211
                    | Lookup of class list * (string * int)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   212
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   213
fun extract_sortlookup thy (raw_typ_def, raw_typ_use) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   214
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   215
    val typ_def = Type.varifyT raw_typ_def;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   216
    val typ_use = Type.varifyT raw_typ_use;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   217
    val match_tab = Sign.typ_match thy (typ_def, typ_use) Vartab.empty;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   218
    fun tab_lookup vname = (the o Vartab.lookup match_tab) (vname, 0);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   219
    fun get_superclass_derivation (subclasses, superclass) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   220
      (the oo get_first) (fn subclass =>
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   221
        Sorts.class_le_path (Sign.classes_of thy) (subclass, superclass)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   222
      ) subclasses;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   223
    fun mk_class_deriv thy subclasses superclass =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   224
      case get_superclass_derivation (subclasses, superclass)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   225
      of (subclass::deriv) => (rev deriv, find_index_eq subclass subclasses);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   226
    fun mk_lookup (sort_def, (Type (tycon, tys))) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   227
          let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   228
            val arity_lookup = map2 mk_lookup
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   229
              (map (filter_class thy) (Sorts.mg_domain (Sign.classes_arities_of thy) tycon sort_def), tys)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   230
          in map (fn class => Instance ((class, tycon), arity_lookup)) sort_def end
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   231
      | mk_lookup (sort_def, TVar ((vname, _), sort_use)) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   232
          let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   233
            fun mk_look class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   234
              let val (deriv, classindex) = mk_class_deriv thy sort_use class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   235
              in Lookup (deriv, (vname, classindex)) end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   236
          in map mk_look sort_def end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   237
  in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   238
    extract_sortctxt thy raw_typ_def
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   239
    |> map (tab_lookup o fst)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   240
    |> map (apfst (filter_class thy))
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   241
    |> filter (not o null o fst)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   242
    |> map mk_lookup
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   243
  end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   244
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   245
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   246
(* outer syntax *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   247
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   248
local
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   249
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   250
structure P = OuterParse
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   251
and K = OuterKeyword;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   252
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   253
in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   254
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   255
val classcgK = "codegen_class";
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   256
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   257
fun classcg raw_class raw_consts raw_tycos thy =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   258
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   259
    val class = Sign.intern_class thy raw_class;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   260
  in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   261
    thy
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   262
    |> put_class_data class {
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   263
         locale_name = "",
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   264
         axclass_name = class,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   265
         consts = [],
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   266
         tycos = []
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   267
       }
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   268
    |> add_consts (class, raw_consts)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   269
    |> add_tycos (class, raw_tycos)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   270
  end
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   271
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   272
val classcgP =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   273
  OuterSyntax.command classcgK "codegen data for classes" K.thy_decl (
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   274
    P.xname
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   275
    -- ((P.$$$ "\\<Rightarrow>" || P.$$$ "=>") |-- (P.list1 P.name))
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   276
    -- (Scan.optional ((P.$$$ "\\<Rightarrow>" || P.$$$ "=>") |-- (P.list1 P.name)) [])
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   277
    >> (fn ((name, tycos), consts) => (Toplevel.theory (classcg name consts tycos)))
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   278
  )
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   279
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   280
val _ = OuterSyntax.add_parsers [classcgP];
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   281
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   282
val _ = OuterSyntax.add_keywords ["\\<Rightarrow>", "=>"];
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   283
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   284
end; (* local *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   285
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   286
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   287
(* setup *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   288
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   289
val _ = Context.add_setup [ClassesData.init];
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   290
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   291
end; (* struct *)