(** [member] is the proof relevant version of [In] **)
Set Implicit Arguments.
Set Strict Implicit.
Set Asymmetric Patterns.
Section member.
Context {T : Type}.
Inductive member (a : T) : list T -> Type :=
| MZ : forall ls, member a (a :: ls)
| MN : forall l ls, member a ls -> member a (l :: ls).
Section to_nat.
Variable a : T.
Fixpoint to_nat {ls} (m : member a ls) : nat :=
match m with
| MZ _ => 0
| MN _ _ m => S (to_nat m)
end.
End to_nat.

(* Specifications: *)
Lemma member_eta
: forall x ls (m : member x ls),
m = match m in member _ ls
return member x ls
with
| MZ ls => MZ x ls
| MN _ _ n => MN _ n
end.
Lemma member_case
: forall x ls (m : member x ls),
match ls as ls return member x ls -> Prop with
| nil => fun _ => False
| l :: ls' => fun m =>
(exists (pf : l = x),
m = match pf in _ = z return member z (l :: ls') with
| eq_refl => MZ _ ls'
end)
\/ exists m' : member x ls',
m = MN _ m'
end m.
Lemma to_nat_eq_member_eq
: forall {_ : EqDec T (@eq T)} x ls (a b : member x ls),
to_nat a = to_nat b ->
a = b.