Require Export BasicDefinitions.
(** ** Formalisation of finite types using canonical structures and type classes *)
(** * Definition of finite Types *)
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
}.
Arguments FinType type {class}.
Existing Instance class | 0.
(* This is a hack to work-around a problem with a class of hacks *)
Hint Extern 5 (finTypeC (EqType ?x)) => unfold x : typeclass_instances.
Canonical Structure finType_CS (X : Type) {p : eq_dec X} {class : finTypeC (EqType X)} : finType := FinType (EqType X).
(** Print the base type of [finType] in the Canonical Structure. *)
Arguments finType_CS (X) {_ _}.
Definition elem (F: finType) := @enum (type F) (class F).
Hint Unfold elem.
Hint Unfold class.

Lemma elem_spec (X: finType) (x:X) : x el (elem X).