l3lab/ntp-mathlib huggingface dataset:
/-- A prefunctor from a quiver `B` to a bicategory `C` can be lifted to a pseudofunctor from
`free_bicategory B` to `C`.
-/
@[simps]
def lift : Pseudofunctor (FreeBicategory B) C where
  obj := F.obj
  map := liftHom F
  mapId a := Iso.refl _
  mapComp f g := Iso.refl _
  map₂ := Quot.lift (liftHom₂ F) fun η θ H => liftHom₂_congr F H
  -- Porting note: We'd really prefer not to be doing this by hand.
  -- in mathlib3 `tidy` did these inductions for us.
  map₂_comp := by
    intros a b f g h η θ
    apply Quot.rec _ _ η
    · intro η
      apply Quot.rec _ _ θ
      · intro θ; rfl
      · intros; rfl
    · intros; rfl
  -- Porting note: still borked from here. The infoview doesn't update properly for me.
  map₂_whisker_left := by
    intro a b c f g h η
    apply Quot.rec _ _ η
    · intros; aesop_cat
    · intros; rfl
  map₂_whisker_right := by intro _ _ _ _ _ η h; dsimp; apply Quot.rec _ _ η <;> 

Proof state:
B : Type u₁
inst✝¹ : Quiver B
C : Type u₂
inst✝ : Bicategory C
F : B ⥤q C
a✝ b✝ c✝ : FreeBicategory B
f✝ g✝ : a✝ ⟶ b✝
η : f✝ ⟶ g✝
h : b✝ ⟶ c✝
⊢ ∀ (a : Hom₂ f✝ g✝),
    Quot.lift (liftHom₂ F) (_ : ∀ (η θ : Hom₂ (f✝ ≫ h) (g✝ ≫ h)), Rel η θ → liftHom₂ F η = liftHom₂ F θ)
        (Quot.mk Rel a ▷ h) =
      𝟙 (liftHom F f✝ ≫ liftHom F h) ≫
        Quot.lift (liftHom₂ F) (_ : ∀ (η θ : Hom₂ f✝ g✝), Rel η θ → liftHom₂ F η = liftHom₂ F θ) (Quot.mk Rel a) ▷
            liftHom F h ≫
          𝟙 (liftHom F g✝ ≫ liftHom F h)

Next tactic:
aesop_cat
/-- A prefunctor from a quiver `B` to a bicategory `C` can be lifted to a pseudofunctor from
`free_bicategory B` to `C`.
-/
@[simps]
def lift : Pseudofunctor (FreeBicategory B) C where
  obj := F.obj
  map := liftHom F
  mapId a := Iso.refl _
  mapComp f g := Iso.refl _
  map₂ := Quot.lift (liftHom₂ F) fun η θ H => liftHom₂_congr F H
  -- Porting note: We'd really prefer not to be doing this by hand.
  -- in mathlib3 `tidy` did these inductions for us.
  map₂_comp := by
    intros a b f g h η θ
    apply Quot.rec _ _ η
    · intro η
      apply Quot.rec _ _ θ
      · intro θ; rfl
      · intros; rfl
    · intros; rfl
  -- Porting note: still borked from here. The infoview doesn't update properly for me.
  map₂_whisker_left := by
    intro a b c f g h η
    apply Quot.rec _ _ η
    · intros; aesop_cat
    · intros; rfl
  map₂_whisker_right := by intro _ _ _ _ _ η h; dsimp; apply Quot.rec _ _ η <;> 

Proof state:
B : Type u₁
inst✝¹ : Quiver B
C : Type u₂
inst✝ : Bicategory C
F : B ⥤q C
a✝ b✝ c✝ : FreeBicategory B
f✝ g✝ : a✝ ⟶ b✝
η : f✝ ⟶ g✝
h : b✝ ⟶ c✝
⊢ ∀ (a b : Hom₂ f✝ g✝) (p : Rel a b),
    (_ :
        Quot.lift (liftHom₂ F) (_ : ∀ (η θ : Hom₂ (f✝ ≫ h) (g✝ ≫ h)), Rel η θ → liftHom₂ F η = liftHom₂ F θ)
            (Quot.mk Rel b ▷ h) =
          𝟙 (liftHom F f✝ ≫ liftHom F h) ≫
            Quot.lift (liftHom₂ F) (_ : ∀ (η θ : Hom₂ f✝ g✝), Rel η θ → liftHom₂ F η = liftHom₂ F θ) (Quot.mk Rel b) ▷
                liftHom F h ≫
              𝟙 (liftHom F g✝ ≫ liftHom F h)) =
      (_ :
        Quot.lift (liftHom₂ F) (_ : ∀ (η θ : Hom₂ (f✝ ≫ h) (g✝ ≫ h)), Rel η θ → liftHom₂ F η = liftHom₂ F θ)
            (Quot.mk Rel b ▷ h) =
          𝟙 (liftHom F f✝ ≫ liftHom F h) ≫
            Quot.lift (liftHom₂ F) (_ : ∀ (η θ : Hom₂ f✝ g✝), Rel η θ → liftHom₂ F η = liftHom₂ F θ) (Quot.mk Rel b) ▷
                liftHom F h ≫
              𝟙 (liftHom F g✝ ≫ liftHom F h))

