Module Export Equivalences.
Generalizable Variables A B C f g.
Global Instance isequiv_idmap (A : Type) : IsEquiv idmap | 0 :=
BuildIsEquiv A A idmap idmap (fun _ => 1) (fun _ => 1) (fun _ => 1).
Definition equiv_idmap (A : Type) : A <~> A := BuildEquiv A A idmap _.
Arguments equiv_idmap {A} , A.
Notation "1" := equiv_idmap : equiv_scope.
Global Instance isequiv_compose `{IsEquiv A B f} `{IsEquiv B C g}
: IsEquiv (compose g f) | 1000
:= BuildIsEquiv A C (compose g f)
(compose f^-1 g^-1)
(fun c => ap g (eisretr f (g^-1 c)) @ eisretr g c)
(fun a => ap (f^-1) (eissect g (f a)) @ eissect f a)
(fun a =>
(whiskerL _ (eisadj g (f a))) @
(ap_pp g _ _)^ @
ap02 g
( (concat_A1p (eisretr f) (eissect g (f a)))^ @
(ap_compose f^-1 f _ @@ eisadj f a) @
(ap_pp f _ _)^
) @
(ap_compose f g _)^
).
Definition equiv_compose {A B C : Type} (g : B -> C) (f : A -> B)
`{IsEquiv B C g} `{IsEquiv A B f}
: A <~> C
:= BuildEquiv A C (compose g f) _.
Global Instance transitive_equiv : Transitive Equiv | 0 :=
fun _ _ _ f g => equiv_compose g f.
admit.
Defined.
Global Instance symmetric_equiv : Symmetric Equiv | 0 := @equiv_inverse.
End Equivalences.
Definition path_prod_uncurried {A B : Type} (z z' : A * B)
(pq : (fst z = fst z') * (snd z = snd z'))
: (z = z').
admit.
Defined.
Global Instance isequiv_path_prod {A B : Type} {z z' : A * B}
: IsEquiv (path_prod_uncurried z z') | 0.
admit.
Defined.
Definition equiv_path_prod {A B : Type} (z z' : A * B)
: (fst z = fst z') * (snd z = snd z')  <~>  (z = z')
:= BuildEquiv _ _ (path_prod_uncurried z z') _.
Generalizable Variables X A B C f g n.
Definition functor_sigma `{P : A -> Type} `{Q : B -> Type}
(f : A -> B) (g : forall a, P a -> Q (f a))
: sigT P -> sigT Q
:= fun u => (f u.1 ; g u.1 u.2).
Global Instance isequiv_functor_sigma `{P : A -> Type} `{Q : B -> Type}
`{IsEquiv A B f} `{forall a, @IsEquiv (P a) (Q (f a)) (g a)}
: IsEquiv (functor_sigma f g) | 1000.
admit.
Defined.
Definition equiv_functor_sigma `{P : A -> Type} `{Q : B -> Type}
(f : A -> B) `{IsEquiv A B f}
(g : forall a, P a -> Q (f a))
`{forall a, @IsEquiv (P a) (Q (f a)) (g a)}
: sigT P <~> sigT Q
:= BuildEquiv _ _ (functor_sigma f g) _.
Definition equiv_functor_sigma' `{P : A -> Type} `{Q : B -> Type}
(f : A <~> B)
(g : forall a, P a <~> Q (f a))
: sigT P <~> sigT Q
:= equiv_functor_sigma f g.
Definition equiv_functor_sigma_id `{P : A -> Type} `{Q : A -> Type}
(g : forall a, P a <~> Q a)
: sigT P <~> sigT Q
:= equiv_functor_sigma' 1 g.
Definition Bip : Type := { C : Type &  C * C }.
Definition BipMor (X Y : Bip) : Type :=
match X, Y with (C;(c0,c1)), (D;(d0,d1)) =>
{ f : C -> D & (f c0 = d0) * (f c1 = d1) }
end.
Definition bipmor2map {X Y : Bip} : BipMor X Y -> X.1 -> Y.1 :=
match X, Y with (C;(c0,c1)), (D;(d0,d1)) => fun i =>
match i with (f;_) => f end
end.
Definition bipidmor {X : Bip} : BipMor X X :=
match X with (C;(c0,c1)) => (idmap; (1, 1)) end.
Definition bipcompmor {X Y Z : Bip} : BipMor X Y -> BipMor Y Z -> BipMor X Z :=
match X, Y, Z with (C;(c0,c1)), (D;(d0,d1)), (E;(e0,e1)) => fun i j =>
match i, j with (f;(f0,f1)), (g;(g0,g1)) =>
(g o f; (ap g f0 @ g0, ap g f1 @ g1))
end
end.
Definition isbipequiv {X Y : Bip} (i : BipMor X Y) : Type :=
{ l : BipMor Y X & bipcompmor i l = bipidmor } *
{ r : BipMor Y X & bipcompmor r i = bipidmor }.

Lemma bipequivEQequiv : forall {X Y : Bip} (i : BipMor X Y),
isbipequiv i <~> IsEquiv (bipmor2map i).