Fixpoint nth_member (ls : list T) (n : nat) {struct n}
  : option { x : T & member x ls } :=
    match ls as ls return option { x : T & member x ls } with
      | nil => None
      | l :: ls =>
        match n with
          | 0 => Some (@existT _ (fun x => member x (l :: ls)) l (MZ _ _))
          | S n =>
            match nth_member ls n with
              | Some (existT v m) => Some (@existT _ _ v (MN _ m))
              | None => None
            end
        end
    end.Definition get_next ls y x (m : member x (y :: ls))
  : option (member x ls) :=
    match m in member _ ls'
          return match ls' with
                   | nil => unit
                   | l' :: ls' => option (member x ls')
                 end
    with
      | MZ _ => None
      | MN _ _ m => Some m
    end.Instance Injective_MN x y ls m m' : Injective (@MN x y ls m = @MN x y ls m').

(* Specifications: *)
Lemma nth_member_nth_error : forall ls p, nth_member ls (to_nat (projT2 p)) = Some p <-> nth_error ls (to_nat (projT2 p)) = Some (projT1 p).
Lemma member_In : forall ls (t : T), member t ls -> List.In t ls.