Next tactic:
aesop_cat
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X Y : D
f : X ⟶ Y
⊢ (R₁ ⋙ G).map f ≫
      (fun X => adj₂.unit.app (G.obj (R₁.obj X)) ≫ R₂.map (h.app (R₁.obj X) ≫ H.map (adj₁.counit.app X))) Y =
    (fun X => adj₂.unit.app (G.obj (R₁.obj X)) ≫ R₂.map (h.app (R₁.obj X) ≫ H.map (adj₁.counit.app X))) X ≫
      (H ⋙ R₂).map f

Next tactic:
dsimp
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X Y : D
f : X ⟶ Y
⊢ G.map (R₁.map f) ≫ adj₂.unit.app (G.obj (R₁.obj Y)) ≫ R₂.map (h.app (R₁.obj Y) ≫ H.map (adj₁.counit.app Y)) =
    (adj₂.unit.app (G.obj (R₁.obj X)) ≫ R₂.map (h.app (R₁.obj X) ≫ H.map (adj₁.counit.app X))) ≫ R₂.map (H.map f)

Next tactic:
rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X Y : D
f : X ⟶ Y
⊢ G.map (R₁.map f) ≫ adj₂.unit.app (G.obj (R₁.obj Y)) ≫ R₂.map (h.app (R₁.obj Y) ≫ H.map (adj₁.counit.app Y)) =
    adj₂.unit.app (G.obj (R₁.obj X)) ≫ R₂.map ((G ⋙ L₂).map (R₁.map f) ≫ h.app (R₁.obj Y) ≫ H.map (adj₁.counit.app Y))

Next tactic:
simp
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : R₁ ⋙ G ⟶ H ⋙ R₂
X Y : C
f : X ⟶ Y
⊢ (G ⋙ L₂).map f ≫
      (fun X => L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X)) ≫ adj₂.counit.app (H.obj (L₁.obj X))) Y =
    (fun X => L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X)) ≫ adj₂.counit.app (H.obj (L₁.obj X))) X ≫
      (L₁ ⋙ H).map f

Next tactic:
dsimp
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : R₁ ⋙ G ⟶ H ⋙ R₂
X Y : C
f : X ⟶ Y
⊢ L₂.map (G.map f) ≫ L₂.map (G.map (adj₁.unit.app Y) ≫ h.app (L₁.obj Y)) ≫ adj₂.counit.app (H.obj (L₁.obj Y)) =
    (L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X)) ≫ adj₂.counit.app (H.obj (L₁.obj X))) ≫ H.map (L₁.map f)

Next tactic:
rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
        

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : R₁ ⋙ G ⟶ H ⋙ R₂
X Y : C
f : X ⟶ Y
⊢ L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X) ≫ (H ⋙ R₂).map (L₁.map f)) ≫ adj₂.counit.app (H.obj (L₁.obj Y)) =
    (L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X)) ≫ adj₂.counit.app (H.obj (L₁.obj X))) ≫ H.map (L₁.map f)

Next tactic:
simp
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
        simp }
  left_inv h := by
    

Proof state:
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
⊢ (fun h =>
        NatTrans.mk fun X => L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X)) ≫ adj₂.counit.app (H.obj (L₁.obj X)))
      ((fun h =>
          NatTrans.mk fun X => adj₂.unit.app (G.obj (R₁.obj X)) ≫ R₂.map (h.app (R₁.obj X) ≫ H.map (adj₁.counit.app X)))
        h) =
    h

Next tactic:
ext X
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
        simp }
  left_inv h := by
    ext X
    

Proof state:
case w.h
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X : C
⊢ ((fun h =>
            NatTrans.mk fun X =>
              L₂.map (G.map (adj₁.unit.app X) ≫ h.app (L₁.obj X)) ≫ adj₂.counit.app (H.obj (L₁.obj X)))
          ((fun h =>
              NatTrans.mk fun X =>
                adj₂.unit.app (G.obj (R₁.obj X)) ≫ R₂.map (h.app (R₁.obj X) ≫ H.map (adj₁.counit.app X)))
            h)).app
      X =
    h.app X

