l3lab/ntp-mathlib huggingface dataset:
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            

Proof state:
case refine'_1
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ ((map f).obj g).left ⟶ h.left
case refine'_2
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ ?refine'_1 ≫ h.hom = ((map f).obj g).hom

Next tactic:
refine' Y.left ≫ pullback.fst
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            

Proof state:
case refine'_2
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ (Y.left ≫ pullback.fst) ≫ h.hom = ((map f).obj g).hom

Next tactic:
dsimp
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            

Proof state:
case refine'_2
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ (Y.left ≫ pullback.fst) ≫ h.hom = g.hom ≫ f

Next tactic:
rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; 

Proof state:
case refine'_2
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ Y.left ≫ pullback.snd ≫ f = Y.left ≫ ((pullback f).obj h).hom ≫ f

Next tactic:
rfl
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            

Proof state:
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X✝ : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
X : (map f).obj g ⟶ h
⊢ (fun Y => homMk (Y.left ≫ pullback.fst))
      ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom))) X) =
    X

Next tactic:
ext
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            

Proof state:
case h
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X✝ : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
X : (map f).obj g ⟶ h
⊢ ((fun Y => homMk (Y.left ≫ pullback.fst))
        ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom))) X)).left =
    X.left

Next tactic:
dsimp
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            

Proof state:
case h
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X✝ : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
X : (map f).obj g ⟶ h
⊢ pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom) ≫ pullback.fst = X.left

Next tactic:
simp
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            

Proof state:
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ (fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
      ((fun Y => homMk (Y.left ≫ pullback.fst)) Y) =
    Y

Next tactic:
apply OverMorphism.ext
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            

Proof state:
case h
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
        ((fun Y => homMk (Y.left ≫ pullback.fst)) Y)).left =
    Y.left

Next tactic:
apply pullback.hom_ext
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · 

Proof state:
case h.h₀
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
          ((fun Y => homMk (Y.left ≫ pullback.fst)) Y)).left ≫
      pullback.fst =
    Y.left ≫ pullback.fst

Next tactic:
dsimp
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              

Proof state:
case h.h₀
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ pullback.lift (Y.left ≫ pullback.fst) g.hom (_ : (homMk (Y.left ≫ pullback.fst)).left ≫ h.hom = ((map f).obj g).hom) ≫
      pullback.fst =
    Y.left ≫ pullback.fst

Next tactic:
simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · 

Proof state:
case h.h₁
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
          ((fun Y => homMk (Y.left ≫ pullback.fst)) Y)).left ≫
      pullback.snd =
    Y.left ≫ pullback.snd

Next tactic:
dsimp
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · dsimp
              

Proof state:
case h.h₁
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ pullback.lift (Y.left ≫ pullback.fst) g.hom (_ : (homMk (Y.left ≫ pullback.fst)).left ≫ h.hom = ((map f).obj g).hom) ≫
      pullback.snd =
    Y.left ≫ pullback.snd

Next tactic:
simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, ← Over.w Y ]
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, ← Over.w Y ]
              

Proof state:
case h.h₁
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
g : Over A
h : Over B
Y : g ⟶ (pullback f).obj h
⊢ Y.left ≫ ((pullback f).obj h).hom = Y.left ≫ pullback.snd

Next tactic:
rfl
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, ← Over.w Y ]
              rfl }
      -- This used to be automatic before leanprover/lean4#2644
      homEquiv_naturality_right := by 

Proof state:
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
⊢ ∀ {X : Over A} {Y Y' : Over B} (f_1 : (map f).obj X ⟶ Y) (g : Y ⟶ Y'),
    ((fun g h =>
            { toFun := fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)),
              invFun := fun Y => homMk (Y.left ≫ pullback.fst),
              left_inv :=
                (_ :
                  ∀ (X : (map f).obj g ⟶ h),
                    (fun Y => homMk (Y.left ≫ pullback.fst))
                        ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom))) X) =
                      X),
              right_inv :=
                (_ :
                  ∀ (Y : g ⟶ (pullback f).obj h),
                    (fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
                        ((fun Y => homMk (Y.left ≫ pullback.fst)) Y) =
                      Y) })
          X Y')
        (f_1 ≫ g) =
      ((fun g h =>
              { toFun := fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)),
                invFun := fun Y => homMk (Y.left ≫ pullback.fst),
                left_inv :=
                  (_ :
                    ∀ (X : (map f).obj g ⟶ h),
                      (fun Y => homMk (Y.left ≫ pullback.fst))
                          ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom))) X) =
                        X),
                right_inv :=
                  (_ :
                    ∀ (Y : g ⟶ (pullback f).obj h),
                      (fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
                          ((fun Y => homMk (Y.left ≫ pullback.fst)) Y) =
                        Y) })
            X Y)
          f_1 ≫
        (pullback f).map g

