l3lab/ntp-mathlib huggingface dataset:
/-- If the index type has cardinality equal to the finite dimension, composing an alternating
map with the same linear equiv on each argument gives the negation of that orientation if and
only if the determinant is negative. -/
theorem map_eq_neg_iff_det_neg (x : Orientation R M ι) (f : M ≃ₗ[R] M)
    (h : Fintype.card ι = finrank R M) :
    Orientation.map ι f x = -x ↔ LinearMap.det (f : M →ₗ[R] M) < 0 := by
  cases isEmpty_or_nonempty ι
  · have H : finrank R M = 0 := h.symm.trans Fintype.card_eq_zero
    simp [LinearMap.det_eq_one_of_finrank_eq_zero H, Module.Ray.ne_neg_self x]
  have H : 0 < finrank R M := by
    rw [← h]
    exact Fintype.card_pos
  haveI : FiniteDimensional R M := finiteDimensional_of_finrank H
  

Proof state:
case inr
R : Type u_1
inst✝³ : LinearOrderedField R
M : Type u_2
inst✝² : AddCommGroup M
inst✝¹ : Module R M
ι : Type u_3
inst✝ : Fintype ι
_i : FiniteDimensional R M
x : Orientation R M ι
f : M ≃ₗ[R] M
h : Fintype.card ι = finrank R M
h✝ : Nonempty ι
H : 0 < finrank R M
this : FiniteDimensional R M
⊢ (map ι f) x = -x ↔ LinearMap.det ↑f < 0

Next tactic:
rw [map_eq_det_inv_smul _ _ h, units_inv_smul, units_smul_eq_neg_iff, LinearEquiv.coe_det]
/-- `m.sym2` is the multiset of all unordered pairs of elements from `m`, with multiplicity.
If `m` has no duplicates then neither does `m.sym2`. -/
protected def sym2 (m : Multiset α) : Multiset (Sym2 α) :=
  m.liftOn (fun xs => xs.sym2) fun _ _ h => by 

Proof state:
α : Type u_1
m : Multiset α
x✝¹ x✝ : List α
h : x✝¹ ≈ x✝
⊢ (fun xs => ↑(List.sym2 xs)) x✝¹ = (fun xs => ↑(List.sym2 xs)) x✝

Next tactic:
rw [coe_eq_coe]
/-- `m.sym2` is the multiset of all unordered pairs of elements from `m`, with multiplicity.
If `m` has no duplicates then neither does `m.sym2`. -/
protected def sym2 (m : Multiset α) : Multiset (Sym2 α) :=
  m.liftOn (fun xs => xs.sym2) fun _ _ h => by rw [coe_eq_coe]; 

Proof state:
α : Type u_1
m : Multiset α
x✝¹ x✝ : List α
h : x✝¹ ≈ x✝
⊢ List.Perm (List.sym2 x✝¹) (List.sym2 x✝)

Next tactic:
exact h.sym2
@[simp]
theorem sym2_eq_zero_iff {m : Multiset α} : m.sym2 = 0 ↔ m = 0 :=
  m.inductionOn fun xs => by 

Proof state:
α : Type u_1
m : Multiset α
xs : List α
⊢ Multiset.sym2 ⟦xs⟧ = 0 ↔ ⟦xs⟧ = 0

Next tactic:
simp
theorem mk_mem_sym2_iff {m : Multiset α} {a b : α} :
    ⟦(a, b)⟧ ∈ m.sym2 ↔ a ∈ m ∧ b ∈ m :=
  m.inductionOn fun xs => by 

Proof state:
α : Type u_1
m : Multiset α
a b : α
xs : List α
⊢ ⟦(a, b)⟧ ∈ Multiset.sym2 ⟦xs⟧ ↔ a ∈ ⟦xs⟧ ∧ b ∈ ⟦xs⟧

Next tactic:
simp [List.mk_mem_sym2_iff]
theorem mem_sym2_iff {m : Multiset α} {z : Sym2 α} :
    z ∈ m.sym2 ↔ ∀ y ∈ z, y ∈ m :=
  m.inductionOn fun xs => by 

Proof state:
α : Type u_1
m : Multiset α
z : Sym2 α
xs : List α
⊢ z ∈ Multiset.sym2 ⟦xs⟧ ↔ ∀ y ∈ z, y ∈ ⟦xs⟧

