(* 
Ltac pos_O_inv p := apply (@pos_O_invert _ p).
Ltac pos_S_inv x := induction x as [ | x ] using pos_S_invert.
*)

Ltac pos_inv p :=   
  match goal with
    | [ H: pos 0     |- _ ] => match H with p => pos_O_inv p end
    | [ H: pos (S _) |- _ ] => match H with p => pos_S_inv p end
  end.Ltac analyse_pos p := 
  match type of p with
    | pos 0     => pos_inv p
    | pos (S _) => pos_inv p; [ | try analyse_pos p ]
  end.Definition pos_O_any X : pos 0 -> X.Fixpoint pos_left n m (p : pos n) : pos (n+m) :=
  match p with
    | pos_fst   => pos_fst
    | pos_nxt p => pos_nxt (pos_left m p)
  end.Fixpoint pos_right n m : pos m -> pos (n+m) :=
  match n with 
    | 0   => fun x => x
    | S n => fun p => pos_nxt (pos_right n p)
  end.Definition pos_both n m : pos (n+m) -> pos n + pos m.Definition pos_lr n m : pos n + pos m -> pos (n+m).Fact pos_both_left n m p : @pos_both n m (@pos_left n m p) = inl p.Fact pos_both_right n m p : @pos_both n m (@pos_right n m p) = inr p.(** A bijection between pos n + pos m <-> pos (n+m) **)

Fact pos_both_lr n m p : @pos_both n m (pos_lr p) = p.Fact pos_lr_both n m p : pos_lr (@pos_both n m p) = p.

Theorem pos_left_right_rect : forall p, P p.