l3lab/ntp-mathlib huggingface dataset:
theorem Ideal.irreducible_map_of_irreducible_minpoly (hI : IsMaximal I) (hI' : I ≠ ⊥)
    (hx : (conductor R x).comap (algebraMap R S) ⊔ I = ⊤) (hx' : IsIntegral R x)
    (hf : Irreducible (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x))) :
    Irreducible (I.map (algebraMap R S)) := by
  have mem_norm_factors : normalize (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)) ∈
      normalizedFactors (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)) :=
    by simp [normalizedFactors_irreducible hf]
  suffices ∃ y, normalizedFactors (I.map (algebraMap R S)) = {y} by
    obtain ⟨y, hy⟩ := this
    have h := normalizedFactors_prod (show I.map (algebraMap R S) ≠ 0 by
          rwa [← bot_eq_zero, Ne.def,
            map_eq_bot_iff_of_injective (NoZeroSMulDivisors.algebraMap_injective R S)])
    rw [associated_iff_eq, hy, Multiset.prod_singleton] at h
    rw [← h]
    exact
      irreducible_of_normalized_factor y
        (show y ∈ normalizedFactors (I.map (algebraMap R S)) by simp [hy])
  rw [normalizedFactors_ideal_map_eq_normalizedFactors_min_poly_mk_map hI hI' hx hx']
  use ((normalizedFactorsMapEquivNormalizedFactorsMinPolyMk hI hI' hx hx').symm
        ⟨normalize (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)), mem_norm_factors⟩ :
      Ideal S)
  rw [Multiset.map_eq_singleton]
  use ⟨normalize (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)), mem_norm_factors⟩
  refine ⟨?_, rfl⟩
  apply Multiset.map_injective Subtype.coe_injective
  rw [Multiset.attach_map_val, Multiset.map_singleton, Subtype.coe_mk]
  

Proof state:
case h.a
R : Type u_1
S : Type u_2
inst✝⁷ : CommRing R
inst✝⁶ : CommRing S
inst✝⁵ : Algebra R S
x : S
I : Ideal R
inst✝⁴ : IsDomain R
inst✝³ : IsIntegrallyClosed R
inst✝² : IsDomain S
inst✝¹ : IsDedekindDomain S
inst✝ : NoZeroSMulDivisors R S
hI : IsMaximal I
hI' : I ≠ ⊥
hx : comap (algebraMap R S) (conductor R x) ⊔ I = ⊤
hx' : _root_.IsIntegral R x
hf : Irreducible (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x))
mem_norm_factors :
  normalize (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)) ∈
    normalizedFactors (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x))
⊢ normalizedFactors (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x)) =
    {normalize (Polynomial.map (Ideal.Quotient.mk I) (minpoly R x))}

Next tactic:
exact normalizedFactors_irreducible hf
lemma Functor.Elements.ext {F : C ⥤ Type w} (x y : F.Elements) (h₁ : x.fst = y.fst)
    (h₂ : F.map (eqToHom h₁) x.snd = y.snd) : x = y := by
  

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
x y : Elements F
h₁ : x.fst = y.fst
h₂ : F.map (eqToHom h₁) x.snd = y.snd
⊢ x = y

Next tactic:
cases x
lemma Functor.Elements.ext {F : C ⥤ Type w} (x y : F.Elements) (h₁ : x.fst = y.fst)
    (h₂ : F.map (eqToHom h₁) x.snd = y.snd) : x = y := by
  cases x
  

Proof state:
case mk
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
y : Elements F
fst✝ : C
snd✝ : F.obj fst✝
h₁ : { fst := fst✝, snd := snd✝ }.fst = y.fst
h₂ : F.map (eqToHom h₁) { fst := fst✝, snd := snd✝ }.snd = y.snd
⊢ { fst := fst✝, snd := snd✝ } = y

Next tactic:
cases y
lemma Functor.Elements.ext {F : C ⥤ Type w} (x y : F.Elements) (h₁ : x.fst = y.fst)
    (h₂ : F.map (eqToHom h₁) x.snd = y.snd) : x = y := by
  cases x
  cases y
  

