src/Pure/Tools/codegen_consts.ML
author haftmann
Wed, 04 Oct 2006 14:17:46 +0200
changeset 20855 9f60d493c8fe
parent 20704 a56f0743b3ee
child 21118 d9789a87825d
permissions -rw-r--r--
clarified header comments
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
20855
9f60d493c8fe clarified header comments
haftmann
parents: 20704
diff changeset
     5
Identifying constants by name plus normalized type instantantiation schemes.
9f60d493c8fe clarified header comments
haftmann
parents: 20704
diff changeset
     6
Type normalization is compatible with overloading discipline and user-defined
9f60d493c8fe clarified header comments
haftmann
parents: 20704
diff changeset
     7
ad-hoc overloading. Convenient data structures for constants.
20387
haftmann
parents:
diff changeset
     8
*)
haftmann
parents:
diff changeset
     9
haftmann
parents:
diff changeset
    10
signature CODEGEN_CONSTS =
haftmann
parents:
diff changeset
    11
sig
haftmann
parents:
diff changeset
    12
  type const = string * typ list (*type instantiations*)
haftmann
parents:
diff changeset
    13
  val const_ord: const * const -> order
haftmann
parents:
diff changeset
    14
  val eq_const: const * const -> bool
haftmann
parents:
diff changeset
    15
  structure Consttab: TABLE
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    16
  val inst_of_typ: theory -> string * typ -> const
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    17
  val typ_of_inst: theory -> const -> string * typ
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    18
  val norm: theory -> const -> const
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    19
  val norm_of_typ: theory -> string * typ -> const
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    20
  val find_def: theory -> const
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    21
    -> ((string (*theory name*) * thm) * typ list) option
20704
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
    22
  val disc_typ_of_classop: theory -> const -> typ
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
    23
  val disc_typ_of_const: theory -> (const -> typ) -> const -> typ
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
    24
  val consts_of: theory -> term -> const list * (string * typ) list
20387
haftmann
parents:
diff changeset
    25
  val read_const: theory -> string -> const
haftmann
parents:
diff changeset
    26
  val string_of_const: theory -> const -> string
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    27
  val raw_string_of_const: const -> string
20387
haftmann
parents:
diff changeset
    28
  val string_of_const_typ: theory -> string * typ -> string
haftmann
parents:
diff changeset
    29
end;
haftmann
parents:
diff changeset
    30
haftmann
parents:
diff changeset
    31
structure CodegenConsts: CODEGEN_CONSTS =
haftmann
parents:
diff changeset
    32
struct
haftmann
parents:
diff changeset
    33
haftmann
parents:
diff changeset
    34
haftmann
parents:
diff changeset
    35
(* basic data structures *)
haftmann
parents:
diff changeset
    36
haftmann
parents:
diff changeset
    37
type const = string * typ list (*type instantiations*);
haftmann
parents:
diff changeset
    38
val const_ord = prod_ord fast_string_ord (list_ord Term.typ_ord);
haftmann
parents:
diff changeset
    39
val eq_const = is_equal o const_ord;
haftmann
parents:
diff changeset
    40
haftmann
parents:
diff changeset
    41
structure Consttab =
haftmann
parents:
diff changeset
    42
  TableFun(
haftmann
parents:
diff changeset
    43
    type key = string * typ list;
haftmann
parents:
diff changeset
    44
    val ord = const_ord;
haftmann
parents:
diff changeset
    45
  );
haftmann
parents:
diff changeset
    46
haftmann
parents:
diff changeset
    47
haftmann
parents:
diff changeset
    48
(* type instantiations and overloading *)
haftmann
parents:
diff changeset
    49
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    50
fun inst_of_typ thy (c_ty as (c, ty)) =
20387
haftmann
parents:
diff changeset
    51
  (c, Consts.typargs (Sign.consts_of thy) c_ty);
haftmann
parents:
diff changeset
    52
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    53
fun typ_of_inst thy (c_tys as (c, tys)) =
20387
haftmann
parents:
diff changeset
    54
  (c, Consts.instance (Sign.consts_of thy) c_tys);
haftmann
parents:
diff changeset
    55
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    56
fun find_def thy (c, tys) =
20387
haftmann
parents:
diff changeset
    57
  let
haftmann
parents:
diff changeset
    58
    val specs = Defs.specifications_of (Theory.defs_of thy) c;
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    59
    val typ_instance = case AxClass.class_of_param thy c
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    60
     of SOME _ => let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    61
          fun instance_tycos (Type (tyco1, _), Type (tyco2, _)) = tyco1 = tyco2
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    62
            | instance_tycos (_ , TVar _) = true
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    63
            | instance_tycos ty_ty = Sign.typ_instance thy ty_ty;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    64
        in instance_tycos end
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    65
      | NONE =>  Sign.typ_instance thy;
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    66
    fun get_def (_, { is_def, thyname, name, lhs, rhs }) =
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    67
      if is_def andalso forall typ_instance (tys ~~ lhs) then
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    68
        case try (Thm.get_axiom_i thy) name
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    69
         of SOME thm => SOME ((thyname, thm), lhs)
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    70
          | NONE => NONE
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    71
      else NONE
20387
haftmann
parents:
diff changeset
    72
  in
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    73
    get_first get_def specs
20387
haftmann
parents:
diff changeset
    74
  end;
