src/Tools/Code/code_symbol.ML
author wenzelm
Fri Mar 21 20:33:56 2014 +0100 (2014-03-21)
changeset 56245 84fc7dfa3cd4
parent 55304 55ac31bc08a4
child 56810 4ccfe99c160b
permissions -rw-r--r--
more qualified names;
wenzelm@52265
     1
(*  Title:      Tools/Code/code_symbol.ML
haftmann@52136
     2
    Author:     Florian Haftmann, TU Muenchen
haftmann@52136
     3
haftmann@52136
     4
Data related to symbols in programs: constants, type constructors, classes,
haftmann@52136
     5
class relations, class instances, modules.
haftmann@52136
     6
*)
haftmann@52136
     7
haftmann@55150
     8
signature BASIC_CODE_SYMBOL =
haftmann@52136
     9
sig
haftmann@52136
    10
  datatype ('a, 'b, 'c, 'd, 'e, 'f) attr =
haftmann@52136
    11
    Constant of 'a | Type_Constructor of 'b | Type_Class of 'c |
haftmann@52136
    12
    Class_Relation of 'd  | Class_Instance of 'e | Module of 'f
haftmann@55150
    13
end
haftmann@55150
    14
haftmann@55150
    15
signature CODE_SYMBOL =
haftmann@55150
    16
sig
haftmann@55150
    17
  include BASIC_CODE_SYMBOL
haftmann@55150
    18
  type T = (string, string, class, class * class, string * class, string) attr
haftmann@55150
    19
  structure Table: TABLE
haftmann@55150
    20
  structure Graph: GRAPH
haftmann@55150
    21
  val default_base: T -> string
haftmann@55150
    22
  val default_prefix: Proof.context -> T -> string
haftmann@55150
    23
  val quote: Proof.context -> T -> string
haftmann@55150
    24
  val marker: T -> string
haftmann@55150
    25
  val value: T
haftmann@55150
    26
  val is_value: T -> bool
haftmann@52136
    27
  val map_attr: ('a -> 'g) -> ('b -> 'h) -> ('c -> 'i) -> ('d -> 'j) -> ('e -> 'k) -> ('f -> 'l)
haftmann@52136
    28
    -> ('a, 'b, 'c, 'd, 'e, 'f) attr -> ('g, 'h, 'i, 'j, 'k, 'l) attr
haftmann@52136
    29
  val maps_attr: ('a -> 'g list) -> ('b -> 'h list)
haftmann@52136
    30
    -> ('c -> 'i list) -> ('d -> 'j list) -> ('e -> 'k list) -> ('f -> 'l list)
haftmann@52136
    31
    -> ('a, 'b, 'c, 'd, 'e, 'f) attr -> ('g, 'h, 'i, 'j, 'k, 'l) attr list
