lemma interSmallest<T>(x : set<T>, y : set<T>)
lemma unionCardBound(x : set<nat>, y : set<nat>, k : nat)
requires forall e :: e in x ==> e < k
requires forall e :: e in y ==> e < k
ensures forall e :: e in x + y ==> e < k
natSetCardBound(x + y, k);
lemma natSetCardBound(x : set<nat>, k : nat)
requires forall e :: e in x ==> e < k
natSetCardBound(x - { k - 1}, k - 1);
lemma {:induction k} successiveNatSetCardBound(x : set<nat>, k : nat)
requires x == set x: nat | 0 <= x < k :: x
successiveNatSetCardBound(x - {k - 1}, k - 1);
lemma cardIsMonotonic<T>(x : set<T>, y : set<T>)
cardIsMonotonic(if e in x then x - {e} else x, y');
lemma pigeonHolePrinciple<T>(x: set<T>, y : set<T>, z : set<T>)
requires |x| >= 2 * |z| / 3 + 1 // or equivalently 2 * |z| < 3 * |x|
requires |y| >= 2 * |z| / 3 + 1 // or equivalently 2 * |z| < 3 * |y|
ensures |x * y| >= |z| / 3 + 1 // or equivalently 3 * |x * y| < |z|
assert(|x| >= 2 * |z| / 3 + 1 <==> 2 * |z| < 3 * |x|);
assert(|y| >= 2 * |z| / 3 + 1 <==> 2 * |z| < 3 * |y|);
if |x * y| < |z| / 3 + 1 {
cardIsMonotonic(x + y, z);
assert(3 * |x * y| > |z| <==> |x * y| >= |z| / 3 + 1 );