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]
35 use map.MapExt (* this imports extensionality for sets *)
38 predicate (==) (s1 s2: set 'a) = forall x: 'a. mem x s1 <-> mem x s2
41 forall s1 s2: set 'a. s1 == s2 -> s1 = s2
43 meta extensionality predicate (==)
47 predicate subset (s1 s2: set 'a) = forall x : 'a. mem x s1 -> mem x s2
50 forall s: set 'a. subset s s
53 forall s1 s2 s3: set 'a. subset s1 s2 -> subset s2 s3 -> subset s1 s3
56 predicate is_empty (s: set 'a) = forall x: 'a. not (mem x s)
58 let constant empty: set 'a = const false
60 lemma is_empty_empty: is_empty (empty: set 'a)
63 forall s: set 'a. is_empty s -> s = empty
66 let constant all: set 'a = const true
69 function add (x: 'a) (s: set 'a): set 'a = s[x <- true]
71 function singleton (x: 'a): set 'a = add x empty
74 forall x, y: 'a. mem y (singleton x) -> y = x
77 function remove (x: 'a) (s: set 'a): set 'a = s[x <- false]
80 forall x: 'a, s: set 'a. mem x s -> add x (remove x s) = s
83 forall x: 'a, s: set 'a. remove x (add x s) = remove x s
86 forall x: 'a, s: set 'a. subset (remove x s) s
89 function union (s1 s2: set 'a): set 'a
90 = fun x -> mem x s1 \/ mem x s2
93 forall s1 s2: set 'a. subset s1 (union s1 s2)
95 forall s1 s2: set 'a. subset s2 (union s1 s2)
98 function inter (s1 s2: set 'a): set 'a
99 = fun x -> mem x s1 /\ mem x s2
101 lemma subset_inter_1:
102 forall s1 s2: set 'a. subset (inter s1 s2) s1
103 lemma subset_inter_2:
104 forall s1 s2: set 'a. subset (inter s1 s2) s2
107 function diff (s1 s2: set 'a): set 'a
108 = fun x -> mem x s1 /\ not (mem x s2)
111 forall s1 s2: set 'a. subset (diff s1 s2) s1
114 function complement (s: set 'a): set 'a
115 = fun x -> not (mem x s)
117 (** arbitrary element *)
118 function pick (s: set 'a): 'a
120 axiom pick_def: forall s: set 'a. not (is_empty s) -> mem (pick s) s
123 predicate disjoint (s1 s2: set 'a) =
124 forall x. not (mem x s1) \/ not (mem x s2)
126 lemma disjoint_inter_empty:
127 forall s1 s2: set 'a. disjoint s1 s2 <-> is_empty (inter s1 s2)
129 lemma disjoint_diff_eq:
130 forall s1 s2: set 'a. disjoint s1 s2 <-> diff s1 s2 = s1
132 lemma disjoint_diff_s2:
133 forall s1 s2: set 'a. disjoint (diff s1 s2) s2
135 (** `{ (x, y) | x in s1 /\ y in s2 }` *)
136 function product (s1: set 'a) (s2: set 'b) : set ('a, 'b)
138 forall s1: set 'a, s2: set 'b, x : 'a, y : 'b.
139 mem (x, y) (product s1 s2) <-> mem x s1 /\ mem y s2
141 (** `{ x | x in s /\ p x }` *)
142 function filter (s: set 'a) (p: 'a -> bool) : set 'a
144 forall s: set 'a, p: 'a -> bool, x: 'a. mem x (filter s p) <-> mem x s /\ p x
147 forall s: set 'a, p: 'a -> bool. subset (filter s p) s
149 (** `{ f x | x in U }` *)
150 function map (f: 'a -> 'b) (u: set 'a) : set 'b =
151 fun (y: 'b) -> exists x: 'a. mem x u /\ y = f x
154 forall f: 'a -> 'b, u: set 'a.
155 forall x: 'a. mem x u -> mem (f x) (map f u)
163 predicate is_finite (s: set 'a)
165 axiom is_finite_empty:
166 forall s: set 'a. is_empty s -> is_finite s
168 axiom is_finite_subset:
169 forall s1 s2: set 'a. is_finite s2 -> subset s1 s2 -> is_finite s1
172 forall x: 'a, s: set 'a. is_finite s -> is_finite (add x s)
173 axiom is_finite_add_rev:
174 forall x: 'a, s: set 'a. is_finite (add x s) -> is_finite s
176 lemma is_finite_singleton:
177 forall x: 'a. is_finite (singleton x)
179 axiom is_finite_remove:
180 forall x: 'a, s: set 'a. is_finite s -> is_finite (remove x s)
181 axiom is_finite_remove_rev:
182 forall x: 'a, s: set 'a. is_finite (remove x s) -> is_finite s
184 axiom is_finite_union:
185 forall s1 s2: set 'a.
186 is_finite s1 -> is_finite s2 -> is_finite (union s1 s2)
187 axiom is_finite_union_rev:
188 forall s1 s2: set 'a.
189 is_finite (union s1 s2) -> is_finite s1 /\ is_finite s2
191 axiom is_finite_inter_left:
192 forall s1 s2: set 'a. is_finite s1 -> is_finite (inter s1 s2)
193 axiom is_finite_inter_right:
194 forall s1 s2: set 'a. is_finite s2 -> is_finite (inter s1 s2)
196 axiom is_finite_diff:
197 forall s1 s2: set 'a. is_finite s1 -> is_finite (diff s1 s2)
200 forall f: 'a -> 'b, s: set 'a. is_finite s -> is_finite (map f s)
202 lemma is_finite_product:
203 forall s1: set 'a, s2 : set 'b. is_finite s1 -> is_finite s2 ->
204 is_finite (product s1 s2)
206 (** `cardinal` function *)
210 function cardinal (set 'a): int
212 axiom cardinal_nonneg:
213 forall s: set 'a. cardinal s >= 0
215 axiom cardinal_empty:
216 forall s: set 'a. is_finite s -> (is_empty s <-> cardinal s = 0)
219 forall x: 'a. forall s: set 'a. is_finite s ->
220 if mem x s then cardinal (add x s) = cardinal s
221 else cardinal (add x s) = cardinal s + 1
223 axiom cardinal_remove:
224 forall x: 'a. forall s: set 'a. is_finite s ->
225 if mem x s then cardinal (remove x s) = cardinal s - 1
226 else cardinal (remove x s) = cardinal s
228 axiom cardinal_subset:
229 forall s1 s2: set 'a. is_finite s2 ->
230 subset s1 s2 -> cardinal s1 <= cardinal s2
233 forall s1 s2: set 'a. is_finite s2 ->
234 subset s1 s2 -> cardinal s1 = cardinal s2 -> s1 = s2
237 forall s: set 'a. cardinal s = 1 ->
238 forall x: 'a. mem x s -> x = pick s
240 axiom cardinal_union:
241 forall s1 s2: set 'a. is_finite s1 -> is_finite s2 ->
242 cardinal (union s1 s2) = cardinal s1 + cardinal s2 - cardinal (inter s1 s2)
244 lemma cardinal_inter_disjoint:
245 forall s1 s2: set 'a. disjoint s1 s2 -> cardinal (inter s1 s2) = 0
248 forall s1 s2: set 'a. is_finite s1 ->
249 cardinal (diff s1 s2) = cardinal s1 - cardinal (inter s1 s2)
252 forall f: 'a -> 'b, s: set 'a. is_finite s ->
253 cardinal (map f s) <= cardinal s
255 lemma cardinal_product:
256 forall s1: set 'a, s2 : set 'b. is_finite s1 -> is_finite s2 ->
257 cardinal (product s1 s2) = cardinal s1 * cardinal s2
260 (** {2 Finite sets} *)
266 (** if `'a` is an infinite type, then `fset 'a` is infinite *)
267 meta "material_type_arg" type fset, 0
270 predicate mem (x: 'a) (s: fset 'a) (* = s.to_map[x] *)
273 predicate (==) (s1 s2: fset 'a) = forall x: 'a. mem x s1 <-> mem x s2
275 lemma extensionality:
276 forall s1 s2: fset 'a. s1 == s2 -> s1 = s2
278 meta extensionality predicate (==)
281 predicate subset (s1 s2: fset 'a) = forall x : 'a. mem x s1 -> mem x s2
284 forall s: fset 'a. subset s s
287 forall s1 s2 s3: fset 'a. subset s1 s2 -> subset s2 s3 -> subset s1 s3
290 predicate is_empty (s: fset 'a) = forall x: 'a. not (mem x s)
292 constant empty: fset 'a
293 (* axiom empty_def: (empty: fset 'a).to_map = const false *)
295 axiom is_empty_empty: is_empty (empty: fset 'a)
297 lemma empty_is_empty:
298 forall s: fset 'a. is_empty s -> s = empty
301 function add (x: 'a) (s: fset 'a) : fset 'a
303 forall x: 'a, s: fset 'a, y: 'a. mem y (add x s) <-> (mem y s \/ y = x)
305 function singleton (x: 'a): fset 'a = add x empty
308 forall x, y: 'a. mem y (singleton x) -> y = x
311 function remove (x: 'a) (s: fset 'a) : fset 'a
313 forall x: 'a, s: fset 'a, y: 'a. mem y (remove x s) <-> (mem y s /\ y <> x)
316 forall x: 'a, s: fset 'a. mem x s -> add x (remove x s) = s
319 forall x: 'a, s: fset 'a. remove x (add x s) = remove x s
322 forall x: 'a, s: fset 'a. subset (remove x s) s
325 function union (s1 s2: fset 'a): fset 'a
327 forall s1 s2: fset 'a, x: 'a. mem x (union s1 s2) <-> mem x s1 \/ mem x s2
329 lemma subset_union_1:
330 forall s1 s2: fset 'a. subset s1 (union s1 s2)
331 lemma subset_union_2:
332 forall s1 s2: fset 'a. subset s2 (union s1 s2)
335 function inter (s1 s2: fset 'a): fset 'a
337 forall s1 s2: fset 'a, x: 'a. mem x (inter s1 s2) <-> mem x s1 /\ mem x s2
339 lemma subset_inter_1:
340 forall s1 s2: fset 'a. subset (inter s1 s2) s1
341 lemma subset_inter_2:
342 forall s1 s2: fset 'a. subset (inter s1 s2) s2
345 function diff (s1 s2: fset 'a): fset 'a
347 forall s1 s2: fset 'a, x: 'a. mem x (diff s1 s2) <-> mem x s1 /\ not (mem x s2)
350 forall s1 s2: fset 'a. subset (diff s1 s2) s1
352 (** arbitrary element *)
353 function pick (s: fset 'a): 'a
355 axiom pick_def: forall s: fset 'a. not (is_empty s) -> mem (pick s) s
358 predicate disjoint (s1 s2: fset 'a) =
359 forall x. not (mem x s1) \/ not (mem x s2)
361 lemma disjoint_inter_empty:
362 forall s1 s2: fset 'a. disjoint s1 s2 <-> is_empty (inter s1 s2)
364 lemma disjoint_diff_eq:
365 forall s1 s2: fset 'a. disjoint s1 s2 <-> diff s1 s2 = s1
367 lemma disjoint_diff_s2:
368 forall s1 s2: fset 'a. disjoint (diff s1 s2) s2
370 (** `{ x | x in s /\ p x }` *)
371 function filter (s: fset 'a) (p: 'a -> bool) : fset 'a
373 forall s: fset 'a, p: 'a -> bool, x: 'a. mem x (filter s p) <-> mem x s /\ p x
376 forall s: fset 'a, p: 'a -> bool. subset (filter s p) s
378 (** `{ f x | x in U }` *)
379 function map (f: 'a -> 'b) (u: fset 'a) : fset 'b
381 forall f: 'a -> 'b, u: fset 'a, y: 'b.
382 mem y (map f u) <-> exists x: 'a. mem x u /\ y = f x
385 forall f: 'a -> 'b, u: fset 'a.
386 forall x: 'a. mem x u -> mem (f x) (map f u)
392 function cardinal (fset 'a) : int
394 axiom cardinal_nonneg:
395 forall s: fset 'a. cardinal s >= 0
397 axiom cardinal_empty:
398 forall s: fset 'a. is_empty s <-> cardinal s = 0
401 forall x: 'a. forall s: fset 'a.
402 if mem x s then cardinal (add x s) = cardinal s
403 else cardinal (add x s) = cardinal s + 1
405 axiom cardinal_remove:
406 forall x: 'a. forall s: fset 'a.
407 if mem x s then cardinal (remove x s) = cardinal s - 1
408 else cardinal (remove x s) = cardinal s
410 axiom cardinal_subset:
411 forall s1 s2: fset 'a.
412 subset s1 s2 -> cardinal s1 <= cardinal s2
415 forall s1 s2: fset 'a.
416 subset s1 s2 -> cardinal s1 = cardinal s2 -> s1 = s2
419 forall s: fset 'a. cardinal s = 1 ->
420 forall x: 'a. mem x s -> x = pick s
422 axiom cardinal_union:
423 forall s1 s2: fset 'a.
424 cardinal (union s1 s2) = cardinal s1 + cardinal s2 - cardinal (inter s1 s2)
426 lemma cardinal_inter_disjoint:
427 forall s1 s2: fset 'a. disjoint s1 s2 -> cardinal (inter s1 s2) = 0
430 forall s1 s2: fset 'a.
431 cardinal (diff s1 s2) = cardinal s1 - cardinal (inter s1 s2)
433 lemma cardinal_filter:
434 forall s: fset 'a, p: 'a -> bool.
435 cardinal (filter s p) <= cardinal s
438 forall f: 'a -> 'b, s: fset 'a.
439 cardinal (map f s) <= cardinal s
443 (** {2 Induction principle on finite sets} *)
454 (forall s: fset t. is_empty s -> p s) ->
455 (forall s: fset t. p s -> forall t. p (add t s)) ->
456 forall s: fset t. p s
460 (** {2 Finite sets of integers} *)
467 function min_elt (s: fset int) : int
470 forall s: fset int. not (is_empty s) ->
471 mem (min_elt s) s /\ forall x. mem x s -> min_elt s <= x
473 function max_elt (s: fset int) : int
476 forall s: fset int. not (is_empty s) ->
477 mem (max_elt s) s /\ forall x. mem x s -> x <= max_elt s
479 function interval (l r: int) : fset int
481 forall l r x. mem x (interval l r) <-> l <= x < r
483 lemma cardinal_interval:
484 forall l r. cardinal (interval l r) = if l <= r then r - l else 0
488 (** {2 Sum of a function over a finite set} *)
495 function sum (fset 'a) ('a -> int) : int
496 (** `sum s f` is the sum `\sum_{mem x s} f x` *)
499 forall s: fset 'a, f. is_empty s -> sum s f = 0
502 forall s: fset 'a, f, x.
503 if mem x s then sum (add x s) f = sum s f
504 else sum (add x s) f = sum s f + f x
507 forall s: fset 'a, f, x.
508 if mem x s then sum (remove x s) f = sum s f - f x
509 else sum (remove x s) f = sum s f
512 forall s1 s2: fset 'a. forall f.
513 sum (union s1 s2) f = sum s1 f + sum s2 f - sum (inter s1 s2) f
516 forall s: fset 'a. forall f g.
517 (forall x. mem x s -> f x = g x) -> sum s f = sum s g
519 axiom cardinal_is_sum:
520 forall s: fset 'a. cardinal s = sum s (fun _ -> 1)
524 (** {2 Finite Monomorphic sets}
526 To be used in programs. *)
528 (** {3 Applicative sets} *)
537 val eq (x y: elt) : bool
538 ensures { result <-> x = y }
540 type set = abstract {
543 meta coercion function to_fset
545 val ghost function mk (s: fset elt) : set
546 ensures { result.to_fset = s }
548 val mem (x: elt) (s: set) : bool
549 ensures { result <-> mem x s }
551 val (==) (s1 s2: set) : bool
552 ensures { result <-> s1 == s2 }
554 val subset (s1 s2: set) : bool
555 ensures { result <-> subset s1 s2 }
558 ensures { result.to_fset = empty }
559 ensures { cardinal result = 0 }
561 val is_empty (s: set) : bool
562 ensures { result <-> is_empty s }
564 val add (x: elt) (s: set) : set
565 ensures { result = add x s }
566 ensures { if mem x s then cardinal result = cardinal s
567 else cardinal result = cardinal s + 1 }
569 let singleton (x: elt) : set
570 ensures { result = singleton x }
571 ensures { cardinal result = 1 }
574 val remove (x: elt) (s: set): set
575 ensures { result = remove x s }
576 ensures { if mem x s then cardinal result = cardinal s - 1
577 else cardinal result = cardinal s }
579 val union (s1 s2: set): set
580 ensures { result = union s1 s2 }
582 val inter (s1 s2: set) : set
583 ensures { result = inter s1 s2 }
585 val diff (s1 s2: set) : set
586 ensures { result = diff s1 s2 }
588 val function choose (s: set) : elt
589 requires { not (is_empty s) }
590 ensures { mem result s }
592 val disjoint (s1 s2: set) : bool
593 ensures { result <-> disjoint s1 s2 }
595 val cardinal (s: set) : int (* Peano.t *)
596 ensures { result = cardinal s }
600 (** {3 Applicative sets of integers} *)
607 clone export SetApp with type elt = int, val eq = Int.(=), axiom .
609 val min_elt (s: set) : int
610 requires { not (is_empty s) }
611 ensures { result = min_elt s }
613 val max_elt (s: set) : int
614 requires { not (is_empty s) }
615 ensures { result = max_elt s }
617 val interval (l r: int) : set
618 ensures { result = interval l r }
619 ensures { cardinal result = if l <= r then r - l else 0 }
623 (** {3 Imperative sets} *)
632 val eq (x y: elt) : bool
633 ensures { result <-> x = y }
635 type set = abstract {
636 mutable to_fset: fset elt;
638 meta coercion function to_fset
640 val mem (x: elt) (s: set) : bool
641 ensures { result <-> mem x s }
643 val (==) (s1 s2: set) : bool
644 ensures { result <-> s1 == s2 }
646 val subset (s1 s2: set) : bool
647 ensures { result <-> subset s1 s2 }
650 ensures { result = empty }
651 ensures { cardinal result = 0 }
653 val clear (s: set) : unit
655 ensures { s = empty }
657 val is_empty (s: set) : bool
658 ensures { result <-> is_empty s }
660 val add (x: elt) (s: set) : unit
662 ensures { s = add x (old s) }
663 ensures { if mem x (old s) then cardinal s = cardinal (old s)
664 else cardinal s = cardinal (old s) + 1 }
666 let singleton (x: elt) : set
667 ensures { result = singleton x }
668 ensures { cardinal result = 1 }
669 = let s = empty () in
673 val remove (x: elt) (s: set) : unit
675 ensures { s = remove x (old s) }
676 ensures { if mem x (old s) then cardinal s = cardinal (old s) - 1
677 else cardinal s = cardinal (old s) }
679 val function choose (s: set) : elt
680 requires { not (is_empty s) }
681 ensures { mem result s }
683 val choose_and_remove (s: set) : elt
684 requires { not (is_empty s) }
686 ensures { result = choose (old s) }
687 ensures { mem result (old s) }
688 ensures { s = remove result (old s) }
690 val disjoint (s1 s2: set) : bool
691 ensures { result <-> disjoint s1 s2 }
693 val cardinal (s: set) : int (* Peano.t? *)
694 ensures { result = cardinal s }
698 (** {3 Imperative sets of integers}
700 This module is mapped to OCaml's Hashtbl in the OCaml driver.
708 clone export SetImp with type elt = int, val eq = Int.(=), axiom .