Inductive pos : nat -> Set :=
  | pos_fst : forall n, pos (S n)
  | pos_nxt : forall n, pos n -> pos (S n).Inductive pos : nat -> Set :=
  | pos_fst : forall n, pos (S n)
  | pos_nxt : forall n, pos n -> pos (S n).Inductive pos : nat -> Set :=
  | pos_fst : forall n, pos (S n)
  | pos_nxt : forall n, pos n -> pos (S n).Notation pos0  := (@pos_fst _).Notation pos1  := (pos_nxt pos0).Notation pos2  := (pos_nxt pos1).Notation pos3  := (pos_nxt pos2).Notation pos4  := (pos_nxt pos3).Notation pos5  := (pos_nxt pos4).Notation pos6  := (pos_nxt pos5).Notation pos7  := (pos_nxt pos6).Notation pos8  := (pos_nxt pos7).Notation pos9  := (pos_nxt pos8).Notation pos10 := (pos_nxt pos9).Notation pos11 := (pos_nxt pos10).Notation pos12 := (pos_nxt pos11).Notation pos13 := (pos_nxt pos12).Notation pos14 := (pos_nxt pos13).Notation pos15 := (pos_nxt pos14).Notation pos16 := (pos_nxt pos15).Notation pos17 := (pos_nxt pos16).Notation pos18 := (pos_nxt pos17).Notation pos19 := (pos_nxt pos18).Notation pos20 := (pos_nxt pos19).Definition pos_iso n m : n = m -> pos n -> pos m.Ltac pos_O_inv p := exfalso; apply (pos_O_inv p).Ltac pos_S_inv p := 
  let H := fresh in
  let q := fresh
  in  rename p into q; destruct (pos_S_inv q) as [ H | (p & H) ]; subst q.Definition pos_nxt_inj n (p q : pos n) (H : pos_nxt p = pos_nxt q) : p = q :=
    match H in _ = a return 
       match a as a' in pos m return 
           match m with 
             | 0 => Prop 
             | S n' => pos n' -> Prop 
           end with
         | pos_fst   => fun _  => True 
         | pos_nxt y => fun x' => x' = y 
       end p with 
     | eq_refl => eq_refl
   end.

(* Specifications: *)
Theorem pos_O_invert X : pos 0 -> X.
Theorem pos_S_invert n P : P (@pos_fst n) -> (forall p, P (pos_nxt p)) -> forall p, P p.