Inductive FiniteT : Type -> Prop :=
  | empty_finite: FiniteT False
  | add_finite: forall T:Type, FiniteT T -> FiniteT (option T)
  | bij_finite: forall (X Y:Type) (f:X->Y), FiniteT X ->
    invertible f -> FiniteT Y.Inductive FiniteT : Type -> Prop :=
  | empty_finite: FiniteT False
  | add_finite: forall T:Type, FiniteT T -> FiniteT (option T)
  | bij_finite: forall (X Y:Type) (f:X->Y), FiniteT X ->
    invertible f -> FiniteT Y.Inductive FiniteT : Type -> Prop :=
  | empty_finite: FiniteT False
  | add_finite: forall T:Type, FiniteT T -> FiniteT (option T)
  | bij_finite: forall (X Y:Type) (f:X->Y), FiniteT X ->
    invertible f -> FiniteT Y.Inductive FiniteT : Type -> Prop :=
  | empty_finite: FiniteT False
  | add_finite: forall T:Type, FiniteT T -> FiniteT (option T)
  | bij_finite: forall (X Y:Type) (f:X->Y), FiniteT X ->
    invertible f -> FiniteT Y.

(* Specifications: *)
Lemma True_finite: FiniteT True.
Lemma finite_dec_exists: forall (X:Type) (P:X->Prop), FiniteT X -> (forall x:X, {P x} + {~ P x}) -> { exists x:X, P x } + { forall x:X, ~ P x }.
Lemma finite_dec_forall: forall (X:Type) (P:X->Prop), FiniteT X -> (forall x:X, { P x } + { ~ P x }) -> { forall x:X, P x } + { exists x:X, ~ P x }.
Lemma finite_eq_dec: forall X:Type, FiniteT X -> forall x y:X, {x=y} + {x<>y}.
Lemma finite_dep_choice: forall (A:Type) (B:forall x:A, Type) (R:forall x:A, B x->Prop), FiniteT A -> (forall x:A, exists y:B x, R x y) -> exists f:(forall x:A, B x), forall x:A, R x (f x).
Lemma finite_choice : forall (A B:Type) (R:A->B->Prop), FiniteT A -> (forall x:A, exists y:B, R x y) -> exists f:A->B, forall x:A, R x (f x).
Lemma Finite_ens_type: forall {X:Type} (S:Ensemble X), Finite _ S -> FiniteT { x:X | In S x }.
Lemma FiniteT_img: forall (X Y:Type) (f:X->Y), FiniteT X -> (forall y1 y2:Y, y1=y2 \/ y1<>y2) -> Finite _ (Im Full_set f).
Lemma surj_finite: forall (X Y:Type) (f:X->Y), FiniteT X -> surjective f -> (forall y1 y2:Y, y1=y2 \/ y1<>y2) -> FiniteT Y.
Lemma finite_subtype: forall (X:Type) (P:X->Prop), FiniteT X -> (forall x:X, P x \/ ~ P x) -> FiniteT {x:X | P x}.
Lemma inj_finite: forall (X Y:Type) (f:X->Y), FiniteT Y -> FunctionProperties.injective f -> (forall y:Y, (exists x:X, f x = y) \/ (~ exists x:X, f x = y)) -> FiniteT X.
Lemma finite_inj_surj: forall (X:Type) (f:X->X), FiniteT X -> injective f -> surjective f.
Lemma finite_surj_inj: forall (X:Type) (f:X->X), FiniteT X -> surjective f -> FunctionProperties.injective f.
Lemma finite_sum: forall X Y:Type, FiniteT X -> FiniteT Y -> FiniteT (X+Y).
Lemma finite_prod: forall (X Y:Type), FiniteT X -> FiniteT Y -> FiniteT (X*Y).
Lemma finite_exp: forall X Y:Type, FiniteT X -> FiniteT Y -> FiniteT (X->Y).
Lemma FiniteT_has_nat_cardinal: forall X:Type, FiniteT X -> exists! n:nat, cardinal _ (@Full_set X) n.