src/Pure/Tools/class_package.ML
author haftmann
Tue, 03 Jan 2006 11:32:16 +0100
changeset 18550 59b89f625d68
parent 18515 1cad5c2b2a0b
child 18575 9ccfd1d1e874
permissions -rw-r--r--
add_local_context now yields imported and body elements seperatly; additional slight clenup in code
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
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    10
  val add_class: bstring -> Locale.expr -> Element.context list -> theory
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    11
    -> ProofContext.context * theory
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    12
  val add_class_i: bstring -> Locale.expr -> Element.context_i list -> theory
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    13
    -> ProofContext.context * theory
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    14
  val add_classentry: class -> xstring list -> xstring list -> theory -> theory
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    15
  val the_consts: theory -> class -> string list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    16
  val the_tycos: theory -> class -> (string * string) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    17
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
    18
  val syntactic_sort_of: theory -> sort -> sort
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    19
  val get_arities: theory -> sort -> string -> sort list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    20
  val get_superclasses: theory -> class -> class list
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
    21
  val get_const_sign: theory -> string -> string -> typ
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    22
  val get_inst_consts_sign: theory -> string * class -> (string * typ) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    23
  val lookup_const_class: theory -> string -> class option
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    24
  val get_classtab: theory -> (string list * (string * string) list) Symtab.table
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    25
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    26
  type sortcontext = (string * sort) list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    27
  datatype sortlookup = Instance of (class * string) * sortlookup list list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    28
                      | Lookup of class list * (string * int)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    29
  val extract_sortctxt: theory -> typ -> sortcontext
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    30
  val extract_sortlookup: theory -> typ * typ -> sortlookup list list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    31