Next tactic:
simp [List.mem_sym2_iff]
open scoped List in
@[simp, mono]
theorem sym2_mono {m m' : Multiset α} (h : m ≤ m') : m.sym2 ≤ m'.sym2 := by
  

Proof state:
α : Type u_1
m m' : Multiset α
h : m ≤ m'
⊢ Multiset.sym2 m ≤ Multiset.sym2 m'

Next tactic:
refine Quotient.inductionOn₂ m m' (fun xs ys h => ?_) h
open scoped List in
@[simp, mono]
theorem sym2_mono {m m' : Multiset α} (h : m ≤ m') : m.sym2 ≤ m'.sym2 := by
  refine Quotient.inductionOn₂ m m' (fun xs ys h => ?_) h
  

Proof state:
α : Type u_1
m m' : Multiset α
h✝ : m ≤ m'
xs ys : List α
h : ⟦xs⟧ ≤ ⟦ys⟧
⊢ Multiset.sym2 ⟦xs⟧ ≤ Multiset.sym2 ⟦ys⟧

Next tactic:
suffices : xs <+~ ys
open scoped List in
@[simp, mono]
theorem sym2_mono {m m' : Multiset α} (h : m ≤ m') : m.sym2 ≤ m'.sym2 := by
  refine Quotient.inductionOn₂ m m' (fun xs ys h => ?_) h
  suffices : xs <+~ ys
  · 

Proof state:
α : Type u_1
m m' : Multiset α
h✝ : m ≤ m'
xs ys : List α
h : ⟦xs⟧ ≤ ⟦ys⟧
this : xs <+~ ys
⊢ Multiset.sym2 ⟦xs⟧ ≤ Multiset.sym2 ⟦ys⟧

Next tactic:
exact this.sym2
open scoped List in
@[simp, mono]
theorem sym2_mono {m m' : Multiset α} (h : m ≤ m') : m.sym2 ≤ m'.sym2 := by
  refine Quotient.inductionOn₂ m m' (fun xs ys h => ?_) h
  suffices : xs <+~ ys
  · exact this.sym2
  

Proof state:
case this
α : Type u_1
m m' : Multiset α
h✝ : m ≤ m'
xs ys : List α
h : ⟦xs⟧ ≤ ⟦ys⟧
⊢ xs <+~ ys

Next tactic:
simpa only [quot_mk_to_coe, coe_le, sym2_coe] using h
theorem card_sym2 {m : Multiset α} :
    Multiset.card m.sym2 = Nat.choose (Multiset.card m + 1) 2 := by
  

Proof state:
α : Type u_1
m : Multiset α
⊢ card (Multiset.sym2 m) = Nat.choose (card m + 1) 2

Next tactic:
refine m.inductionOn fun xs => ?_
theorem card_sym2 {m : Multiset α} :
    Multiset.card m.sym2 = Nat.choose (Multiset.card m + 1) 2 := by
  refine m.inductionOn fun xs => ?_
  

Proof state:
α : Type u_1
m : Multiset α
xs : List α
⊢ card (Multiset.sym2 ⟦xs⟧) = Nat.choose (card ⟦xs⟧ + 1) 2

Next tactic:
simp [List.length_sym2]
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    

Proof state:
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
m n : ℕ
h : ↑m = ↑n
⊢ m = n

Next tactic:
induction' m with m ih generalizing n
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · 

Proof state:
case zero
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
n : ℕ
h : ↑Nat.zero = ↑n
⊢ Nat.zero = n

Next tactic:
rw [H n]
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · rw [H n]
      

Proof state:
case zero
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
n : ℕ
h : ↑Nat.zero = ↑n
⊢ ↑n = 0

Next tactic:
rw [← h, Nat.cast_zero]
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · rw [H n]
      rw [← h, Nat.cast_zero]

    

Proof state:
case succ
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
m : ℕ
ih : ∀ (n : ℕ), ↑m = ↑n → m = n
n : ℕ
h : ↑(Nat.succ m) = ↑n
⊢ Nat.succ m = n

Next tactic:
cases' n with n
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · rw [H n]
      rw [← h, Nat.cast_zero]

    cases' n with n
    · 

Proof state:
case succ.zero
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
m : ℕ
ih : ∀ (n : ℕ), ↑m = ↑n → m = n
h : ↑(Nat.succ m) = ↑Nat.zero
⊢ Nat.succ m = Nat.zero