haftmann@52136
    32
  val maps_attr': ('a -> ('m * 'g) list) -> ('b -> ('m * 'h) list)
haftmann@52136
    33
    -> ('c -> ('m * 'i) list) -> ('d -> ('m * 'j) list) -> ('e -> ('m * 'k) list) -> ('f -> ('m * 'l) list)
haftmann@52136
    34
    -> ('a, 'b, 'c, 'd, 'e, 'f) attr -> ('m * ('g, 'h, 'i, 'j, 'k, 'l) attr) list
haftmann@52136
    35
  type ('a, 'b, 'c, 'd, 'e, 'f) data
haftmann@52136
    36
  val empty_data: ('a, 'b, 'c, 'd, 'e, 'f) data
haftmann@52136
    37
  val merge_data: ('a, 'b, 'c, 'd, 'e, 'f) data * ('a, 'b, 'c, 'd, 'e, 'f) data
haftmann@52136
    38
    -> ('a, 'b, 'c, 'd, 'e, 'f) data
haftmann@52138
    39
  val set_data: (string * 'a option, string * 'b option, string * 'c option,
haftmann@52138
    40
      (class * class) * 'd option, (string * class) * 'e option, string * 'f option) attr
haftmann@52138
    41
    -> ('a, 'b, 'c, 'd, 'e, 'f) data -> ('a, 'b, 'c, 'd, 'e, 'f) data
haftmann@52136
    42
  val lookup_constant_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> string -> 'a option
haftmann@52136
    43
  val lookup_type_constructor_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> string -> 'b option
haftmann@52136
    44
  val lookup_type_class_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> class -> 'c option
haftmann@52136
    45
  val lookup_class_relation_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> class * class -> 'd option
haftmann@52136
    46
  val lookup_class_instance_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> string * class -> 'e option
haftmann@52136
    47
  val lookup_module_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> string -> 'f option
haftmann@55150
    48
  val lookup: ('a, 'a, 'a, 'a, 'a, 'a) data -> T -> 'a option
haftmann@55150
    49
  val symbols_of: ('a, 'b, 'c, 'd, 'e, 'f) data -> T list
haftmann@52136
    50
  val dest_module_data: ('a, 'b, 'c, 'd, 'e, 'f) data -> (string * 'f) list
haftmann@52136
    51
end;
haftmann@52136
    52
haftmann@52136
    53
structure Code_Symbol : CODE_SYMBOL =
haftmann@52136
    54
struct
haftmann@52136
    55
haftmann@52136
    56
(* data for symbols *)
haftmann@52136
    57
haftmann@52136
    58
datatype ('a, 'b, 'c, 'd, 'e, 'f) attr =
haftmann@52136
    59
  Constant of 'a | Type_Constructor of 'b | Type_Class of 'c | Class_Relation of 'd  | Class_Instance of 'e | Module of 'f;
haftmann@52136
    60
haftmann@55150
    61
type T = (string, string, class, string * class, class * class, string) attr;
haftmann@52138
    62
haftmann@54933
    63
fun symbol_ord (Constant c1, Constant c2) = fast_string_ord (c1, c2)
haftmann@54933
    64
  | symbol_ord (Constant _, _) = GREATER
haftmann@54933
    65
  | symbol_ord (_, Constant _) = LESS
haftmann@54933
    66
  | symbol_ord (Type_Constructor tyco1, Type_Constructor tyco2) = fast_string_ord (tyco1, tyco2)
haftmann@54933
    67
  | symbol_ord (Type_Constructor _, _) = GREATER
haftmann@54933
    68
  | symbol_ord (_, Type_Constructor _) = LESS
haftmann@54933
    69
  | symbol_ord (Type_Class class1, Type_Class class2) = fast_string_ord (class1, class2)
haftmann@54933
    70
  | symbol_ord (Type_Class _, _) = GREATER
haftmann@54933
    71
  | symbol_ord (_, Type_Class _) = LESS
haftmann@54933
    72
  | symbol_ord (Class_Relation classrel1, Class_Relation classrel2) =
haftmann@54933
    73
      prod_ord fast_string_ord fast_string_ord (classrel1, classrel2)
haftmann@54933
    74
  | symbol_ord (Class_Relation _, _) = GREATER
haftmann@54933
    75
  | symbol_ord (_, Class_Relation _) = LESS
haftmann@54933
    76
  | symbol_ord (Class_Instance inst1, Class_Instance inst2) =
haftmann@54933
    77
      prod_ord fast_string_ord fast_string_ord (inst1, inst2)
haftmann@54933
    78
  | symbol_ord (Class_Instance _, _) = GREATER
haftmann@54933
    79
  | symbol_ord (_, Class_Instance _) = LESS
haftmann@54933
    80
  | symbol_ord (Module name1, Module name2) = fast_string_ord (name1, name2);
haftmann@54933
    81
haftmann@55150
    82
structure Table = Table(type key = T val ord = symbol_ord);
haftmann@55150
    83
structure Graph = Graph(type key = T val ord = symbol_ord);
haftmann@55150
    84
haftmann@55150
    85
local
haftmann@55150
    86
  val base = Name.desymbolize false o Long_Name.base_name;
haftmann@55150
    87
  fun base_rel (x, y) = base y ^ "_" ^ base x;
haftmann@55150
    88
in
haftmann@55150
    89
haftmann@55150
    90
fun default_base (Constant "") = "value"
wenzelm@56245
    91
  | default_base (Constant @{const_name Pure.imp}) = "follows"
wenzelm@56245
    92
  | default_base (Constant @{const_name Pure.eq}) = "meta_eq"
haftmann@55150
    93
  | default_base (Constant c) = base c
haftmann@55150
    94
  | default_base (Type_Constructor tyco) = base tyco
haftmann@55150
    95
  | default_base (Type_Class class) = base class
haftmann@55150
    96
  | default_base (Class_Relation classrel) = base_rel classrel
haftmann@55150
    97
  | default_base (Class_Instance inst) = base_rel inst;
haftmann@55150
    98
haftmann@55150
    99
end;
haftmann@54933
   100
haftmann@54933
   101
local
haftmann@54933
   102
  fun thyname_of_type thy = #theory_name o Name_Space.the_entry (Sign.type_space thy);
haftmann@54933
   103
  fun thyname_of_class thy = #theory_name o Name_Space.the_entry (Sign.class_space thy);
haftmann@54933
   104
  fun thyname_of_instance thy inst = case Axclass.thynames_of_arity thy inst
haftmann@54933
   105
   of [] => error ("No such instance: " ^ quote (fst inst ^ " :: " ^  snd inst))
haftmann@54933
   106
    | thyname :: _ => thyname;
haftmann@54933
   107
  fun thyname_of_const thy c = case Axclass.class_of_param thy c
haftmann@54933
   108
   of SOME class => thyname_of_class thy class
haftmann@54933
   109
    | NONE => (case Code.get_type_of_constr_or_abstr thy c
haftmann@54933
   110
       of SOME (tyco, _) => thyname_of_type thy tyco
haftmann@54933
   111
        | NONE => #theory_name (Name_Space.the_entry (Sign.const_space thy) c));
haftmann@55147
   112
  fun prefix thy (Constant "") = "Code"
haftmann@55147
   113
    | prefix thy (Constant c) = thyname_of_const thy c
haftmann@55147
   114
    | prefix thy (Type_Constructor tyco) = thyname_of_type thy tyco
haftmann@55147
   115
    | prefix thy (Type_Class class) = thyname_of_class thy class
haftmann@55147
   116
    | prefix thy (Class_Relation (class, _)) = thyname_of_class thy class
haftmann@55147
   117
    | prefix thy (Class_Instance inst) = thyname_of_instance thy inst;
haftmann@54933
   118
in
haftmann@54933
   119
haftmann@55150
   120
fun default_prefix ctxt = prefix (Proof_Context.theory_of ctxt);
haftmann@54933
   121
haftmann@55150
   122
end;
haftmann@55147
   123
haftmann@55147
   124
val value = Constant "";
haftmann@55147
   125
fun is_value (Constant "") = true
haftmann@55147
   126
  | is_value _ = false;
haftmann@54933
   127
wenzelm@55304
   128
fun quote ctxt (Constant c) =
wenzelm@55304
   129
      Library.quote (Code.string_of_const (Proof_Context.theory_of ctxt) c)
wenzelm@55304
   130
  | quote ctxt (Type_Constructor tyco) =
wenzelm@55304
   131
      "type " ^ Library.quote (Proof_Context.markup_type ctxt tyco)
wenzelm@55304
   132
  | quote ctxt (Type_Class class) =
wenzelm@55304
   133
      "class " ^ Library.quote (Proof_Context.markup_class ctxt class)
haftmann@55147
   134
  | quote ctxt (Class_Relation (sub, super)) =
wenzelm@55304
   135
      Library.quote (Proof_Context.markup_class ctxt sub) ^ " < " ^
wenzelm@55304
   136
      Library.quote (Proof_Context.markup_class ctxt super)
haftmann@55147
   137
  | quote ctxt (Class_Instance (tyco, class)) =
wenzelm@55304
   138
      Library.quote (Proof_Context.markup_type ctxt tyco) ^ " :: " ^
wenzelm@55304
   139
      Library.quote (Proof_Context.markup_class ctxt class);
haftmann@55147
   140
haftmann@55147
   141
fun marker (Constant c) = "CONST " ^ c
haftmann@55147
   142
  | marker (Type_Constructor tyco) = "TYPE " ^ tyco
haftmann@55147
   143
  | marker (Type_Class class) = "CLASS " ^ class
haftmann@55147
   144
  | marker (Class_Relation (sub, super)) = "CLASSREL " ^ sub ^ " < " ^ super
haftmann@55147
   145
  | marker (Class_Instance (tyco, class)) = "INSTANCE " ^ tyco ^ " :: " ^ class;
haftmann@54933
   146
haftmann@52136
   147
fun map_attr const tyco class classrel inst module (Constant x) = Constant (const x)
haftmann@52136
   148
  | map_attr const tyco class classrel inst module (Type_Constructor x) = Type_Constructor (tyco x)
haftmann@52136
   149
  | map_attr const tyco class classrel inst module (Type_Class x) = Type_Class (class x)
haftmann@52136
   150
  | map_attr const tyco class classrel inst module (Class_Relation x) = Class_Relation (classrel x)
haftmann@52136
   151
  | map_attr const tyco class classrel inst module (Class_Instance x) = Class_Instance (inst x)
haftmann@52136
   152
  | map_attr const tyco class classrel inst module (Module x) = Module (module x);
haftmann@52136
   153
haftmann@52136
   154
fun maps_attr const tyco class classrel inst module (Constant x) = map Constant (const x)
haftmann@52136
   155
  | maps_attr const tyco class classrel inst module (Type_Constructor x) = map Type_Constructor (tyco x)
haftmann@52136
   156
  | maps_attr const tyco class classrel inst module (Type_Class x) = map Type_Class (class x)
haftmann@52136
   157
  | maps_attr const tyco class classrel inst module (Class_Relation x) = map Class_Relation (classrel x)
haftmann@52136
   158
  | maps_attr const tyco class classrel inst module (Class_Instance x) = map Class_Instance (inst x)
haftmann@52136
   159
  | maps_attr const tyco class classrel inst module (Module x) = map Module (module x);
haftmann@52136
   160
haftmann@52136
   161
fun maps_attr' const tyco class classrel inst module (Constant x) = (map o apsnd) Constant (const x)
haftmann@52136
   162
  | maps_attr' const tyco class classrel inst module (Type_Constructor x) = (map o apsnd) Type_Constructor (tyco x)
haftmann@52136
   163
  | maps_attr' const tyco class classrel inst module (Type_Class x) = (map o apsnd) Type_Class (class x)
haftmann@52136
   164
  | maps_attr' const tyco class classrel inst module (Class_Relation x) = (map o apsnd) Class_Relation (classrel x)
haftmann@52136
   165
  | maps_attr' const tyco class classrel inst module (Class_Instance x) = (map o apsnd) Class_Instance (inst x)
haftmann@52136
   166
  | maps_attr' const tyco class classrel inst module (Module x) = (map o apsnd) Module (module x);
haftmann@52136
   167
haftmann@52136
   168
datatype ('a, 'b, 'c, 'd, 'e, 'f) data =
haftmann@52136
   169
  Data of { constant: 'a Symtab.table, type_constructor: 'b Symtab.table,
haftmann@52136
   170
    type_class: 'c Symtab.table, class_relation: 'd Symreltab.table, class_instance: 'e Symreltab.table,
haftmann@52136
   171
    module: 'f Symtab.table };
haftmann@52136
   172
haftmann@52136
   173
fun make_data constant type_constructor type_class class_relation class_instance module =
haftmann@52136
   174
  Data { constant = constant, type_constructor = type_constructor,
haftmann@52136
   175
    type_class = type_class, class_relation = class_relation, class_instance = class_instance, module = module };
haftmann@52136
   176
fun dest_data (Data x) = x;
haftmann@52136
   177
fun map_data map_constant map_type_constructor map_type_class map_class_relation map_class_instance map_module
haftmann@52136
   178
  (Data { constant, type_constructor, type_class, class_relation, class_instance, module }) =
haftmann@52136
   179
    Data { constant = map_constant constant, type_constructor = map_type_constructor type_constructor,
haftmann@52136
   180
      type_class = map_type_class type_class, class_relation = map_class_relation class_relation,
haftmann@52136
   181
        class_instance = map_class_instance class_instance, module = map_module module };
haftmann@52136
   182
haftmann@52136
   183
val empty_data = Data { constant = Symtab.empty, type_constructor = Symtab.empty,
haftmann@52136
   184
  type_class = Symtab.empty, class_relation = Symreltab.empty, class_instance = Symreltab.empty, module = Symtab.empty };
haftmann@52136
   185
fun merge_data (Data { constant = constant1, type_constructor = type_constructor1,
haftmann@52136
   186
    type_class = type_class1, class_instance = class_instance1, class_relation = class_relation1, module = module1 },
haftmann@52136
   187
  Data { constant = constant2, type_constructor = type_constructor2,
haftmann@52136
   188
    type_class = type_class2, class_instance = class_instance2, class_relation = class_relation2, module = module2 }) =
haftmann@52136
   189
  make_data (Symtab.join (K snd) (constant1, constant2))
haftmann@52136
   190
    (Symtab.join (K snd) (type_constructor1, type_constructor2))
haftmann@52136
   191
    (Symtab.join (K snd) (type_class1, type_class2))
haftmann@52136
   192
    (Symreltab.join (K snd) (class_relation1, class_relation2))
haftmann@52136
   193
    (Symreltab.join (K snd) (class_instance1, class_instance2))
haftmann@52136
   194
    (Symtab.join (K snd) (module1, module2)); (*prefer later entries: K snd*)
haftmann@52136
   195
haftmann@52136
   196
fun set_sym (sym, NONE) = Symtab.delete_safe sym
haftmann@52136
   197
  | set_sym (sym, SOME y) = Symtab.update (sym, y);
haftmann@52136
   198
fun set_symrel (symrel, NONE) = Symreltab.delete_safe symrel
haftmann@52136
   199
  | set_symrel (symrel, SOME y) = Symreltab.update (symrel, y);
haftmann@52136
   200
haftmann@52136
   201
fun set_data (Constant x) = map_data (set_sym x) I I I I I
haftmann@52136
   202
  | set_data (Type_Constructor x) = map_data I (set_sym x) I I I I
haftmann@52136
   203
  | set_data (Type_Class x) = map_data I I (set_sym x) I I I
haftmann@52136
   204
  | set_data (Class_Relation x) = map_data I I I (set_symrel x) I I
haftmann@52136
   205
  | set_data (Class_Instance x) = map_data I I I I (set_symrel x) I
haftmann@52136
   206
  | set_data (Module x) = map_data I I I I I (set_sym x);
haftmann@52136
   207
haftmann@52138
   208
fun lookup_constant_data x = (Symtab.lookup o #constant o dest_data) x;
haftmann@52138
   209
fun lookup_type_constructor_data x = (Symtab.lookup o #type_constructor o dest_data) x;
haftmann@52138
   210
fun lookup_type_class_data x = (Symtab.lookup o #type_class o dest_data) x;
haftmann@52138
   211
fun lookup_class_relation_data x = (Symreltab.lookup o #class_relation o dest_data) x;
haftmann@52138
   212
fun lookup_class_instance_data x = (Symreltab.lookup o #class_instance o dest_data) x;
haftmann@52138
   213
fun lookup_module_data x = (Symtab.lookup o #module o dest_data) x;
haftmann@52138
   214
haftmann@52138
   215
fun lookup data (Constant x) = lookup_constant_data data x
haftmann@52138
   216
  | lookup data (Type_Constructor x) = lookup_type_constructor_data data x
haftmann@52138
   217
  | lookup data (Type_Class x) = lookup_type_class_data data x
haftmann@52138
   218
  | lookup data (Class_Relation x) = lookup_class_relation_data data x
haftmann@52138
   219
  | lookup data (Class_Instance x) = lookup_class_instance_data data x
haftmann@52138
   220
  | lookup data (Module x) = lookup_module_data data x;
haftmann@52138
   221
haftmann@55147
   222
fun symbols_of x = (map Constant o Symtab.keys o #constant o dest_data) x
haftmann@55147
   223
  @ (map Type_Constructor o Symtab.keys o #type_constructor o dest_data) x
haftmann@55147
   224
  @ (map Type_Class o Symtab.keys o #type_class o dest_data) x
haftmann@55147
   225
  @ (map Class_Relation o Symreltab.keys o #class_relation o dest_data) x
haftmann@55147
   226
  @ (map Class_Instance o Symreltab.keys o #class_instance o dest_data) x
haftmann@55147
   227
  @ (map Module o Symtab.keys o #module o dest_data) x;
haftmann@55147
   228
haftmann@52138
   229
fun dest_module_data x = (Symtab.dest o #module o dest_data) x;
haftmann@52138
   230
haftmann@52136
   231
end;
haftmann@55150
   232
haftmann@55150
   233
haftmann@55150
   234
structure Basic_Code_Symbol: BASIC_CODE_SYMBOL = Code_Symbol;