Ltac dec := repeat (destruct Dec).Coercion dec2bool P (d: dec P) := if d then true else false.Definition Dec (X: Prop) (d: dec X) : dec X := d.Notation "'eq_dec' X" := (forall x y : X, dec (x=y)) (at level 70).Structure eqType := EqType {
  eqType_X :> Type;
  eqType_dec : eq_dec eqType_X }.Structure eqType := EqType {
  eqType_X :> Type;
  eqType_dec : eq_dec eqType_X }.Structure eqType := EqType {
  eqType_X :> Type;
  eqType_dec : eq_dec eqType_X }.Structure eqType := EqType {
  eqType_X :> Type;
  eqType_dec : eq_dec eqType_X }.Canonical Structure eqType_CS X (A: eq_dec X) := EqType X.Instance list_eq_dec X :
  eq_dec X -> eq_dec (list X).(** The definitions of finite types are adopted from the Bachelor Thesis of Jan Menz. (https://www.ps.uni-saarland.de/~menz/bachelor.php) *)

Fixpoint count (X: Type) `{eq_dec X}  (A: list  X) (x:  X) {struct A} : nat :=
  match A with
  | nil => O
  | cons y A' =>  if Dec (x=y) then S(count A' x) else count A' x end.Class finTypeC  (type:eqType) : Type := FinTypeC {
                                            enum: list type;
                                            enum_ok: forall x: type, count enum x = 1
                                          }.Class finTypeC  (type:eqType) : Type := FinTypeC {
                                            enum: list type;
                                            enum_ok: forall x: type, count enum x = 1
                                          }.Class finTypeC  (type:eqType) : Type := FinTypeC {
                                            enum: list type;
                                            enum_ok: forall x: type, count enum x = 1
                                          }.Class finTypeC  (type:eqType) : Type := FinTypeC {
                                            enum: list type;
                                            enum_ok: forall x: type, count enum x = 1
                                          }.Structure finType : Type := FinType {
                                type:> eqType;
                                class: finTypeC type }.Structure finType : Type := FinType {
                                type:> eqType;
                                class: finTypeC type }.Structure finType : Type := FinType {
                                type:> eqType;
                                class: finTypeC type }.Structure finType : Type := FinType {
                                type:> eqType;
                                class: finTypeC type }.Canonical Structure finType_CS (X : Type) {p : eq_dec X} {class : finTypeC (EqType X)} : finType := FinType (EqType X).Definition elem (F: finType) := @enum (type F) (class F).

(* Specifications: *)
Lemma countIn (X:eqType) (x:X) A: count A x > 0 -> x el A.
Lemma elem_spec (X: finType) (x:X) : x el (elem X).
Lemma countSplit (X: eqType) (A B: list X) (x: X) : count A x + count B x = count (A ++ B) x.