l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · 

Proof state:
case some.none
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x : α
h : σ (some x) = none
⊢ Option.map (⇑(removeNone σ)) (some x) = (swap none (σ none)) none

Next tactic:
simp [removeNone_none _ h]
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · simp [removeNone_none _ h]
      · 

Proof state:
case some.some
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x val✝ : α
h : σ (some x) = some val✝
⊢ Option.map (⇑(removeNone σ)) (some x) = (swap none (σ none)) (some val✝)

Next tactic:
have hn : σ (some x) ≠ none := by simp [h]
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · simp [removeNone_none _ h]
      · have hn : σ (some x) ≠ none := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x val✝ : α
h : σ (some x) = some val✝
⊢ σ (some x) ≠ none

Next tactic:
simp [h]
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · simp [removeNone_none _ h]
      · have hn : σ (some x) ≠ none := by simp [h]
        

Proof state:
case some.some
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x val✝ : α
h : σ (some x) = some val✝
hn : σ (some x) ≠ none
⊢ Option.map (⇑(removeNone σ)) (some x) = (swap none (σ none)) (some val✝)

Next tactic:
have hσn : σ (some x) ≠ σ none := σ.injective.ne (by simp)
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · simp [removeNone_none _ h]
      · have hn : σ (some x) ≠ none := by simp [h]
        have hσn : σ (some x) ≠ σ none := σ.injective.ne (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x val✝ : α
h : σ (some x) = some val✝
hn : σ (some x) ≠ none
⊢ some x ≠ none

Next tactic:
simp
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · simp [removeNone_none _ h]
      · have hn : σ (some x) ≠ none := by simp [h]
        have hσn : σ (some x) ≠ σ none := σ.injective.ne (by simp)
        

Proof state:
case some.some
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x val✝ : α
h : σ (some x) = some val✝
hn : σ (some x) ≠ none
hσn : σ (some x) ≠ σ none
⊢ Option.map (⇑(removeNone σ)) (some x) = (swap none (σ none)) (some val✝)

Next tactic:
simp [removeNone_some _ ⟨_, h⟩, ← h, swap_apply_of_ne_of_ne hn hσn]
@[simp]
theorem map_equiv_removeNone {α : Type*} [DecidableEq α] (σ : Perm (Option α)) :
    (removeNone σ).optionCongr = swap none (σ none) * σ := by
  ext1 x
  have : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x) := by
    cases' x with x
    · simp
    · cases h : σ (some _)
      · simp [removeNone_none _ h]
      · have hn : σ (some x) ≠ none := by simp [h]
        have hσn : σ (some x) ≠ σ none := σ.injective.ne (by simp)
        simp [removeNone_some _ ⟨_, h⟩, ← h, swap_apply_of_ne_of_ne hn hσn]
  

Proof state:
case H
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
x : Option α
this : Option.map (⇑(removeNone σ)) x = (swap none (σ none)) (σ x)
⊢ (optionCongr (removeNone σ)) x = (swap none (σ none) * σ) x

Next tactic:
simpa using this
/-- Permutations of `Option α` are equivalent to fixing an
`Option α` and permuting the remaining with a `Perm α`.
The fixed `Option α` is swapped with `none`. -/
@[simps]
def Equiv.Perm.decomposeOption {α : Type*} [DecidableEq α] : Perm (Option α) ≃ Option α × Perm α
    where
  toFun σ := (σ none, removeNone σ)
  invFun i := swap none i.1 * i.2.optionCongr
  left_inv σ := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
σ : Perm (Option α)
⊢ (fun i => swap none i.1 * optionCongr i.2) ((fun σ => (σ none, removeNone σ)) σ) = σ

