src/Pure/Tools/codegen_consts.ML
author haftmann
Tue, 29 Aug 2006 14:31:15 +0200
changeset 20428 67fa1c6ba89e
parent 20389 8b6ecb22ef35
child 20456 42be3a46dcd8
permissions -rw-r--r--
refinements
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
20387
haftmann
parents:
diff changeset
     1
(*  Title:      Pure/Tools/codegen_consts.ML
haftmann
parents:
diff changeset
     2
    ID:         $Id$
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
haftmann
parents:
diff changeset
     4
haftmann
parents:
diff changeset
     5
Distinction of ad-hoc overloaded constants. Convenient data structures
haftmann
parents:
diff changeset
     6
for constants.
haftmann
parents:
diff changeset
     7
*)
haftmann
parents:
diff changeset
     8
haftmann
parents:
diff changeset
     9
signature CODEGEN_CONSTS =
haftmann
parents:
diff changeset
    10
sig
haftmann
parents:
diff changeset
    11
  type const = string * typ list (*type instantiations*)
haftmann
parents:
diff changeset
    12
  val const_ord: const * const -> order
haftmann
parents:
diff changeset
    13
  val eq_const: const * const -> bool
haftmann
parents:
diff changeset
    14
  structure Consttab: TABLE
haftmann
parents:
diff changeset
    15
  val typinst_of_typ: theory -> string * typ -> const
haftmann
parents:
diff changeset
    16
  val typ_of_typinst: theory -> const -> string * typ
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    17
  val find_def: theory -> const
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    18
    -> ((string (*theory name*) * string (*definition name*)) * typ list) option
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    19
  val sortinsts: theory -> typ * typ -> (typ * sort) list
20387
haftmann
parents:
diff changeset
    20
  val norminst_of_typ: theory -> string * typ -> const
haftmann
parents:
diff changeset
    21
  val class_of_classop: theory -> const -> class option
haftmann
parents:
diff changeset
    22
  val insts_of_classop: theory -> const -> const list
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    23
  val typ_of_classop: theory -> const -> typ
20387
haftmann
parents:
diff changeset
    24
  val read_const: theory -> string -> const
haftmann
parents:
diff changeset
    25
  val read_const_typ: theory -> string -> string * typ
haftmann
parents:
diff changeset
    26
  val string_of_const: theory -> const -> string
haftmann
parents:
diff changeset
    27
  val string_of_const_typ: theory -> string * typ -> string
haftmann
parents:
diff changeset
    28
end;
haftmann
parents:
diff changeset
    29
haftmann
parents:
diff changeset
    30
structure CodegenConsts: CODEGEN_CONSTS =
haftmann
parents:
diff changeset
    31
struct
haftmann
parents:
diff changeset
    32
haftmann
parents:
diff changeset
    33
haftmann
parents:
diff changeset
    34
(* basic data structures *)
haftmann
parents:
diff changeset
    35
haftmann
parents:
diff changeset
    36
type const = string * typ list (*type instantiations*);
haftmann
parents:
diff changeset
    37
val const_ord = prod_ord fast_string_ord (list_ord Term.typ_ord);
haftmann
parents:
diff changeset
    38
val eq_const = is_equal o const_ord;
haftmann
parents:
diff changeset
    39
haftmann
parents:
diff changeset
    40
structure Consttab =
haftmann
parents:
diff changeset
    41
  TableFun(
haftmann
parents:
diff changeset
    42
    type key = string * typ list;
haftmann
parents:
diff changeset
    43
    val ord = const_ord;
haftmann
parents:
diff changeset
    44
  );
haftmann
parents:
diff changeset
    45
haftmann
parents:
diff changeset
    46
haftmann
parents:
diff changeset
    47
(* type instantiations and overloading *)
haftmann
parents:
diff changeset
    48
haftmann
parents:
diff changeset
    49
fun typinst_of_typ thy (c_ty as (c, ty)) =
haftmann
parents:
diff changeset
    50
  (c, Consts.typargs (Sign.consts_of thy) c_ty);