haftmann
parents:
diff changeset
    75
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    76
fun mk_classop_typinst thy (c, tyco) =
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    77
  (c, [Type (tyco, map (fn v => TVar ((v, 0), Sign.defaultS thy (*for monotonicity*)))
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    78
    (Name.invents Name.context "'a" (Sign.arity_number thy tyco)))]);
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    79
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    80
fun norm thy (c, insts) =
20387
haftmann
parents:
diff changeset
    81
  let
haftmann
parents:
diff changeset
    82
    fun disciplined _ [(Type (tyco, _))] =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    83
          mk_classop_typinst thy (c, tyco)
20387
haftmann
parents:
diff changeset
    84
      | disciplined sort _ =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    85
          (c, [TVar (("'a", 0), sort)]);
20387
haftmann
parents:
diff changeset
    86
    fun ad_hoc c tys =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
    87
      case find_def thy (c, tys)
20387
haftmann
parents:
diff changeset
    88
       of SOME (_, tys) => (c, tys)
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    89
        | NONE => inst_of_typ thy (c, Sign.the_const_type thy c);
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    90
  in case AxClass.class_of_param thy c
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    91
     of SOME class => disciplined [class] insts
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    92
      | _ => ad_hoc c insts
20387
haftmann
parents:
diff changeset
    93
  end;
haftmann
parents:
diff changeset
    94
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    95
fun norm_of_typ thy (c, ty) =
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    96
  norm thy (c, Consts.typargs (Sign.consts_of thy) (c, ty));
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
    97
20704
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
    98
fun disc_typ_of_classop thy (c, [TVar _]) = 
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
    99
      let
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   100
        val class = (the o AxClass.class_of_param thy) c;
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   101
        val (v, cs) = ClassPackage.the_consts_sign thy class
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   102
      in
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   103
        (Logic.varifyT o map_type_tfree (fn u as (w, _) => if w = v then TFree (v, [class]) else TFree u))
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   104
          ((the o AList.lookup (op =) cs) c)
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   105
      end
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   106
  | disc_typ_of_classop thy (c, [TFree _]) = 
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   107
      let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   108
        val class = (the o AxClass.class_of_param thy) c;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   109
        val (v, cs) = ClassPackage.the_consts_sign thy class
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   110
      in
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   111
        (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
   112
          ((the o AList.lookup (op =) cs) c)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   113
      end
20704
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   114
  | disc_typ_of_classop thy (c, [Type (tyco, _)]) =
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   115
      let
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   116
        val class = (the o AxClass.class_of_param thy) c;
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   117
        val (_, cs) = ClassPackage.the_inst_sign thy (class, tyco);
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   118
      in
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   119
        Logic.varifyT ((the o AList.lookup (op =) cs) c)
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   120
      end;
20387
haftmann
parents:
diff changeset
   121
20704
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   122
fun disc_typ_of_const thy f (const as (c, [ty])) =
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   123
      if (is_some o AxClass.class_of_param thy) c
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   124
      then disc_typ_of_classop thy const
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   125
      else f const
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   126
  | disc_typ_of_const thy f const = f const;
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   127
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   128
fun consts_of thy t =
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   129
  fold_aterms (fn Const c => cons (norm_of_typ thy c, c) | _ => I) t []
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   130
  |> split_list;
a56f0743b3ee cleaned up
haftmann
parents: 20600
diff changeset
   131
20387
haftmann
parents:
diff changeset
   132
haftmann
parents:
diff changeset
   133
(* reading constants as terms *)
haftmann
parents:
diff changeset
   134
haftmann
parents:
diff changeset
   135
fun read_const_typ thy raw_t =
haftmann
parents:
diff changeset
   136
  let
haftmann
parents:
diff changeset
   137
    val t = Sign.read_term thy raw_t
haftmann
parents:
diff changeset
   138
  in case try dest_Const t
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
   139
   of SOME c_ty => (typ_of_inst thy o norm_of_typ thy) c_ty
20389
8b6ecb22ef35 cleanup
haftmann
parents: 20387
diff changeset
   140
    | NONE => error ("Not a constant: " ^ Sign.string_of_term thy t)
20387
haftmann
parents:
diff changeset
   141
  end;
haftmann
parents:
diff changeset
   142
haftmann
parents:
diff changeset
   143
fun read_const thy =
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
   144
  norm_of_typ thy o read_const_typ thy;
20387
haftmann
parents:
diff changeset
   145
haftmann
parents:
diff changeset
   146
haftmann
parents:
diff changeset
   147
(* printing constants *)
haftmann
parents:
diff changeset
   148
haftmann
parents:
diff changeset
   149
fun string_of_const thy (c, tys) =
haftmann
parents:
diff changeset
   150
  space_implode " " (Sign.extern_const thy c
haftmann
parents:
diff changeset
   151
    :: map (enclose "[" "]" o Sign.string_of_typ thy) tys);
haftmann
parents:
diff changeset
   152
20600
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
   153
fun raw_string_of_const (c, tys) =
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
   154
  space_implode " " (c
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
   155
    :: map (enclose "[" "]" o Display.raw_string_of_typ) tys);
6d75e02ed285 added codegen_data
haftmann
parents: 20456
diff changeset
   156
20387
haftmann
parents:
diff changeset
   157
fun string_of_const_typ thy (c, ty) =
haftmann
parents:
diff changeset
   158
  string_of_const thy (c, Consts.typargs (Sign.consts_of thy) (c, ty));
haftmann
parents:
diff changeset
   159
haftmann
parents:
diff changeset
   160
end;