Next tactic:
apply H
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · rw [H n]
      rw [← h, Nat.cast_zero]

    cases' n with n
    · apply H
      

Proof state:
case succ.zero.a
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
m : ℕ
ih : ∀ (n : ℕ), ↑m = ↑n → m = n
h : ↑(Nat.succ m) = ↑Nat.zero
⊢ ↑(Nat.succ m) = 0

Next tactic:
rw [h, Nat.cast_zero]
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · rw [H n]
      rw [← h, Nat.cast_zero]

    cases' n with n
    · apply H
      rw [h, Nat.cast_zero]

    

Proof state:
case succ.succ
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
m : ℕ
ih : ∀ (n : ℕ), ↑m = ↑n → m = n
n : ℕ
h : ↑(Nat.succ m) = ↑(Nat.succ n)
⊢ Nat.succ m = Nat.succ n

Next tactic:
simp only [Nat.cast_succ, add_right_cancel_iff] at h
theorem charZero_of_inj_zero [AddGroupWithOne R] (H : ∀ n : ℕ, (n : R) = 0 → n = 0) :
    CharZero R :=
  ⟨@fun m n h => by
    induction' m with m ih generalizing n
    · rw [H n]
      rw [← h, Nat.cast_zero]

    cases' n with n
    · apply H
      rw [h, Nat.cast_zero]

    simp only [Nat.cast_succ, add_right_cancel_iff] at h
    

Proof state:
case succ.succ
R : Type u_1
inst✝ : AddGroupWithOne R
H : ∀ (n : ℕ), ↑n = 0 → n = 0
m : ℕ
ih : ∀ (n : ℕ), ↑m = ↑n → m = n
n : ℕ
h : ↑m = ↑n
⊢ Nat.succ m = Nat.succ n

Next tactic:
rwa [ih]
@[simp, norm_cast]
theorem cast_eq_zero {n : ℕ} : (n : R) = 0 ↔ n = 0 := by 

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
n : ℕ
⊢ ↑n = 0 ↔ n = 0

Next tactic:
rw [← cast_zero, cast_inj]
theorem cast_add_one_ne_zero (n : ℕ) : (n + 1 : R) ≠ 0 := by
  -- porting note: old proof was `exact_mod_cast n.succ_ne_zero`
  

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
n : ℕ
⊢ ↑n + 1 ≠ 0

Next tactic:
norm_cast
theorem cast_add_one_ne_zero (n : ℕ) : (n + 1 : R) ≠ 0 := by
  -- porting note: old proof was `exact_mod_cast n.succ_ne_zero`
  norm_cast
  

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
n : ℕ
⊢ ¬n + 1 = 0

Next tactic:
exact n.succ_ne_zero
@[simp, norm_cast]
theorem cast_eq_one {n : ℕ} : (n : R) = 1 ↔ n = 1 := by 

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
n : ℕ
⊢ ↑n = 1 ↔ n = 1

Next tactic:
rw [← cast_one, cast_inj]
@[simp] lemma ofNat_ne_one (n : ℕ) [h : n.AtLeastTwo] : (no_index (ofNat n) : R) ≠ 1 := by
  

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
n : ℕ
h : Nat.AtLeastTwo n
⊢ ofNat n ≠ 1

Next tactic:
rw [← Nat.cast_eq_ofNat, ← @Nat.cast_one R, Ne.def, Nat.cast_inj]
@[simp] lemma ofNat_ne_one (n : ℕ) [h : n.AtLeastTwo] : (no_index (ofNat n) : R) ≠ 1 := by
  rw [← Nat.cast_eq_ofNat, ← @Nat.cast_one R, Ne.def, Nat.cast_inj]
  

Proof state:
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
n : ℕ
h : Nat.AtLeastTwo n
⊢ ¬n = 1

Next tactic:
exact ne_of_gt h.prop
instance charZero_one {M} [AddMonoidWithOne M] [CharZero M] : NeZero (1 : M) where
  out := by
    

Proof state:
M : Type ?u.5011
inst✝¹ : AddMonoidWithOne M
inst✝ : CharZero M
⊢ 1 ≠ 0

Next tactic:
rw [← Nat.cast_one, Nat.cast_ne_zero]
instance charZero_one {M} [AddMonoidWithOne M] [CharZero M] : NeZero (1 : M) where
  out := by
    rw [← Nat.cast_one, Nat.cast_ne_zero]
    