Next tactic:
dsimp
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
        simp }
  left_inv h := by
    ext X
    dsimp
    

Proof state:
case w.h
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X : C
⊢ L₂.map
        (G.map (adj₁.unit.app X) ≫
          adj₂.unit.app (G.obj (R₁.obj (L₁.obj X))) ≫
            R₂.map (h.app (R₁.obj (L₁.obj X)) ≫ H.map (adj₁.counit.app (L₁.obj X)))) ≫
      adj₂.counit.app (H.obj (L₁.obj X)) =
    h.app X

Next tactic:
simp only [L₂.map_comp, assoc, adj₂.counit_naturality, adj₂.left_triangle_components_assoc, ←
      Functor.comp_map G L₂, h.naturality_assoc, Functor.comp_map L₁, ← H.map_comp,
      adj₁.left_triangle_components]
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
        simp }
  left_inv h := by
    ext X
    dsimp
    simp only [L₂.map_comp, assoc, adj₂.counit_naturality, adj₂.left_triangle_components_assoc, ←
      Functor.comp_map G L₂, h.naturality_assoc, Functor.comp_map L₁, ← H.map_comp,
      adj₁.left_triangle_components]
    

Proof state:
case w.h
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X : C
⊢ h.app X ≫ H.map (𝟙 (L₁.obj X)) = h.app X

Next tactic:
dsimp
/-- Suppose we have a square of functors (where the top and bottom are adjunctions `L₁ ⊣ R₁` and
`L₂ ⊣ R₂` respectively).

      C ↔ D
    G ↓   ↓ H
      E ↔ F

Then we have a bijection between natural transformations `G ⋙ L₂ ⟶ L₁ ⋙ H` and
`R₁ ⋙ G ⟶ H ⋙ R₂`.
This can be seen as a bijection of the 2-cells:

         L₁                  R₁
      C --→ D             C ←-- D
    G ↓  ↗  ↓ H         G ↓  ↘  ↓ H
      E --→ F             E ←-- F
         L₂                  R₂

Note that if one of the transformations is an iso, it does not imply the other is an iso.
-/
def transferNatTrans : (G ⋙ L₂ ⟶ L₁ ⋙ H) ≃ (R₁ ⋙ G ⟶ H ⋙ R₂)
    where
  toFun h :=
    { app := fun X => adj₂.unit.app _ ≫ R₂.map (h.app _ ≫ H.map (adj₁.counit.app _))
      naturality := fun X Y f => by
        dsimp
        rw [assoc, ← R₂.map_comp, assoc, ← H.map_comp, ← adj₁.counit_naturality, H.map_comp, ←
          Functor.comp_map L₁, ← h.naturality_assoc]
        simp }
  invFun h :=
    { app := fun X => L₂.map (G.map (adj₁.unit.app _) ≫ h.app _) ≫ adj₂.counit.app _
      naturality := fun X Y f => by
        dsimp
        rw [← L₂.map_comp_assoc, ← G.map_comp_assoc, ← adj₁.unit_naturality, G.map_comp_assoc, ←
          Functor.comp_map, h.naturality]
        simp }
  left_inv h := by
    ext X
    dsimp
    simp only [L₂.map_comp, assoc, adj₂.counit_naturality, adj₂.left_triangle_components_assoc, ←
      Functor.comp_map G L₂, h.naturality_assoc, Functor.comp_map L₁, ← H.map_comp,
      adj₁.left_triangle_components]
    dsimp
    

Proof state:
case w.h
C : Type u₁
D : Type u₂
inst✝³ : Category.{v₁, u₁} C
inst✝² : Category.{v₂, u₂} D
E : Type u₃
F : Type u₄
inst✝¹ : Category.{v₃, u₃} E
inst✝ : Category.{v₄, u₄} F
G : C ⥤ E
H : D ⥤ F
L₁ : C ⥤ D
R₁ : D ⥤ C
L₂ : E ⥤ F
R₂ : F ⥤ E
adj₁ : L₁ ⊣ R₁
adj₂ : L₂ ⊣ R₂
h : G ⋙ L₂ ⟶ L₁ ⋙ H
X : C
⊢ h.app X ≫ H.map (𝟙 (L₁.obj X)) = h.app X

Next tactic:
simp only [id_comp, ← Functor.comp_map, ← Functor.comp_obj, NatTrans.naturality_assoc]