haftmann
parents:
diff changeset
    51
haftmann
parents:
diff changeset
    52
fun typ_of_typinst thy (c_tys as (c, tys)) =
haftmann
parents:
diff changeset
    53
  (c, Consts.instance (Sign.consts_of thy) c_tys);
haftmann
parents:
diff changeset
    54
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    55
fun find_def thy (c, tys) =
20387
haftmann
parents:
diff changeset
    56
  let
haftmann
parents:
diff changeset
    57
    val specs = Defs.specifications_of (Theory.defs_of thy) c;
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    58
    val typ_instance = case AxClass.class_of_param thy c
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    59
     of SOME _ => let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    60
          fun instance_tycos (Type (tyco1, _), Type (tyco2, _)) = tyco1 = tyco2
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    61
            | instance_tycos (_ , TVar _) = true
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    62
            | instance_tycos ty_ty = Sign.typ_instance thy ty_ty;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    63
        in instance_tycos end
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    64
      | NONE =>  Sign.typ_instance thy
20387
haftmann
parents:
diff changeset
    65
  in
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    66
    get_first (fn (_, { is_def, thyname, name, lhs, ... }) => if is_def
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    67
      andalso forall typ_instance (tys ~~ lhs)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    68
      then SOME ((thyname, name), lhs) else NONE) specs
20387
haftmann
parents:
diff changeset
    69
  end;
haftmann
parents:
diff changeset
    70
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    71
fun sortinsts thy (ty, ty_decl) =
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    72
  Vartab.empty
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    73
  |> Sign.typ_match thy (ty_decl, ty) 
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    74
  |> Vartab.dest
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    75
  |> map (fn (_, (sort, ty)) => (ty, sort));
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    76
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    77
fun mk_classop_typinst thy (c, tyco) =
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    78
  (c, [Type (tyco, map (fn v => TVar ((v, 0), Sign.defaultS thy (*for monotonicity*)))
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    79
    (Name.invents Name.context "'a" (Sign.arity_number thy tyco)))]);
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    80
20387
haftmann
parents:
diff changeset
    81
fun norminst_of_typ thy (c, ty) =
haftmann
parents:
diff changeset
    82
  let
haftmann
parents:
diff changeset
    83
    fun disciplined _ [(Type (tyco, _))] =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    84
          mk_classop_typinst thy (c, tyco)
20387
haftmann
parents:
diff changeset
    85
      | disciplined sort _ =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    86
          (c, [TVar (("'a", 0), sort)]);
20387
haftmann
parents:
diff changeset
    87
    fun ad_hoc c tys =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    88
      case find_def thy (c, tys)
20387
haftmann
parents:
diff changeset
    89
       of SOME (_, tys) => (c, tys)
haftmann
parents:
diff changeset
    90
        | NONE => typinst_of_typ thy (c, Sign.the_const_type thy c);
haftmann
parents:
diff changeset
    91
    val tyinsts = Consts.typargs (Sign.consts_of thy) (c, ty);
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    92
  in if c = "op =" then disciplined (Sign.defaultS thy) tyinsts
20387
haftmann
parents:
diff changeset
    93
    (*the distinction on op = will finally disappear!*)
haftmann
parents:
diff changeset
    94
    else case AxClass.class_of_param thy c
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    95
     of SOME class => disciplined [class] tyinsts
20387
haftmann
parents:
diff changeset
    96
      | _ => ad_hoc c tyinsts
haftmann
parents:
diff changeset
    97
  end;
haftmann
parents:
diff changeset
    98
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    99
fun class_of_classop thy (c, [TVar _]) = 
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   100
      AxClass.class_of_param thy c
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   101
  | class_of_classop thy (c, [TFree _]) = 
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   102
      AxClass.class_of_param thy c
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   103
  | class_of_classop thy (c, _) = NONE;
20387
haftmann
parents:
diff changeset
   104
haftmann
parents:
diff changeset
   105
