Merge branch 'cleaning_again_example_sin_cos' into 'master'
[why3.git] / stdlib / set.mlw
blob70e8e039ea1d6c441629b933bcbac8ba3c59edcf
2 (** {1 Set theories}
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
13     provided when cloned
15     - `SetApp`, `SetAppInt`: immutable sets
16     - `SetImp`, `SetImpInt`: mutable sets
20 (** {2 Potentially infinite sets} *)
22 module Set
24   use map.Map
25   use map.Const
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
32   (** membership *)
33   predicate mem (x: 'a) (s: set 'a) = s[x]
35   (** equality *)
36   predicate (==) (s1 s2: set 'a) = forall x: 'a. mem x s1 <-> mem x s2
38   lemma extensionality:
39     forall s1 s2: set 'a. s1 == s2 -> s1 = s2
41   (** inclusion *)
42   predicate subset (s1 s2: set 'a) = forall x : 'a. mem x s1 -> mem x s2
44   lemma subset_refl:
45     forall s: set 'a. subset s s
47   lemma subset_trans:
48     forall s1 s2 s3: set 'a. subset s1 s2 -> subset s2 s3 -> subset s1 s3
50   (** empty set *)
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)
57   lemma empty_is_empty:
58     forall s: set 'a. is_empty s -> s = empty
60   (** whole set *)
61   let constant all: set 'a = const true
63   (** addition *)
64   function add (x: 'a) (s: set 'a): set 'a = s[x <- true]
66   function singleton (x: 'a): set 'a = add x empty
68   lemma mem_singleton:
69     forall x, y: 'a. mem y (singleton x) -> y = x
71   (** removal *)
72   function remove (x: 'a) (s: set 'a): set 'a = s[x <- false]
74   lemma add_remove:
75     forall x: 'a, s: set 'a. mem x s -> add x (remove x s) = s
77   lemma remove_add:
78     forall x: 'a, s: set 'a. remove x (add x s) = remove x s
80   lemma subset_remove:
81     forall x: 'a, s: set 'a. subset (remove x s) s
83   (** union *)
84   function union (s1 s2: set 'a): set 'a
85   = fun x -> mem x s1 \/ mem x s2
87   lemma subset_union_1:
88     forall s1 s2: set 'a. subset s1 (union s1 s2)
89   lemma subset_union_2:
90     forall s1 s2: set 'a. subset s2 (union s1 s2)
92   (** intersection *)
93   function inter (s1 s2: set 'a): set 'a
94   = fun x -> mem x s1 /\ mem x s2
96   lemma subset_inter_1:
97     forall s1 s2: set 'a. subset (inter s1 s2) s1
98   lemma subset_inter_2:
99     forall s1 s2: set 'a. subset (inter s1 s2) s2
101   (** difference *)
102   function diff (s1 s2: set 'a): set 'a
103   = fun x -> mem x s1 /\ not (mem x s2)
105   lemma subset_diff:
106     forall s1 s2: set 'a. subset (diff s1 s2) s1
108   (** complement *)
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
117   (** disjoint sets *)
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)
132   axiom product_def:
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
138   axiom filter_def:
139     forall s: set 'a, p: 'a -> bool, x: 'a. mem x (filter s p) <-> mem x s /\ p x
141   lemma subset_filter:
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
148   lemma mem_map:
149     forall f: 'a -> 'b, u: set 'a.
150     forall x: 'a. mem x u -> mem (f x) (map f u)
154 module Cardinal
156   use Set
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
166   axiom is_finite_add:
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)
194   lemma is_finite_map:
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 *)
203   use int.Int
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)
213   axiom cardinal_add:
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
227   lemma subset_eq:
228     forall s1 s2: set 'a. is_finite s2 ->
229     subset s1 s2 -> cardinal s1 = cardinal s2 -> s1 = s2
231   lemma cardinal1:
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
242   axiom cardinal_diff:
243     forall s1 s2: set 'a. is_finite s1 ->
244     cardinal (diff s1 s2) = cardinal s1 - cardinal (inter s1 s2)
246   lemma cardinal_map:
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} *)
257 module Fset
259   type fset 'a
261   (** if `'a` is an infinite type, then `fset 'a` is infinite *)
262   meta "material_type_arg" type fset, 0
264   (** membership *)
265   predicate mem (x: 'a) (s: fset 'a) (* = s.to_map[x] *)
267   (** equality *)
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
273   (** inclusion *)
274   predicate subset (s1 s2: fset 'a) = forall x : 'a. mem x s1 -> mem x s2
276   lemma subset_refl:
277     forall s: fset 'a. subset s s
279   lemma subset_trans:
280     forall s1 s2 s3: fset 'a. subset s1 s2 -> subset s2 s3 -> subset s1 s3
282   (** empty set *)
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
293   (** addition *)
294   function add (x: 'a) (s: fset 'a) : fset 'a
295   axiom add_def:
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
300   lemma mem_singleton:
301     forall x, y: 'a. mem y (singleton x) -> y = x
303   (** removal *)
304   function remove (x: 'a) (s: fset 'a) : fset 'a
305   axiom remove_def:
306     forall x: 'a, s: fset 'a, y: 'a. mem y (remove x s) <-> (mem y s /\ y <> x)
308   lemma add_remove:
309     forall x: 'a, s: fset 'a. mem x s -> add x (remove x s) = s
311   lemma remove_add:
312     forall x: 'a, s: fset 'a. remove x (add x s) = remove x s
314   lemma subset_remove:
315     forall x: 'a, s: fset 'a. subset (remove x s) s
317   (** union *)
318   function union (s1 s2: fset 'a): fset 'a
319   axiom union_def:
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)
327   (** intersection *)
328   function inter (s1 s2: fset 'a): fset 'a
329   axiom inter_def:
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
337   (** difference *)
338   function diff (s1 s2: fset 'a): fset 'a
339   axiom diff_def:
340     forall s1 s2: fset 'a, x: 'a. mem x (diff s1 s2) <-> mem x s1 /\ not (mem x s2)
342   lemma subset_diff:
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
350   (** disjoint sets *)
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
365   axiom filter_def:
366     forall s: fset 'a, p: 'a -> bool, x: 'a. mem x (filter s p) <-> mem x s /\ p x
368   lemma subset_filter:
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
373   axiom map_def:
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
377   lemma mem_map:
378     forall f: 'a -> 'b, u: fset 'a.
379     forall x: 'a. mem x u -> mem (f x) (map f u)
381   (** cardinal *)
383   use int.Int
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
393   axiom cardinal_add:
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
407   lemma subset_eq:
408     forall s1 s2: fset 'a.
409     subset s1 s2 -> cardinal s1 = cardinal s2 -> s1 = s2
411   lemma cardinal1:
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
422   axiom cardinal_diff:
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
430   lemma cardinal_map:
431     forall f: 'a -> 'b, s: fset 'a.
432     cardinal (map f s) <= cardinal s
436 (** {2 Induction principle on finite sets} *)
438 module FsetInduction
440   use Fset
442   type t
444   predicate p (fset t)
446   lemma Induction:
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} *)
455 module FsetInt
457   use int.Int
458   use export Fset
460   function min_elt (s: fset int) : int
462   axiom min_elt_def:
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
468   axiom max_elt_def:
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
473   axiom interval_def:
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} *)
483 module FsetSum
485   use int.Int
486   use Fset
488   function sum (fset 'a) ('a -> int) : int
489   (** `sum s f` is the sum `\sum_{mem x s} f x` *)
491   axiom sum_def_empty:
492     forall s: fset 'a, f. is_empty s -> sum s f = 0
494   axiom sum_add:
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
499   axiom sum_remove:
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
504   lemma sum_union:
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
508   lemma sum_eq:
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} *)
523 module SetApp
525   use int.Int
526   use export Fset
528   type elt
530   val eq (x y: elt) : bool
531     ensures { result <-> x = y }
533   type set = abstract {
534     to_fset: fset elt;
535   }
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 }
550   val empty () : set
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 }
565   = add x (empty ())
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} *)
595 module SetAppInt
597   use int.Int
598   use export FsetInt
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} *)
618 module SetImp
620   use int.Int
621   use export Fset
623   type elt
625   val eq (x y: elt) : bool
626     ensures { result <-> x = y }
628   type set = abstract {
629     mutable to_fset: fset elt;
630   }
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 }
642   val empty () : set
643     ensures { result = empty }
644     ensures { cardinal result = 0 }
646   val clear (s: set) : unit
647     writes  { s }
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
654     writes  { s }
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
663     add x s;
664     s
666   val remove (x: elt) (s: set) : unit
667     writes  { s }
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) }
678     writes   { 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.
696 module SetImpInt
698   use int.Int
699   use export FsetInt
701   clone export SetImp with type elt = int, val eq = Int.(=), axiom .