Next tactic:
simp
/-- Permutations of `Option α` are equivalent to fixing an
`Option α` and permuting the remaining with a `Perm α`.
The fixed `Option α` is swapped with `none`. -/
@[simps]
def Equiv.Perm.decomposeOption {α : Type*} [DecidableEq α] : Perm (Option α) ≃ Option α × Perm α
    where
  toFun σ := (σ none, removeNone σ)
  invFun i := swap none i.1 * i.2.optionCongr
  left_inv σ := by simp
  right_inv := fun ⟨x, σ⟩ => by
    

Proof state:
α : Type u_1
inst✝ : DecidableEq α
x✝ : Option α × Perm α
x : Option α
σ : Perm α
⊢ (fun σ => (σ none, removeNone σ)) ((fun i => swap none i.1 * optionCongr i.2) (x, σ)) = (x, σ)

Next tactic:
have : removeNone (swap none x * σ.optionCongr) = σ :=
      Equiv.optionCongr_injective (by simp [← mul_assoc])
/-- Permutations of `Option α` are equivalent to fixing an
`Option α` and permuting the remaining with a `Perm α`.
The fixed `Option α` is swapped with `none`. -/
@[simps]
def Equiv.Perm.decomposeOption {α : Type*} [DecidableEq α] : Perm (Option α) ≃ Option α × Perm α
    where
  toFun σ := (σ none, removeNone σ)
  invFun i := swap none i.1 * i.2.optionCongr
  left_inv σ := by simp
  right_inv := fun ⟨x, σ⟩ => by
    have : removeNone (swap none x * σ.optionCongr) = σ :=
      Equiv.optionCongr_injective (by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
x✝ : Option α × Perm α
x : Option α
σ : Perm α
⊢ optionCongr (removeNone (swap none x * optionCongr σ)) = optionCongr σ

Next tactic:
simp [← mul_assoc]
/-- Permutations of `Option α` are equivalent to fixing an
`Option α` and permuting the remaining with a `Perm α`.
The fixed `Option α` is swapped with `none`. -/
@[simps]
def Equiv.Perm.decomposeOption {α : Type*} [DecidableEq α] : Perm (Option α) ≃ Option α × Perm α
    where
  toFun σ := (σ none, removeNone σ)
  invFun i := swap none i.1 * i.2.optionCongr
  left_inv σ := by simp
  right_inv := fun ⟨x, σ⟩ => by
    have : removeNone (swap none x * σ.optionCongr) = σ :=
      Equiv.optionCongr_injective (by simp [← mul_assoc])
    

Proof state:
α : Type u_1
inst✝ : DecidableEq α
x✝ : Option α × Perm α
x : Option α
σ : Perm α
this : removeNone (swap none x * optionCongr σ) = σ
⊢ (fun σ => (σ none, removeNone σ)) ((fun i => swap none i.1 * optionCongr i.2) (x, σ)) = (x, σ)

Next tactic:
simp [← Perm.eq_inv_iff_eq, this]
theorem Equiv.Perm.decomposeOption_symm_of_none_apply {α : Type*} [DecidableEq α] (e : Perm α)
    (i : Option α) : Equiv.Perm.decomposeOption.symm (none, e) i = i.map e := by 

Proof state:
α : Type u_1
inst✝ : DecidableEq α
e : Perm α
i : Option α
⊢ (decomposeOption.symm (none, e)) i = Option.map (⇑e) i

Next tactic:
simp
theorem Equiv.Perm.decomposeOption_symm_sign {α : Type*} [DecidableEq α] [Fintype α] (e : Perm α) :
    Perm.sign (Equiv.Perm.decomposeOption.symm (none, e)) = Perm.sign e := by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
e : Perm α
⊢ sign (decomposeOption.symm (none, e)) = sign e

Next tactic:
simp
theorem obj_map_id {X Y : C} (f : op X ⟶ op Y) :
    (yoneda.obj X).map f (𝟙 X) = (yoneda.map f.unop).app (op Y) (𝟙 Y) := by
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f : op X ⟶ op Y
⊢ (yoneda.obj X).map f (𝟙 X) = (yoneda.map f.unop).app (op Y) (𝟙 Y)

Next tactic:
dsimp
theorem obj_map_id {X Y : C} (f : op X ⟶ op Y) :
    (yoneda.obj X).map f (𝟙 X) = (yoneda.map f.unop).app (op Y) (𝟙 Y) := by
  dsimp
  

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f : op X ⟶ op Y
⊢ f.unop ≫ 𝟙 X = 𝟙 Y ≫ f.unop

Next tactic:
simp
/-- The Yoneda embedding is faithful.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
instance yoneda_faithful : Faithful (yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁) where
  map_injective {X} {Y} f g p := by
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f g : X ⟶ Y
p : yoneda.map f = yoneda.map g
⊢ f = g

Next tactic:
convert congr_fun (congr_app p (op X)) (𝟙 X) using 1
/-- The Yoneda embedding is faithful.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
instance yoneda_faithful : Faithful (yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁) where
  map_injective {X} {Y} f g p := by
    convert congr_fun (congr_app p (op X)) (𝟙 X) using 1 <;> 

Proof state:
case h.e'_2.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f g : X ⟶ Y
p : yoneda.map f = yoneda.map g
e_1✝ : (X ⟶ Y) = (yoneda.obj Y).obj (op X)
⊢ f = (yoneda.map f).app (op X) (𝟙 X)

Next tactic:
dsimp
/-- The Yoneda embedding is faithful.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
instance yoneda_faithful : Faithful (yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁) where
  map_injective {X} {Y} f g p := by
    convert congr_fun (congr_app p (op X)) (𝟙 X) using 1 <;> 

Proof state:
case h.e'_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f g : X ⟶ Y
p : yoneda.map f = yoneda.map g
e_1✝ : (X ⟶ Y) = (yoneda.obj Y).obj (op X)
⊢ g = (yoneda.map g).app (op X) (𝟙 X)

Next tactic:
dsimp
/-- The Yoneda embedding is faithful.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
instance yoneda_faithful : Faithful (yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁) where
  map_injective {X} {Y} f g p := by
    convert congr_fun (congr_app p (op X)) (𝟙 X) using 1 <;> dsimp <;> 

Proof state:
case h.e'_2.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f g : X ⟶ Y
p : yoneda.map f = yoneda.map g
e_1✝ : (X ⟶ Y) = (yoneda.obj Y).obj (op X)
⊢ f = 𝟙 X ≫ f

Next tactic:
simp
/-- The Yoneda embedding is faithful.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
instance yoneda_faithful : Faithful (yoneda : C ⥤ Cᵒᵖ ⥤ Type v₁) where
  map_injective {X} {Y} f g p := by
    convert congr_fun (congr_app p (op X)) (𝟙 X) using 1 <;> dsimp <;> 

Proof state:
case h.e'_3.h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : C
f g : X ⟶ Y
p : yoneda.map f = yoneda.map g
e_1✝ : (X ⟶ Y) = (yoneda.obj Y).obj (op X)
⊢ g = 𝟙 X ≫ g

Next tactic:
simp
instance coyonedaFull : Full (coyoneda : Cᵒᵖ ⥤ C ⥤ Type v₁) where
  preimage {X} _ f := (f.app _ (𝟙 X.unop)).op
  witness {X} {Y} f := by 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ
f : coyoneda.obj X ⟶ coyoneda.obj Y
⊢ coyoneda.map ((fun {X} x f => (f.app X.unop (𝟙 X.unop)).op) Y f) = f

Next tactic:
simp only [coyoneda]
instance coyonedaFull : Full (coyoneda : Cᵒᵖ ⥤ C ⥤ Type v₁) where
  preimage {X} _ f := (f.app _ (𝟙 X.unop)).op
  witness {X} {Y} f := by simp only [coyoneda]; 

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ
f : coyoneda.obj X ⟶ coyoneda.obj Y
⊢ (NatTrans.mk fun Y_1 g => (f.app X.unop (𝟙 X.unop)).op.unop ≫ g) = f

Next tactic:
aesop_cat
instance coyoneda_faithful : Faithful (coyoneda : Cᵒᵖ ⥤ C ⥤ Type v₁) where
  map_injective {X} _ _ _ p := by
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X x✝² : Cᵒᵖ
x✝¹ x✝ : X ⟶ x✝²
p : coyoneda.map x✝¹ = coyoneda.map x✝
⊢ x✝¹ = x✝

Next tactic:
have t := congr_fun (congr_app p X.unop) (𝟙 _)
instance coyoneda_faithful : Faithful (coyoneda : Cᵒᵖ ⥤ C ⥤ Type v₁) where
  map_injective {X} _ _ _ p := by
    have t := congr_fun (congr_app p X.unop) (𝟙 _)
    

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X x✝² : Cᵒᵖ
x✝¹ x✝ : X ⟶ x✝²
p : coyoneda.map x✝¹ = coyoneda.map x✝
t : (coyoneda.map x✝¹).app X.unop (𝟙 X.unop) = (coyoneda.map x✝).app X.unop (𝟙 X.unop)
⊢ x✝¹ = x✝

Next tactic:
simpa using congr_arg Quiver.Hom.op t
theorem reprW_app_hom (X : Cᵒᵖ) (f : unop X ⟶ F.reprX) :
    (F.reprW.app X).hom f = F.map f.op F.reprx := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : Cᵒᵖ ⥤ Type v₁
inst✝ : Representable F
X : Cᵒᵖ
f : X.unop ⟶ reprX F
⊢ ((reprW F).app X).hom f = F.map f.op (reprx F)

Next tactic:
change F.reprF.app X f = (F.reprF.app (op F.reprX) ≫ F.map f.op) (𝟙 F.reprX)
theorem reprW_app_hom (X : Cᵒᵖ) (f : unop X ⟶ F.reprX) :
    (F.reprW.app X).hom f = F.map f.op F.reprx := by
  change F.reprF.app X f = (F.reprF.app (op F.reprX) ≫ F.map f.op) (𝟙 F.reprX)
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : Cᵒᵖ ⥤ Type v₁
inst✝ : Representable F
X : Cᵒᵖ
f : X.unop ⟶ reprX F
⊢ (reprF F).app X f = ((reprF F).app (op (reprX F)) ≫ F.map f.op) (𝟙 (reprX F))

Next tactic:
rw [← F.reprF.naturality]
theorem reprW_app_hom (X : Cᵒᵖ) (f : unop X ⟶ F.reprX) :
    (F.reprW.app X).hom f = F.map f.op F.reprx := by
  change F.reprF.app X f = (F.reprF.app (op F.reprX) ≫ F.map f.op) (𝟙 F.reprX)
  rw [← F.reprF.naturality]
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : Cᵒᵖ ⥤ Type v₁
inst✝ : Representable F
X : Cᵒᵖ
f : X.unop ⟶ reprX F
⊢ (reprF F).app X f = ((yoneda.obj (reprX F)).map f.op ≫ (reprF F).app (op X.unop)) (𝟙 (reprX F))

Next tactic:
dsimp
theorem reprW_app_hom (X : Cᵒᵖ) (f : unop X ⟶ F.reprX) :
    (F.reprW.app X).hom f = F.map f.op F.reprx := by
  change F.reprF.app X f = (F.reprF.app (op F.reprX) ≫ F.map f.op) (𝟙 F.reprX)
  rw [← F.reprF.naturality]
  dsimp
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : Cᵒᵖ ⥤ Type v₁
inst✝ : Representable F
X : Cᵒᵖ
f : X.unop ⟶ reprX F
⊢ (reprF F).app X f = (reprF F).app X (f ≫ 𝟙 (reprX F))

Next tactic:
simp
theorem coreprW_app_hom (X : C) (f : F.coreprX ⟶ X) :
    (F.coreprW.app X).hom f = F.map f F.coreprx := by
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : C ⥤ Type v₁
inst✝ : Corepresentable F
X : C
f : coreprX F ⟶ X
⊢ ((coreprW F).app X).hom f = F.map f (coreprx F)

Next tactic:
change F.coreprF.app X f = (F.coreprF.app F.coreprX ≫ F.map f) (𝟙 F.coreprX)
theorem coreprW_app_hom (X : C) (f : F.coreprX ⟶ X) :
    (F.coreprW.app X).hom f = F.map f F.coreprx := by
  change F.coreprF.app X f = (F.coreprF.app F.coreprX ≫ F.map f) (𝟙 F.coreprX)
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : C ⥤ Type v₁
inst✝ : Corepresentable F
X : C
f : coreprX F ⟶ X
⊢ (coreprF F).app X f = ((coreprF F).app (coreprX F) ≫ F.map f) (𝟙 (coreprX F))

Next tactic:
rw [← F.coreprF.naturality]
theorem coreprW_app_hom (X : C) (f : F.coreprX ⟶ X) :
    (F.coreprW.app X).hom f = F.map f F.coreprx := by
  change F.coreprF.app X f = (F.coreprF.app F.coreprX ≫ F.map f) (𝟙 F.coreprX)
  rw [← F.coreprF.naturality]
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : C ⥤ Type v₁
inst✝ : Corepresentable F
X : C
f : coreprX F ⟶ X
⊢ (coreprF F).app X f = ((coyoneda.obj (op (coreprX F))).map f ≫ (coreprF F).app X) (𝟙 (coreprX F))

Next tactic:
dsimp
theorem coreprW_app_hom (X : C) (f : F.coreprX ⟶ X) :
    (F.coreprW.app X).hom f = F.map f F.coreprx := by
  change F.coreprF.app X f = (F.coreprF.app F.coreprX ≫ F.map f) (𝟙 F.coreprX)
  rw [← F.coreprF.naturality]
  dsimp
  

Proof state:
C : Type u₁
inst✝¹ : Category.{v₁, u₁} C
F : C ⥤ Type v₁
inst✝ : Corepresentable F
X : C
f : coreprX F ⟶ X
⊢ (coreprF F).app X f = (coreprF F).app X (𝟙 (coreprX F) ≫ f)

Next tactic:
simp
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
⊢ ∀ ⦃X Y : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)⦄ (f : X ⟶ Y),
    (yonedaPairing C).map f ≫ (fun F x => { down := x.app F.1 (𝟙 F.1.unop) }) Y =
      (fun F x => { down := x.app F.1 (𝟙 F.1.unop) }) X ≫ (yonedaEvaluation C).map f

