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.

(* Specifications: *)
Lemma sig_sig_iff_iff': forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a <-> Q a) x,
(sig_sig_iff H) (sig_sig_iff' H x) = x.
Lemma sig_sig_iff'_iff: forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a <-> Q a) x,
(sig_sig_iff' H) (sig_sig_iff H x) = x.
Lemma sig_sig_eq_eq': forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a = Q a) x,
(sig_sig_eq H) (sig_sig_eq' H x) = x.
Lemma sig_sig_eq'_eq: forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a = Q a) x,
(sig_sig_eq' H) (sig_sig_eq H x) = x.
Lemma sig_sigsig_sig: forall {A: Type} {P Q: A -> Prop} x,
@sig_sigsig A P Q (@sigsig_sig A P Q x) = 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.
Lemma sig_sig_iff_iff'_id: forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a <-> Q a),
(sig_sig_iff H) oo (sig_sig_iff' H) = id _.
Lemma bij_fg_sig: forall {A B} (f: bijection A B) (P: A -> Prop) x,
bij_f_sig f P (bij_g_sig f P x) = x.
Lemma bij_gf_sig: forall {A B} (f: bijection A B) (P: A -> Prop) x,
bij_g_sig f P (bij_f_sig f P x) = x.
Lemma sig_sig_iff'_iff_id: forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a <-> Q a),
(sig_sig_iff' H) oo (sig_sig_iff H) = id _.
Lemma sig_sig_eq_eq'_id: forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a = Q a),
(sig_sig_eq H) oo (sig_sig_eq' H) = id _.
Lemma sig_sig_eq'_eq_id: forall {A: Type} {P Q: A -> Prop}
(H: forall a, P a = Q a),
(sig_sig_eq' H) oo (sig_sig_eq H) = id _.
Lemma sig_sigsig_sig_id: forall {A: Type} {P Q: A -> Prop},
sig_sigsig oo (@sigsig_sig A P Q) = id _.
Lemma sigsig_sig_sigsig_id: forall {A: Type} {P Q: A -> Prop},
sigsig_sig oo (@sig_sigsig A P Q) = id _.
Lemma bij_fg_sig_id: forall {A B} (f: bijection A B) (P: A -> Prop),
(bij_f_sig f P) oo (bij_g_sig f P) = id _.
Lemma bij_gf_sig_id: forall {A B} (f: bijection A B) (P: A -> Prop),
(bij_g_sig f P) oo (bij_f_sig f P) = id _.