author | wenzelm |
Sat, 30 Nov 2024 21:01:59 +0100 | |
changeset 81517 | 1b33a7a3c80c |
parent 81513 | d11ed1bf0ad2 |
child 81521 | 1bfad73ab115 |
permissions | -rw-r--r-- |
20089 | 1 |
(* Title: Pure/name.ML |
2 |
Author: Makarius |
|
3 |
||
28965 | 4 |
Names of basic logical entities (variables etc.). |
20089 | 5 |
*) |
6 |
||
7 |
signature NAME = |
|
8 |
sig |
|
24849 | 9 |
val uu: string |
43683 | 10 |
val uu_: string |
24849 | 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 |
|
55948 | 16 |
val is_internal: string -> bool |
55949 | 17 |
val reject_internal: string * Position.T list -> unit |
20089 | 18 |
val skolem: string -> string |
19 |
val dest_skolem: string -> string |
|
55948 | 20 |
val is_skolem: string -> bool |
55949 | 21 |
val reject_skolem: string * Position.T list -> unit |
20089 | 22 |
val clean_index: string * int -> string * int |
23 |
val clean: string -> string |
|
24 |
type context |
|
25 |
val context: context |
|
74411 | 26 |
val build_context: (context -> context) -> context |
20158 | 27 |
val make_context: string list -> context |
20089 | 28 |
val declare: string -> context -> context |
80601 | 29 |
val declare_renamed: string * string -> context -> context |
20158 | 30 |
val is_declared: context -> string -> bool |
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
31 |
val invent: context -> string -> int -> string list |
81513 | 32 |
val invent': string -> int -> context -> string list * context |
81507 | 33 |
val invent_global: string -> int -> string list |
34 |
val invent_global_types: int -> string list |
|
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
35 |
val invent_names: context -> string -> 'a list -> (string * 'a) list |
81507 | 36 |
val invent_names_global: string -> 'a list -> (string * 'a) list |
81509 | 37 |
val invent_types: context -> 'a list -> (string * 'a) list |
81507 | 38 |
val invent_types_global: 'a list -> (string * 'a) list |
20089 | 39 |
val invent_list: string list -> string -> int -> string list |
43326
47cf4bc789aa
simplified Name.variant -- discontinued builtin fold_map;
wenzelm
parents:
43324
diff
changeset
|
40 |
val variant: string -> context -> string * context |
80599 | 41 |
val variant_bound: string -> context -> string * context |
81517 | 42 |
val variant_names: context -> (string * 'a) list -> (string * 'a) list |
43 |
val variant_names_build: (context -> context) -> (string * 'a) list -> (string * 'a) list |
|
20089 | 44 |
val variant_list: string list -> string list -> string list |
56812 | 45 |
val enforce_case: bool -> string -> string |
56811 | 46 |
val desymbolize: bool option -> string -> string |
20089 | 47 |
end; |
48 |
||
49 |
structure Name: NAME = |
|
50 |
struct |
|
51 |
||
24849 | 52 |
(** common defaults **) |
53 |
||
54 |
val uu = "uu"; |
|
43683 | 55 |
val uu_ = "uu_"; |
24849 | 56 |
val aT = "'a"; |
57 |
||
58 |
||
20089 | 59 |
|
60 |
(** special variable names **) |
|
61 |
||
62 |
(* encoded bounds *) |
|
63 |
||
64 |
(*names for numbered variables -- |
|
65 |
preserves order wrt. int_ord vs. string_ord, avoids allocating new strings*) |
|
66 |
||
67 |
val small_int = Vector.tabulate (1000, fn i => |
|
68 |
let val leading = if i < 10 then "00" else if i < 100 then "0" else "" |
|
69 |
in ":" ^ leading ^ string_of_int i end); |
|
70 |
||
71 |
fun bound n = |
|
77846
5ba68d3bd741
more operations, following Isabelle/ML conventions;
wenzelm
parents:
74411
diff
changeset
|
72 |
if n < 1000 then Vector.nth small_int n |
5ba68d3bd741
more operations, following Isabelle/ML conventions;
wenzelm
parents:
74411
diff
changeset
|
73 |
else ":" ^ bound (n div 1000) ^ Vector.nth small_int (n mod 1000); |
20089 | 74 |
|
75 |
val is_bound = String.isPrefix ":"; |
|
76 |
||
77 |
||
55949 | 78 |
(* internal names -- NB: internal subsumes skolem *) |
20089 | 79 |
|
80 |
val internal = suffix "_"; |
|
81 |
val dest_internal = unsuffix "_"; |
|
55948 | 82 |
val is_internal = String.isSuffix "_"; |
55949 | 83 |
fun reject_internal (x, ps) = |
84 |
if is_internal x then error ("Bad name: " ^ quote x ^ Position.here_list ps) else (); |
|
20089 | 85 |
|
86 |
val skolem = suffix "__"; |
|
87 |
val dest_skolem = unsuffix "__"; |
|
55948 | 88 |
val is_skolem = String.isSuffix "__"; |
55949 | 89 |
fun reject_skolem (x, ps) = |
90 |
if is_skolem x then error ("Bad name: " ^ quote x ^ Position.here_list ps) else (); |
|
20089 | 91 |
|
20099 | 92 |
fun clean_index (x, i) = |
93 |
(case try dest_internal x of |
|
94 |
NONE => (x, i) |
|
95 |
| SOME x' => clean_index (x', i + 1)); |
|
20089 | 96 |
|
97 |
fun clean x = #1 (clean_index (x, 0)); |
|
98 |
||
99 |
||
100 |
||
101 |
(** generating fresh names **) |
|
102 |
||
103 |
(* context *) |
|
104 |
||
105 |
datatype context = |
|
106 |
Context of string option Symtab.table; (*declared names with latest renaming*) |
|
107 |
||
20099 | 108 |
fun declare x (Context tab) = |
109 |
Context (Symtab.default (clean x, NONE) tab); |
|
110 |
||
111 |
fun declare_renaming (x, x') (Context tab) = |
|
112 |
Context (Symtab.update (clean x, SOME (clean x')) tab); |
|
20089 | 113 |
|
80601 | 114 |
fun declare_renamed (x, x') = |
115 |
clean x <> clean x' ? declare_renaming (x, x') #> declare x'; |
|
116 |
||
20158 | 117 |
fun is_declared (Context tab) = Symtab.defined tab; |
20089 | 118 |
fun declared (Context tab) = Symtab.lookup tab; |
119 |
||
20121 | 120 |
val context = Context Symtab.empty |> fold declare ["", "'"]; |
74411 | 121 |
|
122 |
fun build_context (f: context -> context) = f context; |
|
123 |
||
124 |
val make_context = build_context o fold declare; |
|
20089 | 125 |
|
126 |
||
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
127 |
(* invent names *) |
20089 | 128 |
|
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
129 |
fun invent ctxt = |
20089 | 130 |
let |
131 |
fun invs _ 0 = [] |
|
132 |
| invs x n = |
|
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
133 |
let val x' = Symbol.bump_string x |
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
134 |
in if is_declared ctxt x then invs x' n else x :: invs x' (n - 1) end; |
20099 | 135 |
in invs o clean end; |
20089 | 136 |
|
81513 | 137 |
fun invent' x n ctxt = |
138 |
let val xs = invent ctxt x n |
|
139 |
in (xs, fold declare xs ctxt) end; |
|
140 |
||
81507 | 141 |
val invent_global = invent context; |
142 |
val invent_global_types = invent_global aT; |
|
143 |
||
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
144 |
fun invent_names ctxt x xs = invent ctxt x (length xs) ~~ xs; |
81507 | 145 |
fun invent_names_global x xs = invent_names context x xs; |
81509 | 146 |
|
147 |
fun invent_types ctxt xs = invent_names ctxt aT xs; |
|
148 |
fun invent_types_global xs = invent_types context xs; |
|
20198 | 149 |
|
43329
84472e198515
tuned signature: Name.invent and Name.invent_names;
wenzelm
parents:
43326
diff
changeset
|
150 |
val invent_list = invent o make_context; |
20089 | 151 |
|
152 |
||
153 |
(* variants *) |
|
154 |
||
155 |
(*makes a variant of a name distinct from already used names in a |
|
156 |
context; preserves a suffix of underscores "_"*) |
|
43326
47cf4bc789aa
simplified Name.variant -- discontinued builtin fold_map;
wenzelm
parents:
43324
diff
changeset
|
157 |
fun variant name ctxt = |
20089 | 158 |
let |
159 |
fun vary x = |
|
160 |
(case declared ctxt x of |
|
161 |
NONE => x |
|
162 |
| SOME x' => vary (Symbol.bump_string (the_default x x'))); |
|
163 |
||
20121 | 164 |
val (x, n) = clean_index (name, 0); |
20089 | 165 |
val (x', ctxt') = |
20158 | 166 |
if not (is_declared ctxt x) then (x, declare x ctxt) |
20089 | 167 |
else |
168 |
let |
|
169 |
val x0 = Symbol.bump_init x; |
|
170 |
val x' = vary x0; |
|
80601 | 171 |
val ctxt' = ctxt |> declare_renamed (x0, x'); |
20089 | 172 |
in (x', ctxt') end; |
43326
47cf4bc789aa
simplified Name.variant -- discontinued builtin fold_map;
wenzelm
parents:
43324
diff
changeset
|
173 |
in (x' ^ replicate_string n "_", ctxt') end; |
20089 | 174 |
|
80599 | 175 |
fun variant_bound name = variant (if is_bound name then "u" else name); |
176 |
||
81517 | 177 |
fun variant_names ctxt xs = #1 (fold_map (variant o fst) xs ctxt) ~~ map snd xs; |
178 |
fun variant_names_build f xs = variant_names (build_context f) xs; |
|
179 |
||
43326
47cf4bc789aa
simplified Name.variant -- discontinued builtin fold_map;
wenzelm
parents:
43324
diff
changeset
|
180 |
fun variant_list used names = #1 (make_context used |> fold_map variant names); |
20089 | 181 |
|
31013 | 182 |
|
31035 | 183 |
(* names conforming to typical requirements of identifiers in the world outside *) |
31013 | 184 |
|
69137
90fce429e1bc
Jenkins: run ocaml_setup
Lars Hupel <lars.hupel@mytum.de>
parents:
56812
diff
changeset
|
185 |
fun enforce_case' false cs = |
56812 | 186 |
(if forall Symbol.is_ascii_upper cs then map else nth_map 0) Symbol.to_ascii_lower cs |
69137
90fce429e1bc
Jenkins: run ocaml_setup
Lars Hupel <lars.hupel@mytum.de>
parents:
56812
diff
changeset
|
187 |
| enforce_case' true cs = |
56812 | 188 |
nth_map 0 Symbol.to_ascii_upper cs; |
189 |
||
190 |
fun enforce_case upper = implode o enforce_case' upper o raw_explode; |
|
191 |
||
56811 | 192 |
fun desymbolize perhaps_upper "" = |
193 |
if the_default false perhaps_upper then "X" else "x" |
|
194 |
| desymbolize perhaps_upper s = |
|
31013 | 195 |
let |
31035 | 196 |
val xs as (x :: _) = Symbol.explode s; |
33547 | 197 |
val ys = |
198 |
if Symbol.is_ascii_letter x orelse Symbol.is_symbolic x then xs |
|
31013 | 199 |
else "x" :: xs; |
200 |
fun is_valid x = |
|
34307 | 201 |
Symbol.is_ascii_letter x orelse Symbol.is_ascii_digit x; |
31013 | 202 |
fun sep [] = [] |
203 |
| sep (xs as "_" :: _) = xs |
|
204 |
| sep xs = "_" :: xs; |
|
31035 | 205 |
fun desep ("_" :: xs) = xs |
206 |
| desep xs = xs; |
|
33547 | 207 |
fun desymb x xs = |
208 |
if is_valid x then x :: xs |
|
31013 | 209 |
else |
33547 | 210 |
(case Symbol.decode x of |
40627
becf5d5187cc
renamed raw "explode" function to "raw_explode" to emphasize its meaning;
wenzelm
parents:
34307
diff
changeset
|
211 |
Symbol.Sym name => "_" :: raw_explode name @ sep xs |
33547 | 212 |
| _ => sep xs); |
56812 | 213 |
val upper_lower = Option.map enforce_case' perhaps_upper |> the_default I; |
31035 | 214 |
in fold_rev desymb ys [] |> desep |> upper_lower |> implode end; |
31013 | 215 |
|
20089 | 216 |
end; |