Next tactic:
intro X Y f
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
f : X ⟶ Y
⊢ (yonedaPairing C).map f ≫ (fun F x => { down := x.app F.1 (𝟙 F.1.unop) }) Y =
    (fun F x => { down := x.app F.1 (𝟙 F.1.unop) }) X ≫ (yonedaEvaluation C).map f

Next tactic:
simp only [yonedaEvaluation]
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
f : X ⟶ Y
⊢ ((yonedaPairing C).map f ≫ fun x => { down := x.app Y.1 (𝟙 Y.1.unop) }) =
    (fun x => { down := x.app X.1 (𝟙 X.1.unop) }) ≫ (evaluationUncurried Cᵒᵖ (Type v₁) ⋙ uliftFunctor.{u₁, v₁}).map f

Next tactic:
ext
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        ext
        

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
f : X ⟶ Y
a✝ : (yonedaPairing C).obj X
⊢ ((yonedaPairing C).map f ≫ fun x => { down := x.app Y.1 (𝟙 Y.1.unop) }) a✝ =
    ((fun x => { down := x.app X.1 (𝟙 X.1.unop) }) ≫ (evaluationUncurried Cᵒᵖ (Type v₁) ⋙ uliftFunctor.{u₁, v₁}).map f)
      a✝

Next tactic:
dsimp
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        ext
        dsimp
        

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
f : X ⟶ Y
a✝ : (yonedaPairing C).obj X
⊢ { down := f.2.app Y.1 (a✝.app Y.1 (𝟙 Y.1.unop ≫ f.1.unop)) } =
    { down := f.2.app Y.1 (X.2.map f.1 (a✝.app X.1 (𝟙 X.1.unop))) }