Proof state:
M : Type ?u.5011
inst✝¹ : AddMonoidWithOne M
inst✝ : CharZero M
⊢ 1 ≠ 0

Next tactic:
trivial
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
⊢ ∀ {X Y X' Y' : C} (f : X ⟶ Y) (g : X' ⟶ Y'),
    ((Functor.mk src✝.toPrefunctor).map f ⊗ (Functor.mk src✝.toPrefunctor).map g) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) Y Y' =
      (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X X' ≫ (Functor.mk src✝.toPrefunctor).map (f ⊗ g)

Next tactic:
aesop_cat
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
⊢ ((fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X Y ⊗ 𝟙 ((Functor.mk src✝.toPrefunctor).obj Z)) ≫
      (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) (X ⊗ Y) Z ≫ (Functor.mk src✝.toPrefunctor).map (α_ X Y Z).hom =
    (α_ ((Functor.mk src✝.toPrefunctor).obj X) ((Functor.mk src✝.toPrefunctor).obj Y)
          ((Functor.mk src✝.toPrefunctor).obj Z)).hom ≫
      (𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) Y Z) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X (Y ⊗ Z)

Next tactic:
ext ⟨⟨f, g⟩, h⟩
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; 

Proof state:
case h.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : (Functor.mk src✝.toPrefunctor).obj Z
f : (Functor.mk src✝.toPrefunctor).obj X
g : (Functor.mk src✝.toPrefunctor).obj Y
⊢ (((fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X Y ⊗ 𝟙 ((Functor.mk src✝.toPrefunctor).obj Z)) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) (X ⊗ Y) Z ≫ (Functor.mk src✝.toPrefunctor).map (α_ X Y Z).hom)
      ((f, g), h) =
    ((α_ ((Functor.mk src✝.toPrefunctor).obj X) ((Functor.mk src✝.toPrefunctor).obj Y)
            ((Functor.mk src✝.toPrefunctor).obj Z)).hom ≫
        (𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) Y Z) ≫
          (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X (Y ⊗ Z))
      ((f, g), h)

Next tactic:
dsimp at f g h
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      

Proof state:
case h.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : 𝟙_ C ⟶ Z
f : 𝟙_ C ⟶ X
g : 𝟙_ C ⟶ Y
⊢ (((fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X Y ⊗ 𝟙 ((Functor.mk src✝.toPrefunctor).obj Z)) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) (X ⊗ Y) Z ≫ (Functor.mk src✝.toPrefunctor).map (α_ X Y Z).hom)
      ((f, g), h) =
    ((α_ ((Functor.mk src✝.toPrefunctor).obj X) ((Functor.mk src✝.toPrefunctor).obj Y)
            ((Functor.mk src✝.toPrefunctor).obj Z)).hom ≫
        (𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) Y Z) ≫
          (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X (Y ⊗ Z))
      ((f, g), h)

Next tactic:
dsimp
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; 

Proof state:
case h.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : 𝟙_ C ⟶ Z
f : 𝟙_ C ⟶ X
g : 𝟙_ C ⟶ Y
⊢ ((λ_ (𝟙_ C)).inv ≫ ((λ_ (𝟙_ C)).inv ≫ (f ⊗ g) ⊗ h)) ≫ (α_ X Y Z).hom =
    (λ_ (𝟙_ C)).inv ≫ (f ⊗ (λ_ (𝟙_ C)).inv ≫ (g ⊗ h))

Next tactic:
simp only [Iso.cancel_iso_inv_left, Category.assoc]
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      

Proof state:
case h.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : 𝟙_ C ⟶ Z
f : 𝟙_ C ⟶ X
g : 𝟙_ C ⟶ Y
⊢ ((λ_ (𝟙_ C)).inv ≫ (f ⊗ g) ⊗ h) ≫ (α_ X Y Z).hom = f ⊗ (λ_ (𝟙_ C)).inv ≫ (g ⊗ h)

Next tactic:
conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : 𝟙_ C ⟶ Z
f : 𝟙_ C ⟶ X
g : 𝟙_ C ⟶ Y
| ((λ_ (𝟙_ C)).inv ≫ (f ⊗ g) ⊗ h) ≫ (α_ X Y Z).hom

Next tactic:
rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
      

Proof state:
case h.mk.mk
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : 𝟙_ C ⟶ Z
f : 𝟙_ C ⟶ X
g : 𝟙_ C ⟶ Y
⊢ (𝟙 (𝟙_ C) ⊗ (λ_ (𝟙_ C)).inv) ≫ (f ⊗ g ⊗ h) = f ⊗ (λ_ (𝟙_ C)).inv ≫ (g ⊗ h)

Next tactic:
conv_rhs => rw [← Category.id_comp f, tensor_comp]
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
      conv_rhs => 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X Y Z : C
h : 𝟙_ C ⟶ Z
f : 𝟙_ C ⟶ X
g : 𝟙_ C ⟶ Y
| f ⊗ (λ_ (𝟙_ C)).inv ≫ (g ⊗ h)

Next tactic:
rw [← Category.id_comp f, tensor_comp]
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
      conv_rhs => rw [← Category.id_comp f, tensor_comp]
    left_unitality := by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
⊢ ∀ (X : C),
    (λ_ ((Functor.mk src✝.toPrefunctor).obj X)).hom =
      ((fun _p => 𝟙 (op (𝟙_ C)).unop) ⊗ 𝟙 ((Functor.mk src✝.toPrefunctor).obj X)) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) (𝟙_ C) X ≫ (Functor.mk src✝.toPrefunctor).map (λ_ X).hom

