{-# OPTIONS --without-K --rewriting #-}

open import lib.Basics
open import lib.FTID
open import lib.Equivalence2
open import lib.types.Sigma
open import lib.types.Pi
open import Bicategory
open import Bicat-iso-aux

-- isomorphism of (2,1)-categories and associated SIP

module Bicat-iso where

open BicatStr
open Psfunctor
open PsftorStr {{...}}

module _ {i₁ i₂ j₁ j₂ : ULevel} {B₀ : Type i₁} where

  is-iso-bc :  {C₀ : Type i₂} {{ξB : BicatStr j₁ B₀}} {{ξC : BicatStr j₂ C₀}}
     Psfunctor {{ξB}} {{ξC}}  Type (lmax (lmax (lmax i₁ i₂) j₁) j₂)
  is-iso-bc φ = is-equiv (map-pf φ) × ((a b : B₀)  is-equiv (F₁ {a = a} {b}))

  iso-bc-is-prop :  {C₀ : Type i₂} {{ξB : BicatStr j₁ B₀}} {{ξC : BicatStr j₂ C₀}} {φ : Psfunctor {{ξB}} {{ξC}}}  is-prop (is-iso-bc φ)
  iso-bc-is-prop = ×-level ⟨⟩ Π-level-instance

  infixr 70 _iso-bc_
  _iso-bc_ : {C₀ : Type i₂}
     BicatStr j₁ B₀  BicatStr j₂ C₀  Type (lmax (lmax (lmax i₁ i₂) j₁) j₂)
  ξB iso-bc ξC = Σ (Psfunctor {{ξB}} {{ξC}})  φ  is-iso-bc {{ξB}} {{ξC}} φ)

module _ {i j} {B₀ : Type i} (ξB : BicatStr j B₀) where

  iso-bc-id : ξB iso-bc ξB
  fst iso-bc-id = idfBC {{ξB}}
  snd iso-bc-id = idf-is-equiv B₀ , λ a b  idf-is-equiv (hom ξB a b)

  abstract
    bc-contr : is-contr (Σ (Bicat j i)  (_ , ξC)  ξB iso-bc ξC))
    bc-contr = equiv-preserves-level lemma {{bc-contr-aux ξB}}
      where
        lemma : tot-iso-bc ξB  Σ (Bicat j i)  (_ , ξC)  ξB iso-bc ξC)
        lemma =
          equiv
             ((C₀ , F₀ , e₀) , (homC , F₁) , (id₁C , F-id) , (◻-C , F-◻) ,
              (ρC , F-ρ) , (lambC , F-λ) , (αC , F-α) , triC , pentC , truncC) 
                (C₀ ,
                bicatstr (curry homC) id₁C  g f  ◻-C (_ , (g , f)))
                   f  ρC (_ , f))  f  lambC (_ , f))  h g f  αC (_ , (h , g , f)))
                   f g  triC (_ , (f , g)))  f g h i  pentC (_ , (f , g , h , i))) {{truncC}}) ,
                (psfunctor F₀
                  {{psfunctorstr  {a} {b} f  –> (F₁ (a , b)) f) F-id  f g  F-◻ (_ , (g , f)))
                     f  F-ρ (_ , f))  f  F-λ (_ , f)) λ h g f  F-α (_ , (h , g , f))}}) ,
                (e₀ , λ a b  snd (F₁ (a , b))))
             ((C₀ , ξC) , psfunctor F₀ {{σ}} , e₀ , e₁) 
              (C₀ , (F₀ , e₀)) ,
                (((λ (a , b)  hom ξC a b) , λ (a , b)  (F₁ {{ξB}} {{ξC}}) , (e₁ a b)) ,
                  ((id₁ ξC , F-id₁ {{ξB}} {{ξC}}) ,
                    (((λ (_ , (g , f))   ξC  g  f) , λ (_ , (g , f))  F-◻ {{ξB}} {{ξC}} f g) ,
                      (((λ (_ , f)  ρ ξC f) , λ (_ , f)  F-ρ {{ξB}} {{ξC}} f) ,
                        (((λ (_ , f)  lamb ξC f) , λ (_ , f)  F-λ {{ξB}} {{ξC}} f) ,
                          (((λ (_ , (h , g , f))  α ξC h g f) , λ (_ , (h , g , f))  F-α {{ξB}} {{ξC}} h g f) ,
                             (_ , (f , g))  tri-bc ξC f g) , ((λ (_ , (f , g , h , i))  pent-bc ξC f g h i) ,
                            hom-trunc ξC))))))))
             _  idp)
             _  idp)

  bc-ind :  {k} (P : ((_ , ξC)  : Bicat j i)  (ξB iso-bc ξC  Type k))
     P _ iso-bc-id  {C@(_ , ξC) : Bicat j i} (p : ξB iso-bc ξC)  P C p
  bc-ind P = ID-ind-map P bc-contr

  bc-ind-β :  {k} (P : ((_ , ξC) : Bicat j i)  (ξB iso-bc ξC  Type k))
     (r : P _ iso-bc-id)  bc-ind P r iso-bc-id == r
  bc-ind-β P = ID-ind-map-β P bc-contr

module _ {i j : ULevel} where

  iso-bc-to-== : {B@(_ , ξB) C@(_ , ξC) : Bicat j i}  ξB iso-bc ξC  B == C
  iso-bc-to-== {B@(_ , ξB)} = bc-ind ξB  C _  B == C) idp

  iso-bc-to-==-β : {(_ , ξB) : Bicat j i}  iso-bc-to-== (iso-bc-id ξB) == idp
  iso-bc-to-==-β {B@(_ , ξB)} = bc-ind-β ξB  C _  B == C) idp

  iso-bc-from-== : {B@(_ , ξB) C : Bicat j i}  B == C  ξB iso-bc (snd C)
  iso-bc-from-== {(_ , ξB)} idp = iso-bc-id ξB

  iso-bc-==-≃ : {B@(_ , ξB) C@(_ , ξC) : Bicat j i}  (ξB iso-bc ξC)  (B == C)
  iso-bc-==-≃ {B@(_ , ξB)} {C@(_ , ξC)} = equiv iso-bc-to-== iso-bc-from-== aux1 aux2
    where

      aux1 :  {D} (p : B == D)  iso-bc-to-== (iso-bc-from-== p) == p
      aux1 idp = iso-bc-to-==-β

      aux2 :  {D@(_ , ξD) : Bicat j i} (p : ξB iso-bc ξD)  iso-bc-from-== (iso-bc-to-== p) == p
      aux2 = bc-ind ξB  _ p  iso-bc-from-== (iso-bc-to-== p) == p) (ap iso-bc-from-== iso-bc-to-==-β)