(** - Once we have has_n_elements, it would seem to be easy to define
 has_at_least_n_elements and has_at_most_n_elements. But one has to take a little
 care. We could not just say, e.g. [
 
Definition has_at_least_n_elements := ]
[    [n:nat;A:Setoid](EXT m:nat | (le n m) /\ (has_n_elements m A)).

 ] since the set may be infinite, and then there is no such m to be found.

 - But we may adapt the definition of has_n_elements slightly. It said that we can
 make a sequence [v] of length [n] with all elements distinct---[(distinct v)];
 covering the whole set---[(seq_set v)='(full v)]. Now we just drop this last
 requirement so we only need to point out a sequence of $n$ different elements:

 %\label{hasatleastnelements}% *)

Definition has_at_least_n_elements (n : Nat) (A : Setoid) :=
  exists v : seq n A, distinct v.(** - Note that, contrarily, we may not just drop the other requirement to obtain 

[Definition has_at_most_n_elements_wrong := 
    [n:nat;A:Setoid](EXT v:(seq n A) | (full A)='(seq_set v)).]

 since this doesn't work out well for empty sets: it has at most n elements for any n,
 but with this definition we'd need to exhibit an n-length sequence, which we can't do
 for $n>0$.*)

Definition has_at_most_n_elements (n : Nat) (A : Setoid) :=
  exists m : nat, m <= n /\ has_n_elements m A.

(* Specifications: *)
Lemma has_n_elements_then_has_at_least_n_elements : forall (A : Setoid) (n : Nat), has_n_elements n A -> has_at_least_n_elements n A.
Lemma has_n_elements_then_has_at_most_n_elements : forall (A : Setoid) (n : Nat), has_n_elements n A -> forall m : Nat, n <= m -> has_at_most_n_elements m A.
Lemma subset_has_at_least_n_elements : forall (A : Setoid) (n : Nat) (B : part_set A), has_at_least_n_elements n B -> has_at_least_n_elements n A.
Lemma subset_bounds_set_size_from_below : forall (A : Setoid) (B : part_set A) (n : Nat), has_n_elements n B -> has_at_least_n_elements n A.
Lemma has_extra_element_strong : forall (A : Setoid) (B C : part_set A) (m n : Nat), has_at_least_n_elements n B -> has_n_elements m C -> m < n -> exists a : A, in_part a B /\ ~ in_part a C.
Lemma not_at_least_then_at_most : forall (A : Setoid) (n : Nat), ~ has_at_least_n_elements (S n) A -> has_at_most_n_elements n A.
Lemma has_n_elements_by_at_least_at_most : forall (A : Setoid) (n : Nat), has_at_least_n_elements n A -> has_at_most_n_elements n A -> has_n_elements n A.
Lemma inclusion_bounds_elements_from_below : forall (A : Setoid) (B C : part_set A) (n : Nat), has_n_elements n B -> included B C -> has_at_least_n_elements n C.
Lemma has_n_elements_doesn't_have_more : forall (A : Setoid) (n : Nat), has_n_elements n A -> forall m : Nat, n < m -> ~ has_at_least_n_elements m A.
Lemma union_has_at_most_n_plus_m_elements : forall (A : Setoid) (B C : part_set A) (n m : Nat), has_n_elements n B -> has_n_elements m C -> has_at_most_n_elements (n + m) (union B C).