4 - polymorphic sets to be used in specification/ghost only
5 (no executable functions)
7 - `Set`, `Cardinal`: possibly infinite sets
8 - `Fset`, `FsetInt`, `FsetInduction`, `FsetSum`: finite sets
10 - monomorphic finite sets to be used in programs only (no logical functions)
12 a program function `eq` deciding equality on the element type must be
15 - `SetApp`, `SetAppInt`: immutable sets
16 - `SetImp`, `SetImpInt`: mutable sets
20 (** {2 Potentially infinite sets} *)
27 type set 'a = map 'a bool
29 (** if `'a` is an infinite type, then `set 'a` is infinite *)
30 meta "material_type_arg" type set, 0
33 predicate mem (x: 'a) (s: set 'a) = s[x]
36 predicate (==) (s1 s2: set 'a) = forall x: 'a. mem x s1 <-> mem x s2
39 forall s1 s2: set 'a. s1 == s2 -> s1 = s2
42 predicate subset (s1 s2: set 'a) = forall x : 'a. mem x s1 -> mem x s2
45 forall s: set 'a. subset s s
48 forall s1 s2 s3: set 'a. subset s1 s2 -> subset s2 s3 -> subset s1 s3
51 predicate is_empty (s: set 'a) = forall x: 'a. not (mem x s)
53 let constant empty: set 'a = const false
55 lemma is_empty_empty: is_empty (empty: set 'a)
58 forall s: set 'a. is_empty s -> s = empty
61 let constant all: set 'a = const true
64 function add (x: 'a) (s: set 'a): set 'a = s[x <- true]
66 function singleton (x: 'a): set 'a = add x empty
69 forall x, y: 'a. mem y (singleton x) -> y = x
72 function remove (x: 'a) (s: set 'a): set 'a = s[x <- false]
75 forall x: 'a, s: set 'a. mem x s -> add x (remove x s) = s
78 forall x: 'a, s: set 'a. remove x (add x s) = remove x s
81 forall x: 'a, s: set 'a. subset (remove x s) s
84 function union (s1 s2: set 'a): set 'a
85 = fun x -> mem x s1 \/ mem x s2
88 forall s1 s2: set 'a. subset s1 (union s1 s2)
90 forall s1 s2: set 'a. subset s2 (union s1 s2)
93 function inter (s1 s2: set 'a): set 'a
94 = fun x -> mem x s1 /\ mem x s2
97 forall s1 s2: set 'a. subset (inter s1 s2) s1
99 forall s1 s2: set 'a. subset (inter s1 s2) s2
102 function diff (s1 s2: set 'a): set 'a
103 = fun x -> mem x s1 /\ not (mem x s2)
106 forall s1 s2: set 'a. subset (diff s1 s2) s1
109 function complement (s: set 'a): set 'a
110 = fun x -> not (mem x s)
112 (** arbitrary element *)
113 function pick (s: set 'a): 'a
115 axiom pick_def: forall s: set 'a. not (is_empty s) -> mem (pick s) s
118 predicate disjoint (s1 s2: set 'a) =
119 forall x. not (mem x s1) \/ not (mem x s2)
121 lemma disjoint_inter_empty:
122 forall s1 s2: set 'a. disjoint s1 s2 <-> is_empty (inter s1 s2)
124 lemma disjoint_diff_eq:
125 forall s1 s2: set 'a. disjoint s1 s2 <-> diff s1 s2 = s1
127 lemma disjoint_diff_s2:
128 forall s1 s2: set 'a. disjoint (diff s1 s2) s2
130 (** `{ (x, y) | x in s1 /\ y in s2 }` *)
131 function product (s1: set 'a) (s2: set 'b) : set ('a, 'b)
133 forall s1: set 'a, s2: set 'b, x : 'a, y : 'b.
134 mem (x, y) (product s1 s2) <-> mem x s1 /\ mem y s2
136 (** `{ x | x in s /\ p x }` *)
137 function filter (s: set 'a) (p: 'a -> bool) : set 'a
139 forall s: set 'a, p: 'a -> bool, x: 'a. mem x (filter s p) <-> mem x s /\ p x
142 forall s: set 'a, p: 'a -> bool. subset (filter s p) s
144 (** `{ f x | x in U }` *)
145 function map (f: 'a -> 'b) (u: set 'a) : set 'b =
146 fun (y: 'b) -> exists x: 'a. mem x u /\ y = f x
149 forall f: 'a -> 'b, u: set 'a.
150 forall x: 'a. mem x u -> mem (f x) (map f u)
158 predicate is_finite (s: set 'a)
160 axiom is_finite_empty:
161 forall s: set 'a. is_empty s -> is_finite s
163 axiom is_finite_subset:
164 forall s1 s2: set 'a. is_finite s2 -> subset s1 s2 -> is_finite s1
167 forall x: 'a, s: set 'a. is_finite s -> is_finite (add x s)
168 axiom is_finite_add_rev:
169 forall x: 'a, s: set 'a. is_finite (add x s) -> is_finite s
171 lemma is_finite_singleton:
172 forall x: 'a. is_finite (singleton x)
174 axiom is_finite_remove:
175 forall x: 'a, s: set 'a. is_finite s -> is_finite (remove x s)
176 axiom is_finite_remove_rev:
177 forall x: 'a, s: set 'a. is_finite (remove x s) -> is_finite s
179 axiom is_finite_union:
180 forall s1 s2: set 'a.
181 is_finite s1 -> is_finite s2 -> is_finite (union s1 s2)
182 axiom is_finite_union_rev:
183 forall s1 s2: set 'a.
184 is_finite (union s1 s2) -> is_finite s1 /\ is_finite s2
186 axiom is_finite_inter_left:
187 forall s1 s2: set 'a. is_finite s1 -> is_finite (inter s1 s2)
188 axiom is_finite_inter_right:
189 forall s1 s2: set 'a. is_finite s2 -> is_finite (inter s1 s2)
191 axiom is_finite_diff:
192 forall s1 s2: set 'a. is_finite s1 -> is_finite (diff s1 s2)
195 forall f: 'a -> 'b, s: set 'a. is_finite s -> is_finite (map f s)
197 lemma is_finite_product:
198 forall s1: set 'a, s2 : set 'b. is_finite s1 -> is_finite s2 ->
199 is_finite (product s1 s2)
201 (** `cardinal` function *)
205 function cardinal (set 'a): int
207 axiom cardinal_nonneg:
208 forall s: set 'a. cardinal s >= 0
210 axiom cardinal_empty:
211 forall s: set 'a. is_finite s -> (is_empty s <-> cardinal s = 0)
214 forall x: 'a. forall s: set 'a. is_finite s ->
215 if mem x s then cardinal (add x s) = cardinal s
216 else cardinal (add x s) = cardinal s + 1
218 axiom cardinal_remove:
219 forall x: 'a. forall s: set 'a. is_finite s ->
220 if mem x s then cardinal (remove x s) = cardinal s - 1
221 else cardinal (remove x s) = cardinal s
223 axiom cardinal_subset:
224 forall s1 s2: set 'a. is_finite s2 ->
225 subset s1 s2 -> cardinal s1 <= cardinal s2
228 forall s1 s2: set 'a. is_finite s2 ->
229 subset s1 s2 -> cardinal s1 = cardinal s2 -> s1 = s2
232 forall s: set 'a. cardinal s = 1 ->
233 forall x: 'a. mem x s -> x = pick s
235 axiom cardinal_union:
236 forall s1 s2: set 'a. is_finite s1 -> is_finite s2 ->
237 cardinal (union s1 s2) = cardinal s1 + cardinal s2 - cardinal (inter s1 s2)
239 lemma cardinal_inter_disjoint:
240 forall s1 s2: set 'a. disjoint s1 s2 -> cardinal (inter s1 s2) = 0
243 forall s1 s2: set 'a. is_finite s1 ->
244 cardinal (diff s1 s2) = cardinal s1 - cardinal (inter s1 s2)
247 forall f: 'a -> 'b, s: set 'a. is_finite s ->
248 cardinal (map f s) <= cardinal s
250 lemma cardinal_product:
251 forall s1: set 'a, s2 : set 'b. is_finite s1 -> is_finite s2 ->
252 cardinal (product s1 s2) = cardinal s1 * cardinal s2
255 (** {2 Finite sets} *)
261 (** if `'a` is an infinite type, then `fset 'a` is infinite *)
262 meta "material_type_arg" type fset, 0
265 predicate mem (x: 'a) (s: fset 'a) (* = s.to_map[x] *)
268 predicate (==) (s1 s2: fset 'a) = forall x: 'a. mem x s1 <-> mem x s2
270 lemma extensionality:
271 forall s1 s2: fset 'a. s1 == s2 -> s1 = s2
274 predicate subset (s1 s2: fset 'a) = forall x : 'a. mem x s1 -> mem x s2
277 forall s: fset 'a. subset s s
280 forall s1 s2 s3: fset 'a. subset s1 s2 -> subset s2 s3 -> subset s1 s3
283 predicate is_empty (s: fset 'a) = forall x: 'a. not (mem x s)
285 constant empty: fset 'a
286 (* axiom empty_def: (empty: fset 'a).to_map = const false *)
288 axiom is_empty_empty: is_empty (empty: fset 'a)
290 lemma empty_is_empty:
291 forall s: fset 'a. is_empty s -> s = empty
294 function add (x: 'a) (s: fset 'a) : fset 'a
296 forall x: 'a, s: fset 'a, y: 'a. mem y (add x s) <-> (mem y s \/ y = x)
298 function singleton (x: 'a): fset 'a = add x empty
301 forall x, y: 'a. mem y (singleton x) -> y = x
304 function remove (x: 'a) (s: fset 'a) : fset 'a
306 forall x: 'a, s: fset 'a, y: 'a. mem y (remove x s) <-> (mem y s /\ y <> x)
309 forall x: 'a, s: fset 'a. mem x s -> add x (remove x s) = s
312 forall x: 'a, s: fset 'a. remove x (add x s) = remove x s
315 forall x: 'a, s: fset 'a. subset (remove x s) s
318 function union (s1 s2: fset 'a): fset 'a
320 forall s1 s2: fset 'a, x: 'a. mem x (union s1 s2) <-> mem x s1 \/ mem x s2
322 lemma subset_union_1:
323 forall s1 s2: fset 'a. subset s1 (union s1 s2)
324 lemma subset_union_2:
325 forall s1 s2: fset 'a. subset s2 (union s1 s2)
328 function inter (s1 s2: fset 'a): fset 'a
330 forall s1 s2: fset 'a, x: 'a. mem x (inter s1 s2) <-> mem x s1 /\ mem x s2
332 lemma subset_inter_1:
333 forall s1 s2: fset 'a. subset (inter s1 s2) s1
334 lemma subset_inter_2:
335 forall s1 s2: fset 'a. subset (inter s1 s2) s2
338 function diff (s1 s2: fset 'a): fset 'a
340 forall s1 s2: fset 'a, x: 'a. mem x (diff s1 s2) <-> mem x s1 /\ not (mem x s2)
343 forall s1 s2: fset 'a. subset (diff s1 s2) s1
345 (** arbitrary element *)
346 function pick (s: fset 'a): 'a
348 axiom pick_def: forall s: fset 'a. not (is_empty s) -> mem (pick s) s
351 predicate disjoint (s1 s2: fset 'a) =
352 forall x. not (mem x s1) \/ not (mem x s2)
354 lemma disjoint_inter_empty:
355 forall s1 s2: fset 'a. disjoint s1 s2 <-> is_empty (inter s1 s2)
357 lemma disjoint_diff_eq:
358 forall s1 s2: fset 'a. disjoint s1 s2 <-> diff s1 s2 = s1
360 lemma disjoint_diff_s2:
361 forall s1 s2: fset 'a. disjoint (diff s1 s2) s2
363 (** `{ x | x in s /\ p x }` *)
364 function filter (s: fset 'a) (p: 'a -> bool) : fset 'a
366 forall s: fset 'a, p: 'a -> bool, x: 'a. mem x (filter s p) <-> mem x s /\ p x
369 forall s: fset 'a, p: 'a -> bool. subset (filter s p) s
371 (** `{ f x | x in U }` *)
372 function map (f: 'a -> 'b) (u: fset 'a) : fset 'b
374 forall f: 'a -> 'b, u: fset 'a, y: 'b.
375 mem y (map f u) <-> exists x: 'a. mem x u /\ y = f x
378 forall f: 'a -> 'b, u: fset 'a.
379 forall x: 'a. mem x u -> mem (f x) (map f u)
385 function cardinal (fset 'a) : int
387 axiom cardinal_nonneg:
388 forall s: fset 'a. cardinal s >= 0
390 axiom cardinal_empty:
391 forall s: fset 'a. is_empty s <-> cardinal s = 0
394 forall x: 'a. forall s: fset 'a.
395 if mem x s then cardinal (add x s) = cardinal s
396 else cardinal (add x s) = cardinal s + 1
398 axiom cardinal_remove:
399 forall x: 'a. forall s: fset 'a.
400 if mem x s then cardinal (remove x s) = cardinal s - 1
401 else cardinal (remove x s) = cardinal s
403 axiom cardinal_subset:
404 forall s1 s2: fset 'a.
405 subset s1 s2 -> cardinal s1 <= cardinal s2
408 forall s1 s2: fset 'a.
409 subset s1 s2 -> cardinal s1 = cardinal s2 -> s1 = s2
412 forall s: fset 'a. cardinal s = 1 ->
413 forall x: 'a. mem x s -> x = pick s
415 axiom cardinal_union:
416 forall s1 s2: fset 'a.
417 cardinal (union s1 s2) = cardinal s1 + cardinal s2 - cardinal (inter s1 s2)
419 lemma cardinal_inter_disjoint:
420 forall s1 s2: fset 'a. disjoint s1 s2 -> cardinal (inter s1 s2) = 0
423 forall s1 s2: fset 'a.
424 cardinal (diff s1 s2) = cardinal s1 - cardinal (inter s1 s2)
426 lemma cardinal_filter:
427 forall s: fset 'a, p: 'a -> bool.
428 cardinal (filter s p) <= cardinal s
431 forall f: 'a -> 'b, s: fset 'a.
432 cardinal (map f s) <= cardinal s
436 (** {2 Induction principle on finite sets} *)
447 (forall s: fset t. is_empty s -> p s) ->
448 (forall s: fset t. p s -> forall t. p (add t s)) ->
449 forall s: fset t. p s
453 (** {2 Finite sets of integers} *)
460 function min_elt (s: fset int) : int
463 forall s: fset int. not (is_empty s) ->
464 mem (min_elt s) s /\ forall x. mem x s -> min_elt s <= x
466 function max_elt (s: fset int) : int
469 forall s: fset int. not (is_empty s) ->
470 mem (max_elt s) s /\ forall x. mem x s -> x <= max_elt s
472 function interval (l r: int) : fset int
474 forall l r x. mem x (interval l r) <-> l <= x < r
476 lemma cardinal_interval:
477 forall l r. cardinal (interval l r) = if l <= r then r - l else 0
481 (** {2 Sum of a function over a finite set} *)
488 function sum (fset 'a) ('a -> int) : int
489 (** `sum s f` is the sum `\sum_{mem x s} f x` *)
492 forall s: fset 'a, f. is_empty s -> sum s f = 0
495 forall s: fset 'a, f, x.
496 if mem x s then sum (add x s) f = sum s f
497 else sum (add x s) f = sum s f + f x
500 forall s: fset 'a, f, x.
501 if mem x s then sum (remove x s) f = sum s f - f x
502 else sum (remove x s) f = sum s f
505 forall s1 s2: fset 'a. forall f.
506 sum (union s1 s2) f = sum s1 f + sum s2 f - sum (inter s1 s2) f
509 forall s: fset 'a. forall f g.
510 (forall x. mem x s -> f x = g x) -> sum s f = sum s g
512 axiom cardinal_is_sum:
513 forall s: fset 'a. cardinal s = sum s (fun _ -> 1)
517 (** {2 Finite Monomorphic sets}
519 To be used in programs. *)
521 (** {3 Applicative sets} *)
530 val eq (x y: elt) : bool
531 ensures { result <-> x = y }
533 type set = abstract {
536 meta coercion function to_fset
538 val ghost function mk (s: fset elt) : set
539 ensures { result.to_fset = s }
541 val mem (x: elt) (s: set) : bool
542 ensures { result <-> mem x s }
544 val (==) (s1 s2: set) : bool
545 ensures { result <-> s1 == s2 }
547 val subset (s1 s2: set) : bool
548 ensures { result <-> subset s1 s2 }
551 ensures { result.to_fset = empty }
552 ensures { cardinal result = 0 }
554 val is_empty (s: set) : bool
555 ensures { result <-> is_empty s }
557 val add (x: elt) (s: set) : set
558 ensures { result = add x s }
559 ensures { if mem x s then cardinal result = cardinal s
560 else cardinal result = cardinal s + 1 }
562 let singleton (x: elt) : set
563 ensures { result = singleton x }
564 ensures { cardinal result = 1 }
567 val remove (x: elt) (s: set): set
568 ensures { result = remove x s }
569 ensures { if mem x s then cardinal result = cardinal s - 1
570 else cardinal result = cardinal s }
572 val union (s1 s2: set): set
573 ensures { result = union s1 s2 }
575 val inter (s1 s2: set) : set
576 ensures { result = inter s1 s2 }
578 val diff (s1 s2: set) : set
579 ensures { result = diff s1 s2 }
581 val function choose (s: set) : elt
582 requires { not (is_empty s) }
583 ensures { mem result s }
585 val disjoint (s1 s2: set) : bool
586 ensures { result <-> disjoint s1 s2 }
588 val cardinal (s: set) : int (* Peano.t *)
589 ensures { result = cardinal s }
593 (** {3 Applicative sets of integers} *)
600 clone export SetApp with type elt = int, val eq = Int.(=), axiom .
602 val min_elt (s: set) : int
603 requires { not (is_empty s) }
604 ensures { result = min_elt s }
606 val max_elt (s: set) : int
607 requires { not (is_empty s) }
608 ensures { result = max_elt s }
610 val interval (l r: int) : set
611 ensures { result = interval l r }
612 ensures { cardinal result = if l <= r then r - l else 0 }
616 (** {3 Imperative sets} *)
625 val eq (x y: elt) : bool
626 ensures { result <-> x = y }
628 type set = abstract {
629 mutable to_fset: fset elt;
631 meta coercion function to_fset
633 val mem (x: elt) (s: set) : bool
634 ensures { result <-> mem x s }
636 val (==) (s1 s2: set) : bool
637 ensures { result <-> s1 == s2 }
639 val subset (s1 s2: set) : bool
640 ensures { result <-> subset s1 s2 }
643 ensures { result = empty }
644 ensures { cardinal result = 0 }
646 val clear (s: set) : unit
648 ensures { s = empty }
650 val is_empty (s: set) : bool
651 ensures { result <-> is_empty s }
653 val add (x: elt) (s: set) : unit
655 ensures { s = add x (old s) }
656 ensures { if mem x (old s) then cardinal s = cardinal (old s)
657 else cardinal s = cardinal (old s) + 1 }
659 let singleton (x: elt) : set
660 ensures { result = singleton x }
661 ensures { cardinal result = 1 }
662 = let s = empty () in
666 val remove (x: elt) (s: set) : unit
668 ensures { s = remove x (old s) }
669 ensures { if mem x (old s) then cardinal s = cardinal (old s) - 1
670 else cardinal s = cardinal (old s) }
672 val function choose (s: set) : elt
673 requires { not (is_empty s) }
674 ensures { mem result s }
676 val choose_and_remove (s: set) : elt
677 requires { not (is_empty s) }
679 ensures { result = choose (old s) }
680 ensures { mem result (old s) }
681 ensures { s = remove result (old s) }
683 val disjoint (s1 s2: set) : bool
684 ensures { result <-> disjoint s1 s2 }
686 val cardinal (s: set) : int (* Peano.t? *)
687 ensures { result = cardinal s }
691 (** {3 Imperative sets of integers}
693 This module is mapped to OCaml's Hashtbl in the OCaml driver.
701 clone export SetImp with type elt = int, val eq = Int.(=), axiom .