Next tactic:
erw [Category.id_comp, ← FunctorToTypes.naturality]
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        ext
        dsimp
        erw [Category.id_comp, ← FunctorToTypes.naturality]
        

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
X Y : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
f : X ⟶ Y
a✝ : (yonedaPairing C).obj X
⊢ { down := f.2.app Y.1 (a✝.app Y.1 f.1.unop) } =
    { down := f.2.app Y.1 (a✝.app Y.1 ((yoneda.obj X.1.unop).map f.1 (𝟙 X.1.unop))) }

Next tactic:
simp only [Category.comp_id, yoneda_obj_map]
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        ext
        dsimp
        erw [Category.id_comp, ← FunctorToTypes.naturality]
        simp only [Category.comp_id, yoneda_obj_map] }
  inv :=
    { app := fun F x =>
        { app := fun X a => (F.2.map a.op) x.down
          naturality := by
            

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
F : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
x : (yonedaEvaluation C).obj F
⊢ ∀ ⦃X Y : Cᵒᵖ⦄ (f : X ⟶ Y),
    ((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).1.unop.map f ≫ (fun X a => F.2.map a.op x.down) Y =
      (fun X a => F.2.map a.op x.down) X ≫ ((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).2.map f

Next tactic:
intro X Y f
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        ext
        dsimp
        erw [Category.id_comp, ← FunctorToTypes.naturality]
        simp only [Category.comp_id, yoneda_obj_map] }
  inv :=
    { app := fun F x =>
        { app := fun X a => (F.2.map a.op) x.down
          naturality := by
            intro X Y f
            

Proof state:
C : Type u₁
inst✝ : Category.{v₁, u₁} C
F : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
x : (yonedaEvaluation C).obj F
X Y : Cᵒᵖ
f : X ⟶ Y
⊢ ((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).1.unop.map f ≫ (fun X a => F.2.map a.op x.down) Y =
    (fun X a => F.2.map a.op x.down) X ≫ ((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).2.map f

Next tactic:
ext
/-- The Yoneda lemma asserts that the Yoneda pairing
`(X : Cᵒᵖ, F : Cᵒᵖ ⥤ Type) ↦ (yoneda.obj (unop X) ⟶ F)`
is naturally isomorphic to the evaluation `(X, F) ↦ F.obj X`.

See <https://stacks.math.columbia.edu/tag/001P>.
-/
def yonedaLemma : yonedaPairing C ≅ yonedaEvaluation C where
  hom :=
    { app := fun F x => ULift.up ((x.app F.1) (𝟙 (unop F.1)))
      naturality := by
        intro X Y f
        simp only [yonedaEvaluation]
        ext
        dsimp
        erw [Category.id_comp, ← FunctorToTypes.naturality]
        simp only [Category.comp_id, yoneda_obj_map] }
  inv :=
    { app := fun F x =>
        { app := fun X a => (F.2.map a.op) x.down
          naturality := by
            intro X Y f
            ext
            

Proof state:
case h
C : Type u₁
inst✝ : Category.{v₁, u₁} C
F : Cᵒᵖ × (Cᵒᵖ ⥤ Type v₁)
x : (yonedaEvaluation C).obj F
X Y : Cᵒᵖ
f : X ⟶ Y
a✝ : ((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).1.unop.obj X
⊢ (((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).1.unop.map f ≫ (fun X a => F.2.map a.op x.down) Y) a✝ =
    ((fun X a => F.2.map a.op x.down) X ≫ ((Functor.prod yoneda.op (𝟭 (Cᵒᵖ ⥤ Type v₁))).obj F).2.map f) a✝

Next tactic:
dsimp