src/Pure/General/name_mangler.ML
author haftmann
Wed, 21 Dec 2005 17:00:57 +0100
changeset 18455 b293c1087f1d
parent 18453 2b2fbc32550e
child 18494 00190b1fa5b3
permissions -rw-r--r--
slight improvements
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     1
(*  Title:      Pure/General/name_mangler.ML
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     2
    ID:         $Id$
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     3
    Author:     Florian Haftmann, TU Muenchen
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     4
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     5
Generic name mangler -- provides bijective mappings from any expressions
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     6
to strings and vice versa.
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     7
*)
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     8
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
     9
signature NAME_MANGLER =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    10
sig
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    11
  type ctxt
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    12
  type src
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    13
  type T
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    14
  val mk_unique: ('b * 'b -> bool) -> ('a * int -> 'b)
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    15
    -> 'a -> 'b list -> 'b * 'b list
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    16
  val mk_unique_multi: ('b * 'b -> bool) -> ('a * int -> 'b)
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    17
    -> 'a list -> 'b list -> 'b list * 'b list
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    18
  val empty: T
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    19
  val get: ctxt -> T -> src -> string
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    20
  val rev: ctxt -> T -> string -> src
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    21
  val declare: ctxt -> src -> T -> string * T
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    22
  val declare_multi: ctxt -> src list -> T -> string list * T
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    23
  val merge: T * T -> T
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    24
  val dest: T -> (src * string) list
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    25
end;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    26
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    27
functor NameManglerFun (
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    28
  type ctxt
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    29
  type src
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    30
  val ord: src * src -> order
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    31
  val mk: ctxt -> src * int -> string
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    32
  val is_valid: ctxt -> string -> bool
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    33
  val maybe_unique: ctxt -> src -> string option
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    34
  val re_mangle: ctxt -> string -> src
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    35
) : NAME_MANGLER =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    36
struct
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    37
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    38
structure Srctab = TableFun (
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    39
  type key = src
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    40
  val ord = ord
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    41
);
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    42
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    43
type ctxt = ctxt;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    44
type src = src;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    45
type T = string Srctab.table * src Symtab.table;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    46
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    47
fun mk_unique eq mk seed used =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    48
  let
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    49
    fun mk_name i =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    50
      let
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    51
        val name = mk (seed, i)
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    52
      in
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    53
        if member eq used name
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    54
        then mk_name (i+1)
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    55
        else name
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    56
      end;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    57
    val name = mk_name 0;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    58
  in (name, name :: used) end;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    59
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    60
fun mk_unique_multi eq mk seeds used =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    61
  let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    62
    fun mk_names i =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    63
      let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    64
        val names = map (fn seed => mk (seed, i)) seeds
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    65
      in
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    66
        if null (gen_inter eq (used, names))
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    67
        then names
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    68
        else mk_names (i+1)
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    69
      end;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    70
    val names = mk_names 0;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    71
  in (names, fold cons names used) end;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    72
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    73
val empty = (Srctab.empty, Symtab.empty);
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    74
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    75
fun get ctxt (tab_f, _) x =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    76
  case Srctab.lookup tab_f x
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    77
   of SOME s => s
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    78
    | NONE => (the o maybe_unique ctxt) x;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    79
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    80
fun rev ctxt (_, tab_r) s =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    81
  case Symtab.lookup tab_r s
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    82
   of SOME x => x
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    83
    | NONE => re_mangle ctxt s;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    84
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    85
fun declare ctxt x (tabs as (tab_f, tab_r)) =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    86
  case maybe_unique ctxt x
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    87
   of NONE => 
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    88
        let
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    89
          fun mk_it (seed, i) =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    90
            let
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    91
              val name = mk ctxt (seed, i)
18455
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    92
            in
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    93
              if is_valid ctxt name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    94
                andalso (not oo Symtab.defined) tab_r name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    95
              then name 
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    96
              else mk_it (seed, i+1)
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    97
            end;
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    98
          val name = (fst oooo mk_unique) (op =) mk_it x [];
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    99
        in
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   100
          (name,
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   101
           (tab_f |> Srctab.update (x, name),
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   102
            tab_r |> Symtab.update (name, x)))
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   103
        end
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   104
    | SOME s => (s, tabs)
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   105
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   106
fun declare_multi ctxt xs (tabs as (tab_f, tab_r)) =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   107
  let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   108
    val xs' = map (maybe_unique ctxt) xs
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   109
  in
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   110
    if forall is_some xs'
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   111
    then (map the xs', tabs)
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   112
    else
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   113
      let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   114
        fun mk_it (seed, i) =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   115
          let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   116
            val name = mk ctxt (seed, i)
18455
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   117
          in
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   118
            if is_valid ctxt name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   119
              andalso (not oo Symtab.defined) tab_r name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   120
            then name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   121
            else mk_it (seed, i+1)
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   122
          end;
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   123
        val names = (fst oooo mk_unique_multi) (op =) mk_it xs [];
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   124
      in
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   125
        (names,
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   126
         (tab_f |> fold2 (curry Srctab.update) xs names,
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   127
          tab_r |> fold2 (curry Symtab.update) names xs))
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   128
      end
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   129
  end;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   130
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   131
fun merge ((tab_f_1, tab_r_1), (tab_f_2, tab_r_2)) =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   132
  (Srctab.merge (op = : string * string -> bool) (tab_f_1, tab_f_2),
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   133
   Symtab.merge (eq_ord ord) (tab_r_1, tab_r_2));
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   134
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   135
fun dest (tab_f, _) = Srctab.dest tab_f;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   136
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   137
end;