author | haftmann |
Fri, 14 Nov 2008 08:50:10 +0100 | |
changeset 28792 | 1d80cee865de |
parent 28737 | 8cbb7cfcfb5b |
child 28821 | 78a6ed46ad04 |
permissions | -rw-r--r-- |
20089 | 1 |
(* Title: Pure/name.ML |
2 |
ID: $Id$ |
|
3 |
Author: Makarius |
|
4 |
||
28075 | 5 |
Names of basic logical entities (variables etc.). Generic name bindings. |
20089 | 6 |
*) |
7 |
||
8 |
signature NAME = |
|
9 |
sig |
|
24849 | 10 |
val uu: string |
11 |
val aT: string |
|
20089 | 12 |
val bound: int -> string |
13 |
val is_bound: string -> bool |
|
14 |
val internal: string -> string |
|
15 |
val dest_internal: string -> string |
|
16 |
val skolem: string -> string |
|
17 |
val dest_skolem: string -> string |
|
18 |
val clean_index: string * int -> string * int |
|
19 |
val clean: string -> string |
|
20 |
type context |
|
21 |
val context: context |
|
20158 | 22 |
val make_context: string list -> context |
20089 | 23 |
val declare: string -> context -> context |
20158 | 24 |
val is_declared: context -> string -> bool |
20089 | 25 |
val invents: context -> string -> int -> string list |
20192
956cd30ef3be
renamed Name.give_names to Name.names and moved Name.alphanum to Symbol.alphanum
haftmann
parents:
20174
diff
changeset
|
26 |
val names: context -> string -> 'a list -> (string * 'a) list |
20089 | 27 |
val invent_list: string list -> string -> int -> string list |
28 |
val variants: string list -> context -> string list * context |
|
29 |
val variant_list: string list -> string list -> string list |
|
30 |
val variant: string list -> string -> string |
|
28075 | 31 |
type binding |
32 |
val binding_pos: string * Position.T -> binding |
|
33 |
val binding: string -> binding |
|
34 |
val no_binding: binding |
|
28725 | 35 |
val prefix_of: binding -> (string * bool) list |
28075 | 36 |
val name_of: binding -> string |
28792 | 37 |
val is_nothing: binding -> bool |
28075 | 38 |
val pos_of: binding -> Position.T |
28725 | 39 |
val add_prefix: bool -> string -> binding -> binding |
28075 | 40 |
val map_name: (string -> string) -> binding -> binding |
28108 | 41 |
val qualified: string -> binding -> binding |
28792 | 42 |
val namify: NameSpace.naming -> binding -> NameSpace.naming * string |
28737 | 43 |
val output: binding -> string |
20089 | 44 |
end; |
45 |
||
46 |
structure Name: NAME = |
|
47 |
struct |
|
48 |
||
24849 | 49 |
(** common defaults **) |
50 |
||
51 |
val uu = "uu"; |
|
52 |
val aT = "'a"; |
|
53 |
||
54 |
||
20089 | 55 |
|
56 |
(** special variable names **) |
|
57 |
||
58 |
(* encoded bounds *) |
|
59 |
||
60 |
(*names for numbered variables -- |
|
61 |
preserves order wrt. int_ord vs. string_ord, avoids allocating new strings*) |
|
62 |
||
63 |
val small_int = Vector.tabulate (1000, fn i => |
|
64 |
let val leading = if i < 10 then "00" else if i < 100 then "0" else "" |
|
65 |
in ":" ^ leading ^ string_of_int i end); |
|
66 |
||
67 |
fun bound n = |
|
68 |
if n < 1000 then Vector.sub (small_int, n) |
|
69 |
else ":" ^ bound (n div 1000) ^ Vector.sub (small_int, n mod 1000); |
|
70 |
||
71 |
val is_bound = String.isPrefix ":"; |
|
72 |
||
73 |
||
74 |
(* internal names *) |
|
75 |
||
76 |
val internal = suffix "_"; |
|
77 |
val dest_internal = unsuffix "_"; |
|
78 |
||
79 |
val skolem = suffix "__"; |
|
80 |
val dest_skolem = unsuffix "__"; |
|
81 |
||
20099 | 82 |
fun clean_index (x, i) = |
83 |
(case try dest_internal x of |
|
84 |
NONE => (x, i) |
|
85 |
| SOME x' => clean_index (x', i + 1)); |
|
20089 | 86 |
|
87 |
fun clean x = #1 (clean_index (x, 0)); |
|
88 |
||
89 |
||
90 |
||
91 |
(** generating fresh names **) |
|
92 |
||
93 |
(* context *) |
|
94 |
||
95 |
datatype context = |
|
96 |
Context of string option Symtab.table; (*declared names with latest renaming*) |
|
97 |
||
20099 | 98 |
fun declare x (Context tab) = |
99 |
Context (Symtab.default (clean x, NONE) tab); |
|
100 |
||
101 |
fun declare_renaming (x, x') (Context tab) = |
|
102 |
Context (Symtab.update (clean x, SOME (clean x')) tab); |
|
20089 | 103 |
|
20158 | 104 |
fun is_declared (Context tab) = Symtab.defined tab; |
20089 | 105 |
fun declared (Context tab) = Symtab.lookup tab; |
106 |
||
20121 | 107 |
val context = Context Symtab.empty |> fold declare ["", "'"]; |
20089 | 108 |
fun make_context used = fold declare used context; |
109 |
||
110 |
||
111 |
(* invents *) |
|
112 |
||
113 |
fun invents ctxt = |
|
114 |
let |
|
115 |
fun invs _ 0 = [] |
|
116 |
| invs x n = |
|
117 |
let val x' = Symbol.bump_string x in |
|
20158 | 118 |
if is_declared ctxt x then invs x' n |
20089 | 119 |
else x :: invs x' (n - 1) |
120 |
end; |
|
20099 | 121 |
in invs o clean end; |
20089 | 122 |
|
20198 | 123 |
fun names ctxt x xs = invents ctxt x (length xs) ~~ xs; |
124 |
||
20089 | 125 |
val invent_list = invents o make_context; |
126 |
||
127 |
||
128 |
(* variants *) |
|
129 |
||
130 |
(*makes a variant of a name distinct from already used names in a |
|
131 |
context; preserves a suffix of underscores "_"*) |
|
132 |
val variants = fold_map (fn name => fn ctxt => |
|
133 |
let |
|
134 |
fun vary x = |
|
135 |
(case declared ctxt x of |
|
136 |
NONE => x |
|
137 |
| SOME x' => vary (Symbol.bump_string (the_default x x'))); |
|
138 |
||
20121 | 139 |
val (x, n) = clean_index (name, 0); |
20089 | 140 |
val (x', ctxt') = |
20158 | 141 |
if not (is_declared ctxt x) then (x, declare x ctxt) |
20089 | 142 |
else |
143 |
let |
|
144 |
val x0 = Symbol.bump_init x; |
|
145 |
val x' = vary x0; |
|
146 |
val ctxt' = ctxt |
|
21565 | 147 |
|> x0 <> x' ? declare_renaming (x0, x') |
20089 | 148 |
|> declare x'; |
149 |
in (x', ctxt') end; |
|
150 |
in (x' ^ replicate_string n "_", ctxt') end); |
|
151 |
||
152 |
fun variant_list used names = #1 (make_context used |> variants names); |
|
153 |
fun variant used = singleton (variant_list used); |
|
154 |
||
28075 | 155 |
|
156 |
||
157 |
(** generic name bindings **) |
|
158 |
||
28725 | 159 |
datatype binding = Binding of ((string * bool) list * string) * Position.T; |
28075 | 160 |
|
28725 | 161 |
fun prefix_of (Binding ((prefix, _), _)) = prefix; |
162 |
fun name_of (Binding ((_, name), _)) = name; |
|
163 |
fun pos_of (Binding (_, pos)) = pos; |
|
164 |
||
165 |
fun binding_pos (name, pos) = Binding (([], name), pos); |
|
28075 | 166 |
fun binding name = binding_pos (name, Position.none); |
167 |
val no_binding = binding ""; |
|
168 |
||
28725 | 169 |
fun map_binding f (Binding bnd) = Binding (f bnd); |
28075 | 170 |
|
28725 | 171 |
fun add_prefix sticky prfx = (map_binding o apfst o apfst) |
172 |
(cons (prfx, sticky)); |
|
173 |
||
174 |
val map_name = map_binding o apfst o apsnd; |
|
28108 | 175 |
val qualified = map_name o NameSpace.qualified; |
28075 | 176 |
|
28792 | 177 |
fun is_nothing (Binding ((_, name), _)) = name = ""; |
178 |
||
179 |
fun namify naming (Binding ((prefix, name), _)) = |
|
180 |
let |
|
181 |
fun mk_prefix (prfx, true) = NameSpace.sticky_prefix prfx |
|
182 |
| mk_prefix (prfx, false) = NameSpace.add_path prfx; |
|
183 |
val naming' = fold mk_prefix prefix naming; |
|
184 |
in (naming', NameSpace.full naming' name) end; |
|
185 |
||
28737 | 186 |
fun output (Binding ((prefix, name), _)) = |
187 |
if null prefix orelse name = "" then name |
|
188 |
else NameSpace.implode (map fst prefix) ^ " / " ^ name; |
|
189 |
||
20089 | 190 |
end; |