4 (** {2 Polymorphic maps to be used in spec/ghost only} *)
12 type fmap 'k 'v = abstract {
16 meta coercion function contents
18 predicate (==) (m1 m2: fmap 'k 'v) =
19 S.(==) m1.domain m2.domain /\
20 forall k. S.mem k m1.domain -> m1[k] = m2[k]
23 forall m1 m2: fmap 'k 'v. m1 == m2 -> m1 = m2
25 predicate mem (k: 'k) (m: fmap 'k 'v) =
28 predicate mapsto (k: 'k) (v: 'v) (m: fmap 'k 'v) =
32 forall k: 'k, m: fmap 'k 'v. mem k m -> mapsto k m[k] m
34 predicate is_empty (m: fmap 'k 'v) =
37 function mk (d: S.fset 'k) (m: 'k -> 'v) : fmap 'k 'v
40 forall d: S.fset 'k, m: 'k -> 'v. domain (mk d m) = d
43 forall d: S.fset 'k, m: 'k -> 'v, k: 'k.
44 S.mem k d -> (mk d m)[k] = m[k]
46 constant empty: fmap 'k 'v
48 axiom is_empty_empty: is_empty (empty: fmap 'k 'v)
50 function add (k: 'k) (v: 'v) (m: fmap 'k 'v) : fmap 'k 'v
52 function ([<-]) (m: fmap 'k 'v) (k: 'k) (v: 'v) : fmap 'k 'v =
55 (*FIXME? (add k v m).contents = m.contents[k <- v] *)
58 forall k v, m: fmap 'k 'v. (add k v m)[k] = v
60 axiom add_contents_other:
61 forall k v, m: fmap 'k 'v, k1. mem k1 m -> k1 <> k -> (add k v m)[k1] = m[k1]
64 forall k v, m: fmap 'k 'v. (add k v m).domain = S.add k m.domain
66 (* FIXME? find_opt (k: 'k) (m: fmap 'k 'v) : option 'v *)
68 function find (k: 'k) (m: fmap 'k 'v) : 'v
71 forall k, m: fmap 'k 'v. mem k m -> find k m = m[k]
73 function remove (k: 'k) (m: fmap 'k 'v) : fmap 'k 'v
75 axiom remove_contents:
76 forall k, m: fmap 'k 'v, k1. mem k1 m -> k1 <> k -> (remove k m)[k1] = m[k1]
79 forall k, m: fmap 'k 'v. (remove k m).domain = S.remove k m.domain
81 function size (m: fmap 'k 'v) : int =
86 (** {2 Finite monomorphic maps to be used in programs only}
88 A program function `eq` deciding equality on the `key` type must be provided when cloned.
91 (** {3 Applicative maps} *)
101 (* we enforce type `key` to have a decidable equality
102 by requiring the following function *)
103 val eq (x y: key) : bool
104 ensures { result <-> x = y }
106 type t 'v = abstract {
107 to_fmap: fmap key 'v;
109 meta coercion function to_fmap
112 ensures { result.to_fmap = empty }
114 val mem (k: key) (m: t 'v) : bool
115 ensures { result <-> mem k m }
117 val is_empty (m: t 'v) : bool
118 ensures { result <-> is_empty m }
120 val add (k: key) (v: 'v) (m: t 'v) : t 'v
121 ensures { result = add k v m }
123 val find (k: key) (m: t 'v) : 'v
125 ensures { result = m[k] }
126 ensures { result = find k m }
130 val find_exn (k: key) (m: t 'v) : 'v
131 ensures { S.mem k m.domain }
132 ensures { result = m[k] }
133 raises { Not_found -> not (S.mem k m.domain) }
135 val remove (k: key) (m: t 'v) : t 'v
136 ensures { result = remove k m }
138 val size (m: t 'v) : int
139 ensures { result = size m }
143 (** {3 Applicative maps of integers} *)
149 clone export MapApp with type key = int, val eq = Int.(=)
153 (** {3 Imperative maps} *)
163 val eq (x y: key) : bool
164 ensures { result <-> x = y }
166 type t 'v = abstract {
167 mutable to_fmap: fmap key 'v;
169 meta coercion function to_fmap
172 ensures { result.to_fmap = empty }
174 val mem (k: key) (m: t 'v) : bool
175 ensures { result <-> mem k m }
177 val is_empty (m: t 'v) : bool
178 ensures { result <-> is_empty m }
180 val add (k: key) (v: 'v) (m: t 'v) : unit
182 ensures { m = add k v (old m) }
184 val find (k: key) (m: t 'v) : 'v
186 ensures { result = m[k] }
187 ensures { result = find k m }
191 val find_exn (k: key) (m: t 'v) : 'v
192 ensures { S.mem k m.domain }
193 ensures { result = m[k] }
194 raises { Not_found -> not (S.mem k m.domain) }
196 val remove (k: key) (m: t 'v) : unit
198 ensures { m = remove k (old m) }
200 val size (m: t 'v) : int
201 ensures { result = size m }
203 val clear (m: t 'v) : unit
205 ensures { m = empty }
209 (** {3 Imperative maps of integers} *)
215 clone export MapImp with type key = int, val eq = Int.(=)