Next tactic:
intros
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, ← Over.w Y ]
              rfl }
      -- This used to be automatic before leanprover/lean4#2644
      homEquiv_naturality_right := by intros; 

Proof state:
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
X✝ : Over A
Y✝ Y'✝ : Over B
f✝ : (map f).obj X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Y'✝
⊢ ((fun g h =>
          { toFun := fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)),
            invFun := fun Y => homMk (Y.left ≫ pullback.fst),
            left_inv :=
              (_ :
                ∀ (X : (map f).obj g ⟶ h),
                  (fun Y => homMk (Y.left ≫ pullback.fst))
                      ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom))) X) =
                    X),
            right_inv :=
              (_ :
                ∀ (Y : g ⟶ (pullback f).obj h),
                  (fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
                      ((fun Y => homMk (Y.left ≫ pullback.fst)) Y) =
                    Y) })
        X✝ Y'✝)
      (f✝ ≫ g✝) =
    ((fun g h =>
            { toFun := fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)),
              invFun := fun Y => homMk (Y.left ≫ pullback.fst),
              left_inv :=
                (_ :
                  ∀ (X : (map f).obj g ⟶ h),
                    (fun Y => homMk (Y.left ≫ pullback.fst))
                        ((fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom))) X) =
                      X),
              right_inv :=
                (_ :
                  ∀ (Y : g ⟶ (pullback f).obj h),
                    (fun X => homMk (pullback.lift X.left g.hom (_ : X.left ≫ h.hom = ((map f).obj g).hom)))
                        ((fun Y => homMk (Y.left ≫ pullback.fst)) Y) =
                      Y) })
          X✝ Y✝)
        f✝ ≫
      (pullback f).map g✝

Next tactic:
dsimp
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, ← Over.w Y ]
              rfl }
      -- This used to be automatic before leanprover/lean4#2644
      homEquiv_naturality_right := by intros; dsimp; 

Proof state:
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
X✝ : Over A
Y✝ Y'✝ : Over B
f✝ : (map f).obj X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Y'✝
⊢ homMk (pullback.lift (f✝.left ≫ g✝.left) X✝.hom (_ : (f✝ ≫ g✝).left ≫ Y'✝.hom = ((map f).obj X✝).hom)) =
    homMk (pullback.lift f✝.left X✝.hom (_ : f✝.left ≫ Y✝.hom = ((map f).obj X✝).hom)) ≫
      homMk
        (pullback.lift (pullback.fst ≫ g✝.left) pullback.snd
          (_ : (pullback.fst ≫ g✝.left) ≫ Y'✝.hom = pullback.snd ≫ f))

Next tactic:
congr 1
/-- `Over.map f` is left adjoint to `Over.pullback f`. -/
def mapPullbackAdj {A B : C} (f : A ⟶ B) : Over.map f ⊣ pullback f :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun g h =>
        { toFun := fun X =>
            Over.homMk (pullback.lift X.left g.hom (Over.w X)) (pullback.lift_snd _ _ _)
          invFun := fun Y => by
            refine' Over.homMk _ _
            refine' Y.left ≫ pullback.fst
            dsimp
            rw [← Over.w Y, Category.assoc, pullback.condition, Category.assoc]; rfl
          left_inv := fun X => by
            ext
            dsimp
            simp
          right_inv := fun Y => by
            -- TODO: It would be nice to replace the next two lines with just `ext`.
            apply OverMorphism.ext
            apply pullback.hom_ext
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app]
            · dsimp
              simp only [limit.lift_π, PullbackCone.mk_pt, PullbackCone.mk_π_app, ← Over.w Y ]
              rfl }
      -- This used to be automatic before leanprover/lean4#2644
      homEquiv_naturality_right := by intros; dsimp; congr 1; 

Proof state:
case e_f
J : Type w
inst✝² : Category.{w', w} J
C : Type u
inst✝¹ : Category.{v, u} C
X : C
inst✝ : HasPullbacks C
A B : C
f : A ⟶ B
X✝ : Over A
Y✝ Y'✝ : Over B
f✝ : (map f).obj X✝ ⟶ Y✝
g✝ : Y✝ ⟶ Y'✝
⊢ pullback.lift (f✝.left ≫ g✝.left) X✝.hom (_ : (f✝ ≫ g✝).left ≫ Y'✝.hom = ((map f).obj X✝).hom) =
    (homMk (pullback.lift f✝.left X✝.hom (_ : f✝.left ≫ Y✝.hom = ((map f).obj X✝).hom))).left ≫
      (homMk
          (pullback.lift (pullback.fst ≫ g✝.left) pullback.snd
            (_ : (pullback.fst ≫ g✝.left) ≫ Y'✝.hom = pullback.snd ≫ f))).left

Next tactic:
aesop_cat