(** General definitions *)

Definition Injective {A B} (f : A->B) :=
 forall x y, f x = f y -> x = y.Definition Surjective {A B} (f : A->B) :=
 forall y, exists x, f x = y.Definition Bijective {A B} (f : A->B) :=
 exists g:B->A, (forall x, g (f x) = x) /\ (forall y, f (g y) = y).(** Finiteness is defined here via exhaustive list enumeration *)

Definition Full {A:Type} (l:list A) := forall a:A, In a l.Definition Finite (A:Type) := exists (l:list A), Full l.(** In many of the following proofs, it will be convenient to have
    list enumerations without duplicates. As soon as we have
    decidability of equality (in Prop), this is equivalent
    to the previous notion (s. lemma Finite_dec). *)

Definition Listing {A:Type} (l:list A) := NoDup l /\ Full l.Definition Finite' (A:Type) := exists (l:list A), Listing l.

(* Specifications: *)
Lemma Listing_decidable_eq {A:Type} (l:list A): Listing l -> decidable_eq A.
Lemma Finite_dec {A:Type}: Finite A /\ decidable_eq A <-> Finite' A.
Lemma Finite_alt_deprecated A (d:decidable_eq A) : Finite A <-> Finite' A.