Proof state:
case mk.mk
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
fst✝¹ : C
snd✝¹ : F.obj fst✝¹
fst✝ : C
snd✝ : F.obj fst✝
h₁ : { fst := fst✝¹, snd := snd✝¹ }.fst = { fst := fst✝, snd := snd✝ }.fst
h₂ : F.map (eqToHom h₁) { fst := fst✝¹, snd := snd✝¹ }.snd = { fst := fst✝, snd := snd✝ }.snd
⊢ { fst := fst✝¹, snd := snd✝¹ } = { fst := fst✝, snd := snd✝ }

Next tactic:
cases h₁
lemma Functor.Elements.ext {F : C ⥤ Type w} (x y : F.Elements) (h₁ : x.fst = y.fst)
    (h₂ : F.map (eqToHom h₁) x.snd = y.snd) : x = y := by
  cases x
  cases y
  cases h₁
  

Proof state:
case mk.mk.refl
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
fst✝ : C
snd✝¹ snd✝ : F.obj fst✝
h₂ :
  F.map (eqToHom (_ : { fst := fst✝, snd := snd✝¹ }.fst = { fst := fst✝, snd := snd✝¹ }.fst))
      { fst := fst✝, snd := snd✝¹ }.snd =
    { fst := fst✝, snd := snd✝ }.snd
⊢ { fst := fst✝, snd := snd✝¹ } = { fst := fst✝, snd := snd✝ }

Next tactic:
simp only [eqToHom_refl, FunctorToTypes.map_id_apply] at h₂
lemma Functor.Elements.ext {F : C ⥤ Type w} (x y : F.Elements) (h₁ : x.fst = y.fst)
    (h₂ : F.map (eqToHom h₁) x.snd = y.snd) : x = y := by
  cases x
  cases y
  cases h₁
  simp only [eqToHom_refl, FunctorToTypes.map_id_apply] at h₂
  

Proof state:
case mk.mk.refl
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
fst✝ : C
snd✝¹ snd✝ : F.obj fst✝
h₂ : snd✝¹ = snd✝
⊢ { fst := fst✝, snd := snd✝¹ } = { fst := fst✝, snd := snd✝ }

Next tactic:
simp [h₂]
/-- The category structure on `F.Elements`, for `F : C ⥤ Type`.
    A morphism `(X, x) ⟶ (Y, y)` is a morphism `f : X ⟶ Y` in `C`, so `F.map f` takes `x` to `y`.
 -/