end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    32
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    33
structure ClassPackage: CLASS_PACKAGE =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    34
struct
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
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    37
(* data kind 'Pure/classes' *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    38
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    39
type class_data = {
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    40
  locale_name: string,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    41
  axclass_name: string,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    42
  consts: string list,
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    43
  tycos: (string * string) list
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
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    46
structure ClassesData = TheoryDataFun (
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    47
  struct
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    48
    val name = "Pure/classes";
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    49
    type T = class_data Symtab.table * class Symtab.table;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    50
    val empty = (Symtab.empty, Symtab.empty);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    51
    val copy = I;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    52
    val extend = I;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    53
    fun merge _ ((t1, r1), (t2, r2))=
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    54
      (Symtab.merge (op =) (t1, t2),
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    55
       Symtab.merge (op =) (r1, r2));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    56
    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
    57
  end
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
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    60
val lookup_class_data = Symtab.lookup o fst o ClassesData.get;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    61
val lookup_const_class = Symtab.lookup o snd o ClassesData.get;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    62
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    63
fun get_class_data thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    64
  case lookup_class_data thy class
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    65
    of NONE => error ("undeclared class " ^ quote class)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    66
     | SOME data => data;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    67
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    68
fun put_class_data class data =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    69
  ClassesData.map (apfst (Symtab.update (class, data)));
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    70
fun add_const class const =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    71
  ClassesData.map (apsnd (Symtab.update (const, class)));
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    72
val the_consts = #consts oo get_class_data;
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    73
val the_tycos = #tycos oo get_class_data;
18168
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
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    76
(* name mangling *)
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_locale_for_class thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    79
  #locale_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
fun get_axclass_for_class thy class =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    82
  #axclass_name (get_class_data thy class);
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
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    85
(* classes *)
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    86
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    87
local
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    88
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    89
open Element
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    90
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    91
fun gen_add_class add_locale bname raw_import raw_body thy =
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
    92
  let
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    93
    fun extract_notes_consts thy elems =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    94
      elems
18550
59b89f625d68 add_local_context now yields imported and body elements seperatly; additional slight clenup in code
haftmann
parents: 18515
diff changeset
    95
      |> Library.flat
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    96
      |> List.mapPartial
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    97
           (fn (Notes notes) => SOME notes
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    98
             | _ => NONE)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
    99
      |> Library.flat
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   100
      |> map (fn (_, facts) => map fst facts)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   101
      |> Library.flat o Library.flat
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   102
      |> map prop_of
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   103
      |> (fn ts => fold (curry add_term_consts) ts [])
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   104
      |> tap (writeln o commas);
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   105
    fun extract_tyvar_name thy tys =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   106
      fold (curry add_typ_tfrees) tys []
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   107
      |> (fn [(v, [])] => v
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   108
           | [(v, sort)] =>
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   109
                if Sorts.sort_eq (Sign.classes_of thy) (Sign.defaultS thy, sort)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   110
                then v 
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   111
                else error ("sort constraint on class type variable: " ^ Sign.string_of_sort thy sort)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   112
           | [] => error ("no class type variable")
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   113
           | vs => error ("more than one type variable: " ^ (commas o map (Sign.string_of_typ thy o TFree)) vs))
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   114
    fun extract_tyvar_consts thy elems =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   115
      elems
18550
59b89f625d68 add_local_context now yields imported and body elements seperatly; additional slight clenup in code
haftmann
parents: 18515
diff changeset
   116
      |> Library.flat
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   117
      |> List.mapPartial
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   118
           (fn (Fixes consts) => SOME consts
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   119
             | _ => NONE)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   120
      |> Library.flat
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   121
      |> map (fn (c, ty, syn) => ((c, the ty), the syn))
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   122
      |> `(fn consts => extract_tyvar_name thy (map (snd o fst) consts));
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   123
    (* fun remove_local_syntax ((c, ty), _) thy =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   124
      thy
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   125
      |> Sign.add_syntax_i [(c, ty, Syntax.NoSyn)]; *)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   126
    fun add_global_const ((c, ty), syn) thy =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   127
      thy
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   128
      |> Sign.add_consts_i [(c, ty, syn)]
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   129
      |> `(fn thy => Sign.intern_const thy c)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   130
    fun add_axclass bname_axiom locale_pred cs thy =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   131
      thy
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   132
      |> AxClass.add_axclass_i (bname, Sign.defaultS thy)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   133
           [Thm.no_attributes (bname_axiom,
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   134
              Const (ObjectLogic.judgment_name thy, dummyT) $
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   135
                list_comb (Const (locale_pred, dummyT), map (fn c => Const (c, dummyT)) cs)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   136
              |> curry (inferT_axm thy) "locale_pred" |> snd)]
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   137
      |-> (fn _ => `(fn thy => Sign.intern_class thy bname))
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   138
    fun print_ctxt ctxt elem = 
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   139
      map Pretty.writeln (Element.pretty_ctxt ctxt elem)
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   140
  in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   141
    thy
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   142
    |> add_locale bname raw_import raw_body
18550
59b89f625d68 add_local_context now yields imported and body elements seperatly; additional slight clenup in code
haftmann
parents: 18515
diff changeset
   143
    |-> (fn ((_, elems : context_i list list), ctxt) =>
59b89f625d68 add_local_context now yields imported and body elements seperatly; additional slight clenup in code
haftmann
parents: 18515
diff changeset
   144
       tap (fn _ => (map o map) (print_ctxt ctxt) elems)
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   145
    #> tap (fn thy => extract_notes_consts thy elems)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   146
    #> `(fn thy => Locale.intern thy bname)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   147
    #-> (fn name_locale =>
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   148
       `(fn thy => extract_tyvar_consts thy elems)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   149
    #-> (fn (v, consts) =>
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   150
       fold_map add_global_const consts
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   151
    #-> (fn cs =>
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   152
       add_axclass (bname ^ "_intro") name_locale cs
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   153
    #-> (fn name_axclass =>
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   154
       put_class_data name_locale {
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   155
          locale_name = name_locale,
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   156
          axclass_name = name_axclass,
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   157
          consts = cs,
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   158
          tycos = []
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   159
        })
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   160
    #> fold (add_const name_locale) cs
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   161
    #> pair ctxt
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   162
    ))))
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   163
  end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   164
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   165
in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   166
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   167
val add_class = gen_add_class (Locale.add_locale_context true);
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   168
val add_class_i = gen_add_class (Locale.add_locale_context_i true);
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   169
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   170
end; (* local *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   171
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   172
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   173
(* class queries *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   174
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   175
fun is_class thy cls = lookup_class_data thy cls |> Option.map (not o null o #consts) |> the_default false;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   176
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   177
fun syntactic_sort_of thy sort =
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   178
  let
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   179
    val classes = Sign.classes_of thy;
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   180
    fun get_sort cls =
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   181
      if is_class thy cls
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   182
      then [cls]
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   183
      else syntactic_sort_of thy (Sorts.superclasses classes cls);
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   184
  in
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   185
    map get_sort sort
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   186
    |> Library.flat
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   187
    |> Sorts.norm_sort classes
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   188
  end;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   189
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   190
fun get_arities thy sort tycon =
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   191
  Sorts.mg_domain (Sign.classes_arities_of thy) tycon (syntactic_sort_of thy sort)
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   192
  |> map (syntactic_sort_of thy);
18168
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_superclasses thy class =
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   195
  if is_class thy class
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   196
  then
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   197
    Sorts.superclasses (Sign.classes_of thy) class
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   198
    |> syntactic_sort_of thy
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   199
  else
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   200
    error ("no syntactic class: " ^ class);
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   201
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
(* instance queries *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   204
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   205
fun get_const_sign thy tvar const =
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   206
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   207
    val class = (the o lookup_const_class thy) const;
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   208
    val (ty, thaw) = (Type.freeze_thaw_type o Sign.the_const_constraint thy) const;
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   209
    val tvars_used = Term.add_tfreesT ty [];
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   210
    val tvar_rename = hd (Term.invent_names (map fst tvars_used) tvar 1);
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   211
  in
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   212
    ty
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   213
    |> map_type_tfree (fn (tvar', sort) =>
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   214
          if Sorts.sort_eq (Sign.classes_of thy) ([class], sort)
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   215
          then TFree (tvar, [])
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   216
          else if tvar' = tvar
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   217
          then TVar ((tvar_rename, 0), sort)
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   218
          else TFree (tvar', sort))
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   219
    |> thaw
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   220
  end;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   221
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   222
fun get_inst_consts_sign thy (tyco, class) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   223
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   224
    val consts = the_consts thy class;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   225
    val arities = get_arities thy [class] tyco;
18304
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   226
    val const_signs = map (get_const_sign thy "'a") consts;
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   227
    val vars_used = fold (fn ty => curry (gen_union (op =))
684832c9fa62 minor improvements
haftmann
parents: 18168
diff changeset
   228
      (map fst (typ_tfrees ty) |> remove (op =) "'a")) const_signs [];
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   229
    val vars_new = Term.invent_names vars_used "'a" (length arities);
18330
444f16d232a2 introduced new map2, fold
haftmann
parents: 18304
diff changeset
   230
    val typ_arity = Type (tyco, map2 (curry TFree) vars_new arities);
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   231
    val instmem_signs =
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   232
      map (typ_subst_TVars [(("'a", 0), typ_arity)]) const_signs;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   233
  in consts ~~ instmem_signs end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   234
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   235
fun get_classtab thy =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   236
  Symtab.fold
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   237
    (fn (class, { consts = consts, tycos = tycos, ... }) =>
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   238
      Symtab.update_new (class, (consts, tycos)))
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   239
       (fst (ClassesData.get thy)) Symtab.empty;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   240
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   241
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   242
(* extracting dictionary obligations from types *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   243
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   244
type sortcontext = (string * sort) list;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   245
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   246
fun extract_sortctxt thy ty =
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   247
  (typ_tfrees o Type.no_tvars) ty
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   248
  |> map (apsnd (syntactic_sort_of thy))
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   249
  |> filter (not o null o snd);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   250
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   251
datatype sortlookup = Instance of (class * string) * sortlookup list list
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   252
                    | Lookup of class list * (string * int)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   253
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   254
fun extract_sortlookup thy (raw_typ_def, raw_typ_use) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   255
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   256
    val typ_def = Type.varifyT raw_typ_def;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   257
    val typ_use = Type.varifyT raw_typ_use;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   258
    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
   259
    fun tab_lookup vname = (the o Vartab.lookup match_tab) (vname, 0);
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   260
    fun get_superclass_derivation (subclasses, superclass) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   261
      (the oo get_first) (fn subclass =>
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   262
        Sorts.class_le_path (Sign.classes_of thy) (subclass, superclass)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   263
      ) subclasses;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   264
    fun mk_class_deriv thy subclasses superclass =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   265
      case get_superclass_derivation (subclasses, superclass)
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   266
      of (subclass::deriv) =>
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   267
        ((rev o filter (is_class thy)) deriv, find_index_eq subclass subclasses);
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   268
    fun mk_lookup (sort_def, (Type (tycon, tys))) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   269
          let
18330
444f16d232a2 introduced new map2, fold
haftmann
parents: 18304
diff changeset
   270
            val arity_lookup = map2 (curry mk_lookup)
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   271
              (map (syntactic_sort_of thy) (Sorts.mg_domain (Sign.classes_arities_of thy) tycon sort_def)) tys
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   272
          in map (fn class => Instance ((class, tycon), arity_lookup)) sort_def end
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   273
      | mk_lookup (sort_def, TVar ((vname, _), sort_use)) =
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   274
          let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   275
            fun mk_look class =
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   276
              let val (deriv, classindex) = mk_class_deriv thy (syntactic_sort_of thy sort_use) class
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   277
              in Lookup (deriv, (vname, classindex)) end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   278
          in map mk_look sort_def end;
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   279
  in
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   280
    extract_sortctxt thy ((fst o Type.freeze_thaw_type) raw_typ_def)
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   281
    |> map (tab_lookup o fst)
18360
a2c9506b62a7 improved class handling
haftmann
parents: 18335
diff changeset
   282
    |> map (apfst (syntactic_sort_of thy))
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   283
    |> filter (not o null o fst)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   284
    |> map mk_lookup
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   285
  end;
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
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   288
(* intermediate auxiliary *)
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   289
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   290
fun add_classentry raw_class raw_cs raw_tycos thy =
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   291
  let
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   292
    val class = Sign.intern_class thy raw_class;
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   293
    val cs = map (Sign.intern_const thy) raw_cs;
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   294
    val tycos = map (rpair (Context.theory_name thy) o Sign.intern_type thy) raw_tycos;
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   295
  in
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   296
    thy
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   297
    |> put_class_data class {
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   298
         locale_name = "",
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   299
         axclass_name = class,
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   300
         consts = cs,
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   301
         tycos = tycos
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   302
       }
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   303
    |> fold (add_const class) cs
18335
99baddf6b0d0 various improvements
haftmann
parents: 18330
diff changeset
   304
  end;
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   305
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   306
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   307
(* toplevel interface *)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   308
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   309
local
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   310
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   311
structure P = OuterParse
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   312
and K = OuterKeyword
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   313
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   314
in
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   315
18550
59b89f625d68 add_local_context now yields imported and body elements seperatly; additional slight clenup in code
haftmann
parents: 18515
diff changeset
   316
val classK = "class"
18515
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   317
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   318
val locale_val =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   319
  (P.locale_expr --
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   320
    Scan.optional (P.$$$ "+" |-- P.!!! (Scan.repeat1 P.context_element)) [] ||
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   321
  Scan.repeat1 P.context_element >> pair Locale.empty);
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   322
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   323
val classP =
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   324
  OuterSyntax.command classK "operational type classes" K.thy_decl
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   325
    (P.name -- Scan.optional (P.$$$ "=" |-- P.!!! locale_val) (Locale.empty, [])
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   326
      >> (Toplevel.theory_context
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   327
          o (fn f => swap o f) o (fn (name, (expr, elems)) => add_class name expr elems)));
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   328
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   329
val _ = OuterSyntax.add_parsers [classP];
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   330
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   331
end; (* local *)
1cad5c2b2a0b substantial improvements in code generating
haftmann
parents: 18380
diff changeset
   332
18168
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   333
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   334
(* setup *)
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   335
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   336
val _ = Context.add_setup [ClassesData.init];
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   337
d35daf321b8a class_package - operational view on type classes
haftmann
parents:
diff changeset
   338
end; (* struct *)