Program Definition sig_sig_iff {A: Type} {P Q: A -> Prop}
(H: forall a, P a <-> Q a) (x: sig P): sig Q := x.
Next Obligation.
rewrite <- H; auto.
Defined.
Program Definition sig_sig_iff' {A: Type} {P Q: A -> Prop}
(H: forall a, P a <-> Q a) (x: sig Q): sig P := x.
Next Obligation.
rewrite H; auto.
Defined.
Program Definition sig_sig_eq {A: Type} {P Q: A -> Prop}
(H: forall a, P a = Q a) (x: sig P): sig Q := x.
Next Obligation.
rewrite <- H; auto.
Defined.
Program Definition sig_sig_eq' {A: Type} {P Q: A -> Prop}
(H: forall a, P a = Q a) (x: sig Q): sig P := x.
Next Obligation.
rewrite H; auto.
Defined.
Program Definition sigsig_sig {A: Type} {P Q: A -> Prop}
(x: sig (fun x: sig P => Q (proj1_sig x))): sig (fun x => P x /\ Q x) := x.
Program Definition sig_sigsig {A: Type} {P Q: A -> Prop}
(x: sig (fun x => P x /\ Q x)): sig (fun x: sig P => Q (proj1_sig x)) := x.
Program Definition bij_f_sig {A B} (f: bijection A B) (P: A -> Prop)
(x: sig P): sig (fun b => P (bij_g _ _ f b)) := bij_f _ _ f x.
Next Obligation.
rewrite bij_gf; auto.
Defined.
Program Definition bij_g_sig {A B} (f: bijection A B) (P: A -> Prop)
(x: sig (fun b => P (bij_g _ _ f b))): sig P := bij_g _ _ f x.

Lemma sigsig_sig_sigsig: forall {A: Type} {P Q: A -> Prop} x,
@sigsig_sig A P Q (@sig_sigsig A P Q x) = x.