fun insts_of_classop thy (c_tys as (c, tys)) =
20428
67fa1c6ba89e refinements
haftmann
parents: 20389
diff changeset
   106
  (*get rid of this finally*)
20387
haftmann
parents:
diff changeset
   107
  case AxClass.class_of_param thy c
haftmann
parents:
diff changeset
   108
   of NONE => [c_tys]
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   109
    | SOME class => let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   110
        val cs = maps (AxClass.params_of thy)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   111
          (Sorts.all_super_classes (Sign.classes_of thy) class)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   112
        fun add_tyco (tyco, classes) =
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   113
          if member (op = o apsnd fst) classes class
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   114
          then cons tyco else I;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   115
        val tycos =
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   116
          Symtab.fold add_tyco
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   117
            ((#arities o Sorts.rep_algebra o Sign.classes_of) thy) [];
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   118
      in maps (fn c => map (fn tyco => mk_classop_typinst thy (c, tyco)) tycos) cs end;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   119
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   120
fun typ_of_classop thy (c, [TVar _]) = 
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   121
      let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   122
        val class = (the o AxClass.class_of_param thy) c;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   123
        val (v, cs) = ClassPackage.the_consts_sign thy class
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   124
      in
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   125
        (Logic.varifyT o map_type_tfree (fn u as (w, _) => if w = v then TFree (v, [class]) else TFree u))
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   126
          ((the o AList.lookup (op =) cs) c)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   127
      end
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   128
  | typ_of_classop thy (c, [TFree _]) = 
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   129
      let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   130
        val class = (the o AxClass.class_of_param thy) c;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   131
        val (v, cs) = ClassPackage.the_consts_sign thy class
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   132
      in
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   133
        (Logic.varifyT o map_type_tfree (fn u as (w, _) => if w = v then TFree (v, [class]) else TFree u))
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   134
          ((the o AList.lookup (op =) cs) c)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   135
      end
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   136
  | typ_of_classop thy (c, [Type (tyco, _)]) =
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   137
      let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   138
        val class = (the o AxClass.class_of_param thy) c;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   139
        val (_, cs) = ClassPackage.the_inst_sign thy (class, tyco);
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   140
      in
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   141
        Logic.varifyT ((the o AList.lookup (op =) cs) c)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   142
      end;
20387
haftmann
parents:
diff changeset
   143
haftmann
parents:
diff changeset
   144
haftmann
parents:
diff changeset
   145
(* reading constants as terms *)
haftmann
parents:
diff changeset
   146
haftmann
parents:
diff changeset
   147
fun read_const_typ thy raw_t =
haftmann
parents:
diff changeset
   148
  let
haftmann
parents:
diff changeset
   149
    val t = Sign.read_term thy raw_t
haftmann
parents:
diff changeset
   150
  in case try dest_Const t
haftmann
parents:
diff changeset
   151
   of SOME c_ty => c_ty
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   152
    | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t)
20387
haftmann
parents:
diff changeset
   153
  end;
haftmann
parents:
diff changeset
   154
haftmann
parents:
diff changeset
   155
fun read_const thy =
haftmann
parents:
diff changeset
   156
  typinst_of_typ thy o read_const_typ thy;
haftmann
parents:
diff changeset
   157
haftmann
parents:
diff changeset
   158
haftmann
parents:
diff changeset
   159
(* printing constants *)
haftmann
parents:
diff changeset
   160
haftmann
parents:
diff changeset
   161
fun string_of_const thy (c, tys) =
haftmann
parents:
diff changeset
   162
  space_implode " " (Sign.extern_const thy c
haftmann
parents:
diff changeset
   163
    :: map (enclose "[" "]" o Sign.string_of_typ thy) tys);
haftmann
parents:
diff changeset
   164
haftmann
parents:
diff changeset
   165
fun string_of_const_typ thy (c, ty) =
haftmann
parents:
diff changeset
   166
  string_of_const thy (c, Consts.typargs (Sign.consts_of thy) (c, ty));
haftmann
parents:
diff changeset
   167
haftmann
parents:
diff changeset
   168
end;