src/Pure/General/name_mangler.ML
author haftmann
Tue, 09 May 2006 10:07:38 +0200
changeset 19596 7b07dac44e09
parent 18494 00190b1fa5b3
permissions -rw-r--r--
removed superfluous eq_ord
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 =
18494
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    63
      if i < 2 then
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    64
        let
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    65
          val names = map (fn seed => mk (seed, i)) seeds
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    66
        in
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    67
          if null (gen_inter eq (used, names))
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    68
            andalso (not oo has_duplicates) eq names
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    69
          then names
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    70
          else mk_names (i+1)
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    71
        end
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    72
      else
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    73
        used
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    74
        |> fold_map (mk_unique eq mk) seeds
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    75
        |> fst;
00190b1fa5b3 slight improvements
haftmann
parents: 18455
diff changeset
    76
      val names = mk_names 0;
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    77
  in (names, fold cons names used) end;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    78
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    79
val empty = (Srctab.empty, Symtab.empty);
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
    80
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    81
fun get ctxt (tab_f, _) x =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    82
  case Srctab.lookup tab_f x
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    83
   of SOME s => s
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    84
    | NONE => (the o maybe_unique ctxt) x;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    85
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    86
fun rev ctxt (_, tab_r) s =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    87
  case Symtab.lookup tab_r s
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    88
   of SOME x => x
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    89
    | NONE => re_mangle ctxt s;
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    90
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    91
fun declare ctxt x (tabs as (tab_f, tab_r)) =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    92
  case maybe_unique ctxt x
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    93
   of NONE => 
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    94
        let
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    95
          fun mk_it (seed, i) =
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    96
            let
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
    97
              val name = mk ctxt (seed, i)
18455
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    98
            in
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
    99
              if is_valid ctxt name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   100
                andalso (not oo Symtab.defined) tab_r name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   101
              then name 
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   102
              else mk_it (seed, i+1)
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   103
            end;
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   104
          val name = (fst oooo mk_unique) (op =) mk_it x [];
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   105
        in
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   106
          (name,
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   107
           (tab_f |> Srctab.update (x, name),
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   108
            tab_r |> Symtab.update (name, x)))
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   109
        end
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   110
    | SOME s => (s, tabs)
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   111
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   112
fun declare_multi ctxt xs (tabs as (tab_f, tab_r)) =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   113
  let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   114
    val xs' = map (maybe_unique ctxt) xs
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   115
  in
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   116
    if forall is_some xs'
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   117
    then (map the xs', tabs)
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   118
    else
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   119
      let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   120
        fun mk_it (seed, i) =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   121
          let
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   122
            val name = mk ctxt (seed, i)
18455
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   123
          in
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   124
            if is_valid ctxt name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   125
              andalso (not oo Symtab.defined) tab_r name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   126
            then name
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   127
            else mk_it (seed, i+1)
b293c1087f1d slight improvements
haftmann
parents: 18453
diff changeset
   128
          end;
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   129
        val names = (fst oooo mk_unique_multi) (op =) mk_it xs [];
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   130
      in
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   131
        (names,
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   132
         (tab_f |> fold2 (curry Srctab.update) xs names,
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   133
          tab_r |> fold2 (curry Symtab.update) names xs))
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   134
      end
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   135
  end;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   136
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   137
fun merge ((tab_f_1, tab_r_1), (tab_f_2, tab_r_2)) =
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   138
  (Srctab.merge (op = : string * string -> bool) (tab_f_1, tab_f_2),
19596
7b07dac44e09 removed superfluous eq_ord
haftmann
parents: 18494
diff changeset
   139
   Symtab.merge (is_equal o ord) (tab_r_1, tab_r_2));
18453
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   140
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   141
fun dest (tab_f, _) = Srctab.dest tab_f;
2b2fbc32550e slight refinements
haftmann
parents: 18387
diff changeset
   142
18387
90b2b2fd3fdf added generic name mangler
haftmann
parents:
diff changeset
   143
end;