2 (** Pigeonhole principle (also know as Dirichlet's drawer principle)
4 Proved using a lemma function. *)
8 use int.Int, set.Fset, ref.Ref
10 let rec ghost below (n: int) : fset int
12 ensures { forall i. mem i result <-> 0 <= i < n }
13 ensures { cardinal result = n }
15 = if n = 0 then empty else add (n-1) (below (n-1))
17 let lemma pigeonhole (n m: int) (f: int -> int)
18 requires { 0 <= m < n }
19 requires { forall i. 0 <= i < n -> 0 <= f i < m }
20 ensures { exists i1, i2. 0 <= i1 < i2 < n /\ f i1 = f i2 }
24 invariant { cardinal !s = i }
25 invariant { forall x. mem x !s <-> (exists j. 0 <= j < i /\ x = f j) }
26 if mem (f i) !s then return;
29 let b = below m in assert { subset !s b };