Set Implicit Arguments.
Fixpoint fin (n : nat) : Type :=
match n with
| 0 => False
| S n' => option (fin n')
end.
Fixpoint fin_eq_dec (n : nat) : forall (a b : fin n), {a = b} + {a <> b}.
refine
(match n with
| 0 => fun a b : fin 0 => right (match b with end)
| S n' => fun a b : fin (S n') =>
match a, b with
| Some a', Some b' =>
match fin_eq_dec n' a' b' with
| left _ _ => left _
| right _ _ => right _
end
| Some a', None => right _
| None, Some b' => right _
| None, None => left eq_refl
end
end); congruence.
Defined.
Fixpoint all_fin (n : nat) : list (fin n) :=
match n with
| 0 => []
| S n' => None :: map (fun x => Some x) (all_fin n')
end.

(* Specifications: *)
Lemma all_fin_all :
forall n (x : fin n),
In x (all_fin n).
Lemma all_fin_NoDup :
forall n, NoDup (all_fin n).