| author | haftmann |
| Mon, 14 Nov 2005 15:15:07 +0100 | |
| changeset 18167 | 4f9410e685df |
| parent 17911 | fbe857bedcd7 |
| child 18453 | 2b2fbc32550e |
| permissions | -rw-r--r-- |
| 17152 | 1 |
(* Title: Pure/General/alist.ML |
2 |
ID: $Id$ |
|
3 |
Author: Florian Haftmann, TU Muenchen |
|
4 |
||
5 |
Association lists -- lists of (key, value) pairs with unique keys. |
|
6 |
A light-weight representation of finite mappings; |
|
7 |
see also Pure/General/table.ML for a more scalable implementation. |
|
8 |
*) |
|
9 |
||
10 |
signature ALIST = |
|
11 |
sig |
|
| 17766 | 12 |
exception DUP |
| 17152 | 13 |
val lookup: ('a * 'b -> bool) -> ('b * 'c) list -> 'a -> 'c option
|
14 |
val defined: ('a * 'b -> bool) -> ('b * 'c) list -> 'a -> bool
|
|
15 |
val update: ('a * 'a -> bool) -> ('a * 'b)
|
|
16 |
-> ('a * 'b) list -> ('a * 'b) list
|
|
17 |
val default: ('a * 'a -> bool) -> ('a * 'b)
|
|
18 |
-> ('a * 'b) list -> ('a * 'b) list
|
|
19 |
val delete: ('a * 'b -> bool) -> 'a
|
|
20 |
-> ('b * 'c) list -> ('b * 'c) list
|
|
21 |
val map_entry: ('a * 'b -> bool) -> 'a -> ('c -> 'c)
|
|
22 |
-> ('b * 'c) list -> ('b * 'c) list
|
|
| 17487 | 23 |
val make: ('a -> 'b) -> 'a list -> ('a * 'b) list
|
| 17911 | 24 |
val join: ('a * 'a -> bool) -> ('a -> 'b * 'b -> 'b option) ->
|
25 |
('a * 'b) list * ('a * 'b) list -> ('a * 'b) list (*exception DUP*)
|
|
| 17766 | 26 |
val merge: ('a * 'a -> bool) -> ('b * 'b -> bool)
|
| 17911 | 27 |
-> ('a * 'b) list * ('a * 'b) list -> ('a * 'b) list (*exception DUP*)
|
| 17497 | 28 |
val find: ('a * 'b -> bool) -> ('c * 'b) list -> 'a -> 'c list
|
|
18167
4f9410e685df
string_of_alist - convenient q'n'd printout function
haftmann
parents:
17911
diff
changeset
|
29 |
val string_of_alist: ('a -> string) -> ('b -> string) -> ('a * 'b) list -> string
|
| 17152 | 30 |
end; |
31 |
||
32 |
structure AList: ALIST = |
|
33 |
struct |
|
34 |
||
| 17766 | 35 |
fun find_index eq xs key = |
36 |
let |
|
37 |
fun find [] _ = 0 |
|
38 |
| find ((key', value)::xs) i = |
|
39 |
if eq (key, key') |
|
40 |
then i |
|
41 |
else find xs (i+1); |
|
42 |
in find xs 1 end; |
|
43 |
||
| 17152 | 44 |
fun lookup _ [] _ = NONE |
45 |
| lookup eq ((key, value)::xs) key' = |
|
46 |
if eq (key', key) then SOME value |
|
47 |
else lookup eq xs key'; |
|
48 |
||
49 |
fun defined _ [] _ = false |
|
50 |
| defined eq ((key, value)::xs) key' = |
|
51 |
eq (key', key) orelse defined eq xs key'; |
|
52 |
||
| 17766 | 53 |
fun update eq (x as (key, value)) xs = |
| 17152 | 54 |
let |
| 17766 | 55 |
val i = find_index eq xs key; |
56 |
fun upd 1 (_::xs) = (x::xs) |
|
57 |
| upd i (x::xs) = x :: upd (i-1) xs; |
|
58 |
in if i = 0 then x::xs else upd i xs end; |
|
| 17152 | 59 |
|
60 |
fun default eq (key, value) xs = |
|
61 |
if defined eq xs key then xs else (key, value)::xs; |
|
62 |
||
63 |
fun delete eq key xs = |
|
64 |
let |
|
| 17766 | 65 |
val i = find_index eq xs key; |
66 |
fun del 1 (_::xs) = xs |
|
67 |
| del i (x::xs) = x :: del (i-1) xs; |
|
68 |
in if i = 0 then xs else del i xs end; |
|
69 |
||
70 |
fun map_entry eq key f xs = |
|
71 |
let |
|
72 |
val i = find_index eq xs key; |
|
73 |
fun mapp 1 ((x as (key, value))::xs) = (key, f value) :: xs |
|
74 |
| mapp i (x::xs) = x :: mapp (i-1) xs; |
|
75 |
in if i = 0 then xs else mapp i xs end; |
|
| 17152 | 76 |
|
| 17766 | 77 |
exception DUP; |
78 |
||
| 17911 | 79 |
fun join eq f (xs, ys) = |
80 |
let |
|
81 |
fun add (key, x) xs = |
|
82 |
(case lookup eq xs key of |
|
83 |
NONE => update eq (key, x) xs |
|
84 |
| SOME y => |
|
85 |
(case f key (y, x) of |
|
86 |
SOME z => update eq (key, z) xs |
|
87 |
| NONE => raise DUP)); |
|
88 |
in fold_rev add xs ys end; |
|
89 |
||
| 17766 | 90 |
fun merge eq_key eq_val (xs, ys) = |
| 17191 | 91 |
let |
| 17766 | 92 |
fun add (x as (key, value)) ys = |
93 |
case lookup eq_key ys key |
|
94 |
of NONE => update eq_key x ys |
|
95 |
| SOME value' => |
|
96 |
if eq_val (value, value') |
|
97 |
then ys |
|
98 |
else raise DUP; |
|
| 17911 | 99 |
in fold_rev add xs ys end; |
| 17191 | 100 |
|
| 17487 | 101 |
fun make keyfun = |
102 |
let fun keypair x = (x, keyfun x) |
|
103 |
in map keypair end; |
|
104 |
||
| 17497 | 105 |
fun find eq [] _ = [] |
106 |
| find eq ((key, value) :: xs) value' = |
|
107 |
let |
|
| 17766 | 108 |
val values = find eq xs value'; |
| 17497 | 109 |
in if eq (value', value) then key :: values else values end; |
110 |
||
|
18167
4f9410e685df
string_of_alist - convenient q'n'd printout function
haftmann
parents:
17911
diff
changeset
|
111 |
fun string_of_alist string_of_key string_of_value = |
|
4f9410e685df
string_of_alist - convenient q'n'd printout function
haftmann
parents:
17911
diff
changeset
|
112 |
map (fn (key, value) => string_of_key key ^ " -> " ^ string_of_value value) |
|
4f9410e685df
string_of_alist - convenient q'n'd printout function
haftmann
parents:
17911
diff
changeset
|
113 |
#> commas |
|
4f9410e685df
string_of_alist - convenient q'n'd printout function
haftmann
parents:
17911
diff
changeset
|
114 |
#> enclose "[" "]" |
|
4f9410e685df
string_of_alist - convenient q'n'd printout function
haftmann
parents:
17911
diff
changeset
|
115 |
|
| 17152 | 116 |
end; |