instance categoryOfElements (F : C ⥤ Type w) : Category.{v} F.Elements where
  Hom p q := { f : p.1 ⟶ q.1 // (F.map f) p.2 = q.2 }
  id p := ⟨𝟙 p.1, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
p : Functor.Elements F
⊢ F.map (𝟙 p.fst) p.snd = p.snd

Next tactic:
aesop_cat
/-- The category structure on `F.Elements`, for `F : C ⥤ Type`.
    A morphism `(X, x) ⟶ (Y, y)` is a morphism `f : X ⟶ Y` in `C`, so `F.map f` takes `x` to `y`.
 -/
instance categoryOfElements (F : C ⥤ Type w) : Category.{v} F.Elements where
  Hom p q := { f : p.1 ⟶ q.1 // (F.map f) p.2 = q.2 }
  id p := ⟨𝟙 p.1, by aesop_cat⟩
  comp {X Y Z} f g := ⟨f.val ≫ g.val, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
X Y Z : Functor.Elements F
f : X ⟶ Y
g : Y ⟶ Z
⊢ F.map (↑f ≫ ↑g) X.snd = Z.snd

Next tactic:
simp [f.2, g.2]
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
p q : Functor.Elements F
f : p ⟶ q
⊢ F.map (Groupoid.inv ↑f) q.snd = F.map (Groupoid.inv ↑f) (F.map (↑f) p.snd)

Next tactic:
rw [f.2]
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by rw [f.2]
        _ = (F.map f.val ≫ F.map (Groupoid.inv f.val)) p.2 := rfl
        _ = p.2 := by
          

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
p q : Functor.Elements F
f : p ⟶ q
⊢ (F.map ↑f ≫ F.map (Groupoid.inv ↑f)) p.snd = p.snd

Next tactic:
rw [← F.map_comp]
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by rw [f.2]
        _ = (F.map f.val ≫ F.map (Groupoid.inv f.val)) p.2 := rfl
        _ = p.2 := by
          rw [← F.map_comp]
          

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
p q : Functor.Elements F
f : p ⟶ q
⊢ F.map (↑f ≫ Groupoid.inv ↑f) p.snd = p.snd

Next tactic:
simp
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by rw [f.2]
        _ = (F.map f.val ≫ F.map (Groupoid.inv f.val)) p.2 := rfl
        _ = p.2 := by
          rw [← F.map_comp]
          simp
        ⟩
  inv_comp _ := by
    

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
X✝ Y✝ : Functor.Elements F
x✝ : X✝ ⟶ Y✝
⊢ (fun {p q} f => { val := Groupoid.inv ↑f, property := (_ : F.map (Groupoid.inv ↑f) q.snd = p.snd) }) x✝ ≫ x✝ = 𝟙 Y✝

Next tactic:
ext
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by rw [f.2]
        _ = (F.map f.val ≫ F.map (Groupoid.inv f.val)) p.2 := rfl
        _ = p.2 := by
          rw [← F.map_comp]
          simp
        ⟩
  inv_comp _ := by
    ext
    

Proof state:
case w
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
X✝ Y✝ : Functor.Elements F
x✝ : X✝ ⟶ Y✝
⊢ ↑((fun {p q} f => { val := Groupoid.inv ↑f, property := (_ : F.map (Groupoid.inv ↑f) q.snd = p.snd) }) x✝ ≫ x✝) =
    ↑(𝟙 Y✝)

Next tactic:
simp
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by rw [f.2]
        _ = (F.map f.val ≫ F.map (Groupoid.inv f.val)) p.2 := rfl
        _ = p.2 := by
          rw [← F.map_comp]
          simp
        ⟩
  inv_comp _ := by
    ext
    simp
  comp_inv _ := by
    

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
X✝ Y✝ : Functor.Elements F
x✝ : X✝ ⟶ Y✝
⊢ x✝ ≫ (fun {p q} f => { val := Groupoid.inv ↑f, property := (_ : F.map (Groupoid.inv ↑f) q.snd = p.snd) }) x✝ = 𝟙 X✝

Next tactic:
ext
instance groupoidOfElements {G : Type u} [Groupoid.{v} G] (F : G ⥤ Type w) :
    Groupoid F.Elements
    where
  inv {p q} f :=
    ⟨Groupoid.inv f.val,
      calc
        F.map (Groupoid.inv f.val) q.2 = F.map (Groupoid.inv f.val) (F.map f.val p.2) := by rw [f.2]
        _ = (F.map f.val ≫ F.map (Groupoid.inv f.val)) p.2 := rfl
        _ = p.2 := by
          rw [← F.map_comp]
          simp
        ⟩
  inv_comp _ := by
    ext
    simp
  comp_inv _ := by
    ext
    

Proof state:
case w
C : Type u
inst✝¹ : Category.{v, u} C
G : Type u
inst✝ : Groupoid G
F : G ⥤ Type w
X✝ Y✝ : Functor.Elements F
x✝ : X✝ ⟶ Y✝
⊢ ↑(x✝ ≫ (fun {p q} f => { val := Groupoid.inv ↑f, property := (_ : F.map (Groupoid.inv ↑f) q.snd = p.snd) }) x✝) =
    ↑(𝟙 X✝)

Next tactic:
simp
/-- A natural transformation between functors induces a functor between the categories of elements.
-/
@[simps]
def map {F₁ F₂ : C ⥤ Type w} (α : F₁ ⟶ F₂) : F₁.Elements ⥤ F₂.Elements
    where
  obj t := ⟨t.1, α.app t.1 t.2⟩
  map {t₁ t₂} k := ⟨k.1, by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F F₁ F₂ : C ⥤ Type w
α : F₁ ⟶ F₂
t₁ t₂ : Functor.Elements F₁
k : t₁ ⟶ t₂
⊢ F₂.map (↑k) ((fun t => { fst := t.fst, snd := α.app t.fst t.snd }) t₁).snd =
    ((fun t => { fst := t.fst, snd := α.app t.fst t.snd }) t₂).snd

Next tactic:
simpa [← k.2] using (FunctorToTypes.naturality _ _ α k.1 t₁.2).symm
/-- The forward direction of the equivalence `F.Elements ≅ (*, F)`. -/
def toStructuredArrow : F.Elements ⥤ StructuredArrow PUnit F where
  obj X := StructuredArrow.mk fun _ => X.2
  map {X Y} f := StructuredArrow.homMk f.val (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
X Y : Functor.Elements F
f : X ⟶ Y
⊢ ((fun X => StructuredArrow.mk fun x => X.snd) X).hom ≫ F.map ↑f = ((fun X => StructuredArrow.mk fun x => X.snd) Y).hom

Next tactic:
funext
/-- The forward direction of the equivalence `F.Elements ≅ (*, F)`. -/
def toStructuredArrow : F.Elements ⥤ StructuredArrow PUnit F where
  obj X := StructuredArrow.mk fun _ => X.2
  map {X Y} f := StructuredArrow.homMk f.val (by funext; 

Proof state:
case h
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
X Y : Functor.Elements F
f : X ⟶ Y
x✝ : (Functor.fromPUnit PUnit.{w + 1}).obj ((fun X => StructuredArrow.mk fun x => X.snd) X).left
⊢ (((fun X => StructuredArrow.mk fun x => X.snd) X).hom ≫ F.map ↑f) x✝ =
    Comma.hom ((fun X => StructuredArrow.mk fun x => X.snd) Y) x✝

Next tactic:
simp [f.2]
/-- The equivalence between the category of elements `F.Elements`
    and the comma category `(*, F)`. -/
@[simps! functor_obj functor_map inverse_obj inverse_map unitIso_hom
  unitIso_inv counitIso_hom counitIso_inv]
def structuredArrowEquivalence : F.Elements ≌ StructuredArrow PUnit F :=
  Equivalence.mk (toStructuredArrow F) (fromStructuredArrow F)
    (NatIso.ofComponents fun X => eqToIso (by 

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F : C ⥤ Type w
X : Functor.Elements F
⊢ (𝟭 (Functor.Elements F)).obj X = (toStructuredArrow F ⋙ fromStructuredArrow F).obj X

Next tactic:
aesop_cat
/-- The forward direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaSections`.
-/
@[simps]
def toCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : F.Elementsᵒᵖ ⥤ CostructuredArrow yoneda F
    where
  obj X := CostructuredArrow.mk ((yonedaSections (unop (unop X).fst) F).inv (ULift.up (unop X).2))
  map f := by
    

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X✝ Y✝ : (Functor.Elements F)ᵒᵖ
f : X✝ ⟶ Y✝
⊢ (fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) X✝ ⟶
    (fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) Y✝

Next tactic:
fapply CostructuredArrow.homMk
/-- The forward direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaSections`.
-/
@[simps]
def toCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : F.Elementsᵒᵖ ⥤ CostructuredArrow yoneda F
    where
  obj X := CostructuredArrow.mk ((yonedaSections (unop (unop X).fst) F).inv (ULift.up (unop X).2))
  map f := by
    fapply CostructuredArrow.homMk
    · 

Proof state:
case g
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X✝ Y✝ : (Functor.Elements F)ᵒᵖ
f : X✝ ⟶ Y✝
⊢ ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) X✝).left ⟶
    ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) Y✝).left

Next tactic:
exact f.unop.val.unop
/-- The forward direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaSections`.
-/
@[simps]
def toCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : F.Elementsᵒᵖ ⥤ CostructuredArrow yoneda F
    where
  obj X := CostructuredArrow.mk ((yonedaSections (unop (unop X).fst) F).inv (ULift.up (unop X).2))
  map f := by
    fapply CostructuredArrow.homMk
    · exact f.unop.val.unop
    · 

Proof state:
case w
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X✝ Y✝ : (Functor.Elements F)ᵒᵖ
f : X✝ ⟶ Y✝
⊢ autoParam
    (yoneda.map (↑f.unop).unop ≫
        ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) Y✝).hom =
      ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) X✝).hom)
    _auto✝

Next tactic:
ext Z y
/-- The forward direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaSections`.
-/
@[simps]
def toCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : F.Elementsᵒᵖ ⥤ CostructuredArrow yoneda F
    where
  obj X := CostructuredArrow.mk ((yonedaSections (unop (unop X).fst) F).inv (ULift.up (unop X).2))
  map f := by
    fapply CostructuredArrow.homMk
    · exact f.unop.val.unop
    · ext Z y
      

Proof state:
case w.w.h.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X✝ Y✝ : (Functor.Elements F)ᵒᵖ
f : X✝ ⟶ Y✝
Z : Cᵒᵖ
y :
  (yoneda.obj
        ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) X✝).left).obj
    Z
