(** - 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.

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).