Next tactic:
aesop_cat
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
      conv_rhs => rw [← Category.id_comp f, tensor_comp]
    left_unitality := by aesop_cat
    right_unitality := fun X => by
      

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X : C
⊢ (ρ_ ((Functor.mk src✝.toPrefunctor).obj X)).hom =
    (𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ fun _p => 𝟙 (op (𝟙_ C)).unop) ≫
      (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X (𝟙_ C) ≫ (Functor.mk src✝.toPrefunctor).map (ρ_ X).hom

Next tactic:
ext ⟨f, ⟨⟩⟩
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
      conv_rhs => rw [← Category.id_comp f, tensor_comp]
    left_unitality := by aesop_cat
    right_unitality := fun X => by
      ext ⟨f, ⟨⟩⟩; 

Proof state:
case h.mk.unit
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X : C
f : (Functor.mk src✝.toPrefunctor).obj X
⊢ (ρ_ ((Functor.mk src✝.toPrefunctor).obj X)).hom (f, PUnit.unit) =
    ((𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ fun _p => 𝟙 (op (𝟙_ C)).unop) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X (𝟙_ C) ≫ (Functor.mk src✝.toPrefunctor).map (ρ_ X).hom)
      (f, PUnit.unit)

Next tactic:
dsimp at f
/-- `(𝟙_ C ⟶ -)` is a lax monoidal functor to `Type`. -/
noncomputable
def coyonedaTensorUnit (C : Type u) [Category.{v} C] [MonoidalCategory C] :
    LaxMonoidalFunctor C (Type v) :=
  { coyoneda.obj (op (𝟙_ C)) with
    ε := fun _p => 𝟙 _
    μ := fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)
    μ_natural := by aesop_cat
    associativity := fun X Y Z => by
      ext ⟨⟨f, g⟩, h⟩; dsimp at f g h
      dsimp; simp only [Iso.cancel_iso_inv_left, Category.assoc]
      conv_lhs =>
        rw [← Category.id_comp h, tensor_comp, Category.assoc, associator_naturality, ←
          Category.assoc, unitors_inv_equal, triangle_assoc_comp_right_inv]
      conv_rhs => rw [← Category.id_comp f, tensor_comp]
    left_unitality := by aesop_cat
    right_unitality := fun X => by
      ext ⟨f, ⟨⟩⟩; dsimp at f
      

Proof state:
case h.mk.unit
C : Type u
inst✝¹ : Category.{v, u} C
inst✝ : MonoidalCategory C
src✝ : C ⥤ Type v := coyoneda.obj (op (𝟙_ C))
X : C
f : 𝟙_ C ⟶ X
⊢ (ρ_ ((Functor.mk src✝.toPrefunctor).obj X)).hom (f, PUnit.unit) =
    ((𝟙 ((Functor.mk src✝.toPrefunctor).obj X) ⊗ fun _p => 𝟙 (op (𝟙_ C)).unop) ≫
        (fun X Y p => (λ_ (𝟙_ C)).inv ≫ (p.1 ⊗ p.2)) X (𝟙_ C) ≫ (Functor.mk src✝.toPrefunctor).map (ρ_ X).hom)
      (f, PUnit.unit)

Next tactic:
dsimp