⊢ (yoneda.map (↑f.unop).unop ≫
          ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) Y✝).hom).app
      Z y =
    ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) X✝).hom.app Z y

Next tactic:
dsimp
/-- The forward direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaSections`.
-/
@[simps]
def toCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : F.Elementsᵒᵖ ⥤ CostructuredArrow yoneda F
    where
  obj X := CostructuredArrow.mk ((yonedaSections (unop (unop X).fst) F).inv (ULift.up (unop X).2))
  map f := by
    fapply CostructuredArrow.homMk
    · exact f.unop.val.unop
    · ext Z y
      dsimp
      

Proof state:
case w.w.h.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X✝ Y✝ : (Functor.Elements F)ᵒᵖ
f : X✝ ⟶ Y✝
Z : Cᵒᵖ
y :
  (yoneda.obj
        ((fun X => CostructuredArrow.mk ((yonedaSections X.unop.fst.unop F).inv { down := X.unop.snd })) X✝).left).obj
    Z
⊢ F.map (↑f.unop ≫ y.op) Y✝.unop.snd = F.map y.op X✝.unop.snd

Next tactic:
simp only [FunctorToTypes.map_comp_apply, ← f.unop.2]
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
⊢ F.map f.unop.left.op ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) X).snd =
    ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).snd

Next tactic:
convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
      

Proof state:
case h.e'_3.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
e_1✝ :
  F.obj ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).fst =
    ((Functor.fromPUnit F).obj X.unop.right).obj (op Y.unop.left)
⊢ ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).snd =
    ((yoneda.obj X.unop.left).map f.unop.left.op ≫ X.unop.hom.app (op Y.unop.left)) (𝟙 (op X.unop.left).unop)

Next tactic:
simp only [Equiv.toFun_as_coe, Quiver.Hom.unop_op, yonedaEquiv_apply, types_comp_apply,
        Category.comp_id, yoneda_obj_map]
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
      simp only [Equiv.toFun_as_coe, Quiver.Hom.unop_op, yonedaEquiv_apply, types_comp_apply,
        Category.comp_id, yoneda_obj_map]
      

Proof state:
case h.e'_3.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
e_1✝ :
  F.obj ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).fst =
    ((Functor.fromPUnit F).obj X.unop.right).obj (op Y.unop.left)
⊢ Y.unop.hom.app (op Y.unop.left) (𝟙 Y.unop.left) = X.unop.hom.app (op Y.unop.left) f.unop.left

Next tactic:
have : yoneda.map f.unop.left ≫ (unop X).hom = (unop Y).hom := by
        convert f.unop.3
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
      simp only [Equiv.toFun_as_coe, Quiver.Hom.unop_op, yonedaEquiv_apply, types_comp_apply,
        Category.comp_id, yoneda_obj_map]
      have : yoneda.map f.unop.left ≫ (unop X).hom = (unop Y).hom := by
        

Proof state:
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
e_1✝ :
  F.obj ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).fst =
    ((Functor.fromPUnit F).obj X.unop.right).obj (op Y.unop.left)
⊢ yoneda.map f.unop.left ≫ X.unop.hom = Y.unop.hom

Next tactic:
convert f.unop.3
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
      simp only [Equiv.toFun_as_coe, Quiver.Hom.unop_op, yonedaEquiv_apply, types_comp_apply,
        Category.comp_id, yoneda_obj_map]
      have : yoneda.map f.unop.left ≫ (unop X).hom = (unop Y).hom := by
        convert f.unop.3
      

Proof state:
case h.e'_3.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
e_1✝ :
  F.obj ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).fst =
    ((Functor.fromPUnit F).obj X.unop.right).obj (op Y.unop.left)
this : yoneda.map f.unop.left ≫ X.unop.hom = Y.unop.hom
⊢ Y.unop.hom.app (op Y.unop.left) (𝟙 Y.unop.left) = X.unop.hom.app (op Y.unop.left) f.unop.left

Next tactic:
erw [← this]
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
      simp only [Equiv.toFun_as_coe, Quiver.Hom.unop_op, yonedaEquiv_apply, types_comp_apply,
        Category.comp_id, yoneda_obj_map]
      have : yoneda.map f.unop.left ≫ (unop X).hom = (unop Y).hom := by
        convert f.unop.3
      erw [← this]
      

Proof state:
case h.e'_3.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
e_1✝ :
  F.obj ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).fst =
    ((Functor.fromPUnit F).obj X.unop.right).obj (op Y.unop.left)
this : yoneda.map f.unop.left ≫ X.unop.hom = Y.unop.hom
⊢ (yoneda.map f.unop.left ≫ X.unop.hom).app (op Y.unop.left) (𝟙 Y.unop.left) =
    X.unop.hom.app (op Y.unop.left) f.unop.left

Next tactic:
simp only [yoneda_map_app, FunctorToTypes.comp]
/-- The reverse direction of the equivalence `F.Elementsᵒᵖ ≅ (yoneda, F)`,
given by `CategoryTheory.yonedaEquiv`.
-/
@[simps]
def fromCostructuredArrow (F : Cᵒᵖ ⥤ Type v) : (CostructuredArrow yoneda F)ᵒᵖ ⥤ F.Elements where
  obj X := ⟨op (unop X).1, yonedaEquiv.1 (unop X).3⟩
  map {X Y} f :=
    ⟨f.unop.1.op, by
      convert (congr_fun ((unop X).hom.naturality f.unop.left.op) (𝟙 _)).symm
      simp only [Equiv.toFun_as_coe, Quiver.Hom.unop_op, yonedaEquiv_apply, types_comp_apply,
        Category.comp_id, yoneda_obj_map]
      have : yoneda.map f.unop.left ≫ (unop X).hom = (unop Y).hom := by
        convert f.unop.3
      erw [← this]
      simp only [yoneda_map_app, FunctorToTypes.comp]
      

Proof state:
case h.e'_3.h
C : Type u
inst✝ : Category.{v, u} C
F✝ : C ⥤ Type w
F : Cᵒᵖ ⥤ Type v
X Y : (CostructuredArrow yoneda F)ᵒᵖ
f : X ⟶ Y
e_1✝ :
  F.obj ((fun X => { fst := op X.unop.left, snd := Equiv.toFun yonedaEquiv X.unop.hom }) Y).fst =
    ((Functor.fromPUnit F).obj X.unop.right).obj (op Y.unop.left)
this : yoneda.map f.unop.left ≫ X.unop.hom = Y.unop.hom
⊢ X.unop.hom.app (op Y.unop.left) (𝟙 Y.unop.left ≫ f.unop.left) = X.unop.hom.app (op Y.unop.left) f.unop.left

Next tactic:
erw [Category.id_comp]