Import Upstream version 20180207
[hcoop/debian/mlton.git] / mlyacc / src / utils.sml
CommitLineData
7f918cf1
CE
1(* ML-Yacc Parser Generator (c) 1989 Andrew W. Appel, David R. Tarditi *)
2
3(* Implementation of ordered sets using ordered lists and red-black trees. The
4 code for red-black trees was originally written by Norris Boyd, which was
5 modified for use here.
6*)
7
8(* ordered sets implemented using ordered lists.
9
10 Upper bound running times for functions implemented here:
11
12 app = O(n)
13 card = O(n)
14 closure = O(n^2)
15 difference = O(n+m), where n,m = the size of the two sets used here.
16 empty = O(1)
17 exists = O(n)
18 find = O(n)
19 fold = O(n)
20 insert = O(n)
21 is_empty = O(1)
22 make_list = O(1)
23 make_set = O(n^2)
24 partition = O(n)
25 remove = O(n)
26 revfold = O(n)
27 select_arb = O(1)
28 set_eq = O(n), where n = the cardinality of the smaller set
29 set_gt = O(n), ditto
30 singleton = O(1)
31 union = O(n+m)
32*)
33
34functor ListOrdSet(B : sig type elem
35 val gt : elem * elem -> bool
36 val eq : elem * elem -> bool
37 end ) : ORDSET =
38
39struct
40 type elem = B.elem
41 val elem_gt = B.gt
42 val elem_eq = B.eq
43
44 type set = elem list
45 exception Select_arb
46 val empty = nil
47
48 val insert = fn (key,s) =>
49 let fun f (l as (h::t)) =
50 if elem_gt(key,h) then h::(f t)
51 else if elem_eq(key,h) then key::t
52 else key::l
53 | f nil = [key]
54 in f s
55 end
56
57 val select_arb = fn nil => raise Select_arb
58 | a::b => a
59
60 val exists = fn (key,s) =>
61 let fun f (h::t) = if elem_gt(key,h) then f t
62 else elem_eq(h,key)
63 | f nil = false
64 in f s
65 end
66
67 val find = fn (key,s) =>
68 let fun f (h::t) = if elem_gt(key,h) then f t
69 else if elem_eq(h,key) then SOME h
70 else NONE
71 | f nil = NONE
72 in f s
73 end
74
75 fun revfold f lst init = List.foldl f init lst
76 fun fold f lst init = List.foldr f init lst
77 val app = List.app
78
79fun set_eq(h::t,h'::t') =
80 (case elem_eq(h,h')
81 of true => set_eq(t,t')
82 | a => a)
83 | set_eq(nil,nil) = true
84 | set_eq _ = false
85
86fun set_gt(h::t,h'::t') =
87 (case elem_gt(h,h')
88 of false => (case (elem_eq(h,h'))
89 of true => set_gt(t,t')
90 | a => a)
91 | a => a)
92 | set_gt(_::_,nil) = true
93 | set_gt _ = false
94
95fun union(a as (h::t),b as (h'::t')) =
96 if elem_gt(h',h) then h::union(t,b)
97 else if elem_eq(h,h') then h::union(t,t')
98 else h'::union(a,t')
99 | union(nil,s) = s
100 | union(s,nil) = s
101
102val make_list = fn s => s
103
104val is_empty = fn nil => true | _ => false
105
106val make_set = fn l => List.foldr insert [] l
107
108val partition = fn f => fn s =>
109 fold (fn (e,(yes,no)) =>
110 if (f e) then (e::yes,no) else (e::no,yes)) s (nil,nil)
111
112val remove = fn (e,s) =>
113 let fun f (l as (h::t)) = if elem_gt(h,e) then l
114 else if elem_eq(h,e) then t
115 else h::(f t)
116 | f nil = nil
117 in f s
118 end
119
120 (* difference: X-Y *)
121
122 fun difference (nil,_) = nil
123 | difference (r,nil) = r
124 | difference (a as (h::t),b as (h'::t')) =
125 if elem_gt (h',h) then h::difference(t,b)
126 else if elem_eq(h',h) then difference(t,t')
127 else difference(a,t')
128
129 fun singleton X = [X]
130
131 fun card(S) = fold (fn (a,count) => count+1) S 0
132
133 local
134 fun closure'(from, f, result) =
135 if is_empty from then result
136 else
137 let val (more,result) =
138 fold (fn (a,(more',result')) =>
139 let val more = f a
140 val new = difference(more,result)
141 in (union(more',new),union(result',new))
142 end) from
143 (empty,result)
144 in closure'(more,f,result)
145 end
146 in
147 fun closure(start, f) = closure'(start, f, start)
148 end
149end
150
151(* ordered set implemented using red-black trees:
152
153 Upper bound running time of the functions below:
154
155 app: O(n)
156 card: O(n)
157 closure: O(n^2 ln n)
158 difference: O(n ln n)
159 empty: O(1)
160 exists: O(ln n)
161 find: O(ln n)
162 fold: O(n)
163 insert: O(ln n)
164 is_empty: O(1)
165 make_list: O(n)
166 make_set: O(n ln n)
167 partition: O(n ln n)
168 remove: O(n ln n)
169 revfold: O(n)
170 select_arb: O(1)
171 set_eq: O(n)
172 set_gt: O(n)
173 singleton: O(1)
174 union: O(n ln n)
175*)
176
177functor RbOrdSet (B : sig type elem
178 val eq : (elem*elem) -> bool
179 val gt : (elem*elem) -> bool
180 end
181 ) : ORDSET =
182struct
183
184 type elem = B.elem
185 val elem_gt = B.gt
186 val elem_eq = B.eq
187
188 datatype Color = RED | BLACK
189
190 abstype set = EMPTY | TREE of (B.elem * Color * set * set)
191 with exception Select_arb
192 val empty = EMPTY
193
194 fun insert(key,t) =
195 let fun f EMPTY = TREE(key,RED,EMPTY,EMPTY)
196 | f (TREE(k,BLACK,l,r)) =
197 if elem_gt (key,k)
198 then case f r
199 of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) =>
200 (case l
201 of TREE(lk,RED,ll,lr) =>
202 TREE(k,RED,TREE(lk,BLACK,ll,lr),
203 TREE(rk,BLACK,rl,rr))
204 | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll),
205 TREE(rk,RED,rlr,rr)))
206 | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) =>
207 (case l
208 of TREE(lk,RED,ll,lr) =>
209 TREE(k,RED,TREE(lk,BLACK,ll,lr),
210 TREE(rk,BLACK,rl,rr))
211 | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr))
212 | r => TREE(k,BLACK,l,r)
213 else if elem_gt(k,key)
214 then case f l
215 of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) =>
216 (case r
217 of TREE(rk,RED,rl,rr) =>
218 TREE(k,RED,TREE(lk,BLACK,ll,lr),
219 TREE(rk,BLACK,rl,rr))
220 | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl),
221 TREE(k,RED,lrr,r)))
222 | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) =>
223 (case r
224 of TREE(rk,RED,rl,rr) =>
225 TREE(k,RED,TREE(lk,BLACK,ll,lr),
226 TREE(rk,BLACK,rl,rr))
227 | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r)))
228 | l => TREE(k,BLACK,l,r)
229 else TREE(key,BLACK,l,r)
230 | f (TREE(k,RED,l,r)) =
231 if elem_gt(key,k) then TREE(k,RED,l, f r)
232 else if elem_gt(k,key) then TREE(k,RED, f l, r)
233 else TREE(key,RED,l,r)
234 in case f t
235 of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r)
236 | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r)
237 | t => t
238 end
239
240 fun select_arb (TREE(k,_,l,r)) = k
241 | select_arb EMPTY = raise Select_arb
242
243 fun exists(key,t) =
244 let fun look EMPTY = false
245 | look (TREE(k,_,l,r)) =
246 if elem_gt(k,key) then look l
247 else if elem_gt(key,k) then look r
248 else true
249 in look t
250 end
251
252 fun find(key,t) =
253 let fun look EMPTY = NONE
254 | look (TREE(k,_,l,r)) =
255 if elem_gt(k,key) then look l
256 else if elem_gt(key,k) then look r
257 else SOME k
258 in look t
259 end
260
261 fun revfold f t start =
262 let fun scan (EMPTY,value) = value
263 | scan (TREE(k,_,l,r),value) = scan(r,f(k,scan(l,value)))
264 in scan(t,start)
265 end
266
267 fun fold f t start =
268 let fun scan(EMPTY,value) = value
269 | scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value)))
270 in scan(t,start)
271 end
272
273 fun app f t =
274 let fun scan EMPTY = ()
275 | scan(TREE(k,_,l,r)) = (scan l; f k; scan r)
276 in scan t
277 end
278
279(* equal_tree : test if two trees are equal. Two trees are equal if
280 the set of leaves are equal *)
281
282 fun set_eq (tree1 as (TREE _),tree2 as (TREE _)) =
283 let datatype pos = L | R | M
284 exception Done
285 fun getvalue(stack as ((a,position)::b)) =
286 (case a
287 of (TREE(k,_,l,r)) =>
288 (case position
289 of L => getvalue ((l,L)::(a,M)::b)
290 | M => (k,case r of EMPTY => b | _ => (a,R)::b)
291 | R => getvalue ((r,L)::b)
292 )
293 | EMPTY => getvalue b
294 )
295 | getvalue(nil) = raise Done
296 fun f (nil,nil) = true
297 | f (s1 as (_ :: _),s2 as (_ :: _ )) =
298 let val (v1,news1) = getvalue s1
299 and (v2,news2) = getvalue s2
300 in (elem_eq(v1,v2)) andalso f(news1,news2)
301 end
302 | f _ = false
303 in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false
304 end
305 | set_eq (EMPTY,EMPTY) = true
306 | set_eq _ = false
307
308 (* gt_tree : Test if tree1 is greater than tree 2 *)
309
310 fun set_gt (tree1,tree2) =
311 let datatype pos = L | R | M
312 exception Done
313 fun getvalue(stack as ((a,position)::b)) =
314 (case a
315 of (TREE(k,_,l,r)) =>
316 (case position
317 of L => getvalue ((l,L)::(a,M)::b)
318 | M => (k,case r of EMPTY => b | _ => (a,R)::b)
319 | R => getvalue ((r,L)::b)
320 )
321 | EMPTY => getvalue b
322 )
323 | getvalue(nil) = raise Done
324 fun f (nil,nil) = false
325 | f (s1 as (_ :: _),s2 as (_ :: _ )) =
326 let val (v1,news1) = getvalue s1
327 and (v2,news2) = getvalue s2
328 in (elem_gt(v1,v2)) orelse (elem_eq(v1,v2) andalso f(news1,news2))
329 end
330 | f (_,nil) = true
331 | f (nil,_) = false
332 in f ((tree1,L)::nil,(tree2,L)::nil) handle Done => false
333 end
334
335 fun is_empty S = (let val _ = select_arb S in false end
336 handle Select_arb => true)
337
338 fun make_list S = fold (op ::) S nil
339
340 fun make_set l = List.foldr insert empty l
341
342 fun partition F S = fold (fn (a,(Yes,No)) =>
343 if F(a) then (insert(a,Yes),No)
344 else (Yes,insert(a,No)))
345 S (empty,empty)
346
347 fun remove(X, XSet) =
348 let val (YSet, _) =
349 partition (fn a => not (elem_eq (X, a))) XSet
350 in YSet
351 end
352
353 fun difference(Xs, Ys) =
354 fold (fn (p as (a,Xs')) =>
355 if exists(a,Ys) then Xs' else insert p)
356 Xs empty
357
358 fun singleton X = insert(X,empty)
359
360 fun card(S) = fold (fn (_,count) => count+1) S 0
361
362 fun union(Xs,Ys)= fold insert Ys Xs
363
364 local
365 fun closure'(from, f, result) =
366 if is_empty from then result
367 else
368 let val (more,result) =
369 fold (fn (a,(more',result')) =>
370 let val more = f a
371 val new = difference(more,result)
372 in (union(more',new),union(result',new))
373 end) from
374 (empty,result)
375 in closure'(more,f,result)
376 end
377 in
378 fun closure(start, f) = closure'(start, f, start)
379 end
380 end
381end
382
383(* In utils.sig
384signature TABLE =
385 sig
386 type 'a table
387 type key
388 val size : 'a table -> int
389 val empty: 'a table
390 val exists: (key * 'a table) -> bool
391 val find : (key * 'a table) -> 'a option
392 val insert: ((key * 'a) * 'a table) -> 'a table
393 val make_table : (key * 'a ) list -> 'a table
394 val make_list : 'a table -> (key * 'a) list
395 val fold : ((key * 'a) * 'b -> 'b) -> 'a table -> 'b -> 'b
396 end
397*)
398
399functor Table (B : sig type key
400 val gt : (key * key) -> bool
401 end
402 ) : TABLE =
403struct
404
405 datatype Color = RED | BLACK
406 type key = B.key
407
408 abstype 'a table = EMPTY
409 | TREE of ((B.key * 'a ) * Color * 'a table * 'a table)
410 with
411
412 val empty = EMPTY
413
414 fun insert(elem as (key,data),t) =
415 let val key_gt = fn (a,_) => B.gt(key,a)
416 val key_lt = fn (a,_) => B.gt(a,key)
417 fun f EMPTY = TREE(elem,RED,EMPTY,EMPTY)
418 | f (TREE(k,BLACK,l,r)) =
419 if key_gt k
420 then case f r
421 of r as TREE(rk,RED, rl as TREE(rlk,RED,rll,rlr),rr) =>
422 (case l
423 of TREE(lk,RED,ll,lr) =>
424 TREE(k,RED,TREE(lk,BLACK,ll,lr),
425 TREE(rk,BLACK,rl,rr))
426 | _ => TREE(rlk,BLACK,TREE(k,RED,l,rll),
427 TREE(rk,RED,rlr,rr)))
428 | r as TREE(rk,RED,rl, rr as TREE(rrk,RED,rrl,rrr)) =>
429 (case l
430 of TREE(lk,RED,ll,lr) =>
431 TREE(k,RED,TREE(lk,BLACK,ll,lr),
432 TREE(rk,BLACK,rl,rr))
433 | _ => TREE(rk,BLACK,TREE(k,RED,l,rl),rr))
434 | r => TREE(k,BLACK,l,r)
435 else if key_lt k
436 then case f l
437 of l as TREE(lk,RED,ll, lr as TREE(lrk,RED,lrl,lrr)) =>
438 (case r
439 of TREE(rk,RED,rl,rr) =>
440 TREE(k,RED,TREE(lk,BLACK,ll,lr),
441 TREE(rk,BLACK,rl,rr))
442 | _ => TREE(lrk,BLACK,TREE(lk,RED,ll,lrl),
443 TREE(k,RED,lrr,r)))
444 | l as TREE(lk,RED, ll as TREE(llk,RED,lll,llr), lr) =>
445 (case r
446 of TREE(rk,RED,rl,rr) =>
447 TREE(k,RED,TREE(lk,BLACK,ll,lr),
448 TREE(rk,BLACK,rl,rr))
449 | _ => TREE(lk,BLACK,ll,TREE(k,RED,lr,r)))
450 | l => TREE(k,BLACK,l,r)
451 else TREE(elem,BLACK,l,r)
452 | f (TREE(k,RED,l,r)) =
453 if key_gt k then TREE(k,RED,l, f r)
454 else if key_lt k then TREE(k,RED, f l, r)
455 else TREE(elem,RED,l,r)
456 in case f t
457 of TREE(k,RED, l as TREE(_,RED,_,_), r) => TREE(k,BLACK,l,r)
458 | TREE(k,RED, l, r as TREE(_,RED,_,_)) => TREE(k,BLACK,l,r)
459 | t => t
460 end
461
462 fun exists(key,t) =
463 let fun look EMPTY = false
464 | look (TREE((k,_),_,l,r)) =
465 if B.gt(k,key) then look l
466 else if B.gt(key,k) then look r
467 else true
468 in look t
469 end
470
471 fun find(key,t) =
472 let fun look EMPTY = NONE
473 | look (TREE((k,data),_,l,r)) =
474 if B.gt(k,key) then look l
475 else if B.gt(key,k) then look r
476 else SOME data
477 in look t
478 end
479
480 fun fold f t start =
481 let fun scan(EMPTY,value) = value
482 | scan(TREE(k,_,l,r),value) = scan(l,f(k,scan(r,value)))
483 in scan(t,start)
484 end
485
486 fun make_table l = List.foldr insert empty l
487
488 fun size S = fold (fn (_,count) => count+1) S 0
489
490 fun make_list table = fold (op ::) table nil
491
492 end
493end;
494
495(* assumes that a functor Table with signature TABLE from table.sml is
496 in the environment *)
497
498(* In utils.sig
499signature HASH =
500 sig
501 type table
502 type elem
503
504 val size : table -> int
505 val add : elem * table -> table
506 val find : elem * table -> int option
507 val exists : elem * table -> bool
508 val empty : table
509 end
510*)
511
512(* hash: creates a hash table of size n which assigns each distinct member
513 a unique integer between 0 and n-1 *)
514
515functor Hash(B : sig type elem
516 val gt : elem * elem -> bool
517 end) : HASH =
518struct
519 type elem=B.elem
520 structure HashTable = Table(type key=B.elem
521 val gt = B.gt)
522
523 type table = {count : int, table : int HashTable.table}
524
525 val empty = {count=0,table=HashTable.empty}
526 val size = fn {count,table} => count
527 val add = fn (e,{count,table}) =>
528 {count=count+1,table=HashTable.insert((e,count),table)}
529 val find = fn (e,{table,count}) => HashTable.find(e,table)
530 val exists = fn (e,{table,count}) => HashTable.exists(e,table)
531end;