l3lab/ntp-mathlib huggingface dataset:
theorem wittStructureRat_vars [Fintype idx] (Φ : MvPolynomial idx ℚ) (n : ℕ) :
    (wittStructureRat p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) := by
  rw [wittStructureRat]
  intro x hx
  simp only [Finset.mem_product, true_and_iff, Finset.mem_univ, Finset.mem_range]
  obtain ⟨k, hk, hx'⟩ := mem_vars_bind₁ _ _ hx
  obtain ⟨i, -, hx''⟩ := mem_vars_bind₁ _ _ hx'
  obtain ⟨j, hj, rfl⟩ := mem_vars_rename _ _ hx''
  rw [wittPolynomial_vars, Finset.mem_range] at hj
  replace hk := xInTermsOfW_vars_subset p _ hk
  

Proof state:
case intro.intro.intro.intro.intro.intro
p : ℕ
R : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
hp : Fact (Nat.Prime p)
inst✝ : Fintype idx
Φ : MvPolynomial idx ℚ
n k : ℕ
i : idx
j : ℕ
hj : j < k + 1
hx : (i, j) ∈ vars ((bind₁ fun k => (bind₁ fun i => (rename (Prod.mk i)) (W_ ℚ k)) Φ) (xInTermsOfW p ℚ n))
hx' : (i, j) ∈ vars ((bind₁ fun i => (rename (Prod.mk i)) (W_ ℚ k)) Φ)
hx'' : (i, j) ∈ vars ((rename (Prod.mk i)) (W_ ℚ k))
hk : k ∈ Finset.range (n + 1)
⊢ (i, j).2 < n + 1

Next tactic:
rw [Finset.mem_range] at hk
theorem wittStructureRat_vars [Fintype idx] (Φ : MvPolynomial idx ℚ) (n : ℕ) :
    (wittStructureRat p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) := by
  rw [wittStructureRat]
  intro x hx
  simp only [Finset.mem_product, true_and_iff, Finset.mem_univ, Finset.mem_range]
  obtain ⟨k, hk, hx'⟩ := mem_vars_bind₁ _ _ hx
  obtain ⟨i, -, hx''⟩ := mem_vars_bind₁ _ _ hx'
  obtain ⟨j, hj, rfl⟩ := mem_vars_rename _ _ hx''
  rw [wittPolynomial_vars, Finset.mem_range] at hj
  replace hk := xInTermsOfW_vars_subset p _ hk
  rw [Finset.mem_range] at hk
  

Proof state:
case intro.intro.intro.intro.intro.intro
p : ℕ
R : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
hp : Fact (Nat.Prime p)
inst✝ : Fintype idx
Φ : MvPolynomial idx ℚ
n k : ℕ
i : idx
j : ℕ
hj : j < k + 1
hx : (i, j) ∈ vars ((bind₁ fun k => (bind₁ fun i => (rename (Prod.mk i)) (W_ ℚ k)) Φ) (xInTermsOfW p ℚ n))
hx' : (i, j) ∈ vars ((bind₁ fun i => (rename (Prod.mk i)) (W_ ℚ k)) Φ)
hx'' : (i, j) ∈ vars ((rename (Prod.mk i)) (W_ ℚ k))
hk : k < n + 1
⊢ (i, j).2 < n + 1

Next tactic:
exact lt_of_lt_of_le hj hk
theorem wittStructureInt_vars [Fintype idx] (Φ : MvPolynomial idx ℤ) (n : ℕ) :
    (wittStructureInt p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) := by
  

Proof state:
p : ℕ
R : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
hp : Fact (Nat.Prime p)
inst✝ : Fintype idx
Φ : MvPolynomial idx ℤ
n : ℕ
⊢ vars (wittStructureInt p Φ n) ⊆ Finset.univ ×ˢ Finset.range (n + 1)

Next tactic:
have : Function.Injective (Int.castRingHom ℚ) := Int.cast_injective
theorem wittStructureInt_vars [Fintype idx] (Φ : MvPolynomial idx ℤ) (n : ℕ) :
    (wittStructureInt p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) := by
  have : Function.Injective (Int.castRingHom ℚ) := Int.cast_injective
  

Proof state:
p : ℕ
R : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
hp : Fact (Nat.Prime p)
inst✝ : Fintype idx
Φ : MvPolynomial idx ℤ
n : ℕ
this : Function.Injective ⇑(Int.castRingHom ℚ)
⊢ vars (wittStructureInt p Φ n) ⊆ Finset.univ ×ˢ Finset.range (n + 1)

Next tactic:
rw [← vars_map_of_injective _ this, map_wittStructureInt]
theorem wittStructureInt_vars [Fintype idx] (Φ : MvPolynomial idx ℤ) (n : ℕ) :
    (wittStructureInt p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) := by
  have : Function.Injective (Int.castRingHom ℚ) := Int.cast_injective
  rw [← vars_map_of_injective _ this, map_wittStructureInt]
  

Proof state:
p : ℕ
R : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
hp : Fact (Nat.Prime p)
inst✝ : Fintype idx
Φ : MvPolynomial idx ℤ
n : ℕ
this : Function.Injective ⇑(Int.castRingHom ℚ)
⊢ vars (wittStructureRat p ((map (Int.castRingHom ℚ)) Φ) n) ⊆ Finset.univ ×ˢ Finset.range (n + 1)

Next tactic:
apply wittStructureRat_vars
/-- A helper structure to construct the shift functor `(Discrete A) ⥤ (C ⥤ C)`. -/
structure ShiftMkCore where
  /-- the family of shift functors -/
  F : A → C ⥤ C
  /-- the shift by 0 identifies to the identity functor -/
  zero : F 0 ≅ 𝟭 C
  /-- the composition of shift functors identifies to the shift by the sum -/
  add : ∀ n m : A, F (n + m) ≅ F n ⋙ F m
  /-- compatibility with the associativity -/
  assoc_hom_app : ∀ (m₁ m₂ m₃ : A) (X : C),
    (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
      eqToHom (by 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
F : A → C ⥤ C
zero : F 0 ≅ 𝟭 C
add : (n m : A) → F (n + m) ≅ F n ⋙ F m
m₁ m₂ m₃ : A
X : C
⊢ (F (m₁ + m₂ + m₃)).obj X = (F (m₁ + (m₂ + m₃))).obj X

Next tactic:
rw [add_assoc]
/-- A helper structure to construct the shift functor `(Discrete A) ⥤ (C ⥤ C)`. -/
structure ShiftMkCore where
  /-- the family of shift functors -/
  F : A → C ⥤ C
  /-- the shift by 0 identifies to the identity functor -/
  zero : F 0 ≅ 𝟭 C
  /-- the composition of shift functors identifies to the shift by the sum -/
  add : ∀ n m : A, F (n + m) ≅ F n ⋙ F m
  /-- compatibility with the associativity -/
  assoc_hom_app : ∀ (m₁ m₂ m₃ : A) (X : C),
    (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
      eqToHom (by rw [add_assoc]) ≫ (add m₁ (m₂ + m₃)).hom.app X ≫
        (add m₂ m₃).hom.app ((F m₁).obj X) := by aesop_cat
  /-- compatibility with the left addition with 0 -/
  zero_add_hom_app : ∀ (n : A) (X : C), (add 0 n).hom.app X =
    eqToHom (by 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
F : A → C ⥤ C
zero : F 0 ≅ 𝟭 C
add : (n m : A) → F (n + m) ≅ F n ⋙ F m
assoc_hom_app :
  autoParam
    (∀ (m₁ m₂ m₃ : A) (X : C),
      (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
        eqToHom (_ : (F (m₁ + m₂ + m₃)).obj X = (F (m₁ + (m₂ + m₃))).obj X) ≫
          (add m₁ (m₂ + m₃)).hom.app X ≫ (add m₂ m₃).hom.app ((F m₁).obj X))
    _auto✝
n : A
X : C
⊢ (F (0 + n)).obj X = (F n).obj ((𝟭 C).obj X)

Next tactic:
dsimp
/-- A helper structure to construct the shift functor `(Discrete A) ⥤ (C ⥤ C)`. -/
structure ShiftMkCore where
  /-- the family of shift functors -/
  F : A → C ⥤ C
  /-- the shift by 0 identifies to the identity functor -/
  zero : F 0 ≅ 𝟭 C
  /-- the composition of shift functors identifies to the shift by the sum -/
  add : ∀ n m : A, F (n + m) ≅ F n ⋙ F m
  /-- compatibility with the associativity -/
  assoc_hom_app : ∀ (m₁ m₂ m₃ : A) (X : C),
    (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
      eqToHom (by rw [add_assoc]) ≫ (add m₁ (m₂ + m₃)).hom.app X ≫
        (add m₂ m₃).hom.app ((F m₁).obj X) := by aesop_cat
  /-- compatibility with the left addition with 0 -/
  zero_add_hom_app : ∀ (n : A) (X : C), (add 0 n).hom.app X =
    eqToHom (by dsimp; 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
F : A → C ⥤ C
zero : F 0 ≅ 𝟭 C
add : (n m : A) → F (n + m) ≅ F n ⋙ F m
assoc_hom_app :
  autoParam
    (∀ (m₁ m₂ m₃ : A) (X : C),
      (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
        eqToHom (_ : (F (m₁ + m₂ + m₃)).obj X = (F (m₁ + (m₂ + m₃))).obj X) ≫
          (add m₁ (m₂ + m₃)).hom.app X ≫ (add m₂ m₃).hom.app ((F m₁).obj X))
    _auto✝
n : A
X : C
⊢ (F (0 + n)).obj X = (F n).obj X

Next tactic:
rw [zero_add]
/-- A helper structure to construct the shift functor `(Discrete A) ⥤ (C ⥤ C)`. -/
structure ShiftMkCore where
  /-- the family of shift functors -/
  F : A → C ⥤ C
  /-- the shift by 0 identifies to the identity functor -/
  zero : F 0 ≅ 𝟭 C
  /-- the composition of shift functors identifies to the shift by the sum -/
  add : ∀ n m : A, F (n + m) ≅ F n ⋙ F m
  /-- compatibility with the associativity -/
  assoc_hom_app : ∀ (m₁ m₂ m₃ : A) (X : C),
    (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
      eqToHom (by rw [add_assoc]) ≫ (add m₁ (m₂ + m₃)).hom.app X ≫
        (add m₂ m₃).hom.app ((F m₁).obj X) := by aesop_cat
  /-- compatibility with the left addition with 0 -/
  zero_add_hom_app : ∀ (n : A) (X : C), (add 0 n).hom.app X =
    eqToHom (by dsimp; rw [zero_add]) ≫ (F n).map (zero.inv.app X) := by aesop_cat
  /-- compatibility with the right addition with 0 -/
  add_zero_hom_app : ∀ (n : A) (X : C), (add n 0).hom.app X =
    eqToHom (by 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
F : A → C ⥤ C
zero : F 0 ≅ 𝟭 C
add : (n m : A) → F (n + m) ≅ F n ⋙ F m
assoc_hom_app :
  autoParam
    (∀ (m₁ m₂ m₃ : A) (X : C),
      (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
        eqToHom (_ : (F (m₁ + m₂ + m₃)).obj X = (F (m₁ + (m₂ + m₃))).obj X) ≫
          (add m₁ (m₂ + m₃)).hom.app X ≫ (add m₂ m₃).hom.app ((F m₁).obj X))
    _auto✝
zero_add_hom_app :
  autoParam
    (∀ (n : A) (X : C),
      (add 0 n).hom.app X = eqToHom (_ : (F (0 + n)).obj X = (F n).obj ((𝟭 C).obj X)) ≫ (F n).map (zero.inv.app X))
    _auto✝
n : A
X : C
⊢ (F (n + 0)).obj X = (𝟭 C).obj ((F n).obj X)

Next tactic:
dsimp
/-- A helper structure to construct the shift functor `(Discrete A) ⥤ (C ⥤ C)`. -/
structure ShiftMkCore where
  /-- the family of shift functors -/
  F : A → C ⥤ C
  /-- the shift by 0 identifies to the identity functor -/
  zero : F 0 ≅ 𝟭 C
  /-- the composition of shift functors identifies to the shift by the sum -/
  add : ∀ n m : A, F (n + m) ≅ F n ⋙ F m
  /-- compatibility with the associativity -/
  assoc_hom_app : ∀ (m₁ m₂ m₃ : A) (X : C),
    (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
      eqToHom (by rw [add_assoc]) ≫ (add m₁ (m₂ + m₃)).hom.app X ≫
        (add m₂ m₃).hom.app ((F m₁).obj X) := by aesop_cat
  /-- compatibility with the left addition with 0 -/
  zero_add_hom_app : ∀ (n : A) (X : C), (add 0 n).hom.app X =
    eqToHom (by dsimp; rw [zero_add]) ≫ (F n).map (zero.inv.app X) := by aesop_cat
  /-- compatibility with the right addition with 0 -/
  add_zero_hom_app : ∀ (n : A) (X : C), (add n 0).hom.app X =
    eqToHom (by dsimp; 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
F : A → C ⥤ C
zero : F 0 ≅ 𝟭 C
add : (n m : A) → F (n + m) ≅ F n ⋙ F m
assoc_hom_app :
  autoParam
    (∀ (m₁ m₂ m₃ : A) (X : C),
      (add (m₁ + m₂) m₃).hom.app X ≫ (F m₃).map ((add m₁ m₂).hom.app X) =
        eqToHom (_ : (F (m₁ + m₂ + m₃)).obj X = (F (m₁ + (m₂ + m₃))).obj X) ≫
          (add m₁ (m₂ + m₃)).hom.app X ≫ (add m₂ m₃).hom.app ((F m₁).obj X))
    _auto✝
zero_add_hom_app :
  autoParam
    (∀ (n : A) (X : C),
      (add 0 n).hom.app X = eqToHom (_ : (F (0 + n)).obj X = (F n).obj ((𝟭 C).obj X)) ≫ (F n).map (zero.inv.app X))
    _auto✝
n : A
X : C
⊢ (F (n + 0)).obj X = (F n).obj X

Next tactic:
rw [add_zero]
@[reassoc]
lemma assoc_inv_app (h : ShiftMkCore C A) (m₁ m₂ m₃ : A) (X : C) :
    (h.F m₃).map ((h.add m₁ m₂).inv.app X) ≫ (h.add (m₁ + m₂) m₃).inv.app X =
    (h.add m₂ m₃).inv.app ((h.F m₁).obj X) ≫ (h.add m₁ (m₂ + m₃)).inv.app X ≫
      eqToHom (by 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
m₁ m₂ m₃ : A
X : C
⊢ (F h (m₁ + (m₂ + m₃))).obj X = (F h (m₁ + m₂ + m₃)).obj X

Next tactic:
rw [add_assoc]
@[reassoc]
lemma assoc_inv_app (h : ShiftMkCore C A) (m₁ m₂ m₃ : A) (X : C) :
    (h.F m₃).map ((h.add m₁ m₂).inv.app X) ≫ (h.add (m₁ + m₂) m₃).inv.app X =
    (h.add m₂ m₃).inv.app ((h.F m₁).obj X) ≫ (h.add m₁ (m₂ + m₃)).inv.app X ≫
      eqToHom (by rw [add_assoc]) := by
  

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
m₁ m₂ m₃ : A
X : C
⊢ (F h m₃).map ((add h m₁ m₂).inv.app X) ≫ (add h (m₁ + m₂) m₃).inv.app X =
    (add h m₂ m₃).inv.app ((F h m₁).obj X) ≫
      (add h m₁ (m₂ + m₃)).inv.app X ≫ eqToHom (_ : (F h (m₁ + (m₂ + m₃))).obj X = (F h (m₁ + m₂ + m₃)).obj X)

Next tactic:
rw [← cancel_mono ((h.add (m₁ + m₂) m₃).hom.app X ≫ (h.F m₃).map ((h.add m₁ m₂).hom.app X)),
    Category.assoc, Category.assoc, Category.assoc, Iso.inv_hom_id_app_assoc, ← Functor.map_comp,
    Iso.inv_hom_id_app, Functor.map_id, h.assoc_hom_app, eqToHom_trans_assoc, eqToHom_refl,
    Category.id_comp, Iso.inv_hom_id_app_assoc, Iso.inv_hom_id_app]
@[reassoc]
lemma assoc_inv_app (h : ShiftMkCore C A) (m₁ m₂ m₃ : A) (X : C) :
    (h.F m₃).map ((h.add m₁ m₂).inv.app X) ≫ (h.add (m₁ + m₂) m₃).inv.app X =
    (h.add m₂ m₃).inv.app ((h.F m₁).obj X) ≫ (h.add m₁ (m₂ + m₃)).inv.app X ≫
      eqToHom (by rw [add_assoc]) := by
  rw [← cancel_mono ((h.add (m₁ + m₂) m₃).hom.app X ≫ (h.F m₃).map ((h.add m₁ m₂).hom.app X)),
    Category.assoc, Category.assoc, Category.assoc, Iso.inv_hom_id_app_assoc, ← Functor.map_comp,
    Iso.inv_hom_id_app, Functor.map_id, h.assoc_hom_app, eqToHom_trans_assoc, eqToHom_refl,
    Category.id_comp, Iso.inv_hom_id_app_assoc, Iso.inv_hom_id_app]
  

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
m₁ m₂ m₃ : A
X : C
⊢ 𝟙 ((F h m₃).obj ((F h m₁ ⋙ F h m₂).obj X)) = 𝟙 ((F h m₂ ⋙ F h m₃).obj ((F h m₁).obj X))

Next tactic:
rfl
lemma zero_add_inv_app (h : ShiftMkCore C A) (n : A) (X : C) :
    (h.add 0 n).inv.app X = (h.F n).map (h.zero.hom.app X) ≫
      eqToHom (by 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
n : A
X : C
⊢ (F h n).obj ((𝟭 C).obj X) = (F h (0 + n)).obj X

Next tactic:
dsimp
lemma zero_add_inv_app (h : ShiftMkCore C A) (n : A) (X : C) :
    (h.add 0 n).inv.app X = (h.F n).map (h.zero.hom.app X) ≫
      eqToHom (by dsimp; 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
n : A
X : C
⊢ (F h n).obj X = (F h (0 + n)).obj X

Next tactic:
rw [zero_add]
lemma zero_add_inv_app (h : ShiftMkCore C A) (n : A) (X : C) :
    (h.add 0 n).inv.app X = (h.F n).map (h.zero.hom.app X) ≫
      eqToHom (by dsimp; rw [zero_add]) := by
  

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
n : A
X : C
⊢ (add h 0 n).inv.app X = (F h n).map (h.zero.hom.app X) ≫ eqToHom (_ : (F h n).obj ((𝟭 C).obj X) = (F h (0 + n)).obj X)

Next tactic:
rw [← cancel_epi ((h.add 0 n).hom.app X), Iso.hom_inv_id_app, h.zero_add_hom_app,
    Category.assoc, ← Functor.map_comp_assoc, Iso.inv_hom_id_app, Functor.map_id,
    Category.id_comp, eqToHom_trans, eqToHom_refl]
lemma add_zero_inv_app (h : ShiftMkCore C A) (n : A) (X : C) :
    (h.add n 0).inv.app X = h.zero.hom.app ((h.F n).obj X) ≫
      eqToHom (by 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
n : A
X : C
⊢ (𝟭 C).obj ((F h n).obj X) = (F h (n + 0)).obj X

Next tactic:
dsimp
lemma add_zero_inv_app (h : ShiftMkCore C A) (n : A) (X : C) :
    (h.add n 0).inv.app X = h.zero.hom.app ((h.F n).obj X) ≫
      eqToHom (by dsimp; 

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
n : A
X : C
⊢ (F h n).obj X = (F h (n + 0)).obj X

Next tactic:
rw [add_zero]
lemma add_zero_inv_app (h : ShiftMkCore C A) (n : A) (X : C) :
    (h.add n 0).inv.app X = h.zero.hom.app ((h.F n).obj X) ≫
      eqToHom (by dsimp; rw [add_zero]) := by
  

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
n : A
X : C
⊢ (add h n 0).inv.app X = h.zero.hom.app ((F h n).obj X) ≫ eqToHom (_ : (𝟭 C).obj ((F h n).obj X) = (F h (n + 0)).obj X)

Next tactic:
rw [← cancel_epi ((h.add n 0).hom.app X), Iso.hom_inv_id_app, h.add_zero_hom_app,
    Category.assoc, Iso.inv_hom_id_app_assoc, eqToHom_trans, eqToHom_refl]
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
⊢ ∀ {X Y X' Y' : Discrete A} (f : X ⟶ Y) (g : X' ⟶ Y'),
    MonoidalCategory.tensorHom ((Functor.mk src✝.toPrefunctor).map f) ((Functor.mk src✝.toPrefunctor).map g) ≫
        (fun m n => (ShiftMkCore.add h m.as n.as).inv) Y Y' =
      (fun m n => (ShiftMkCore.add h m.as n.as).inv) X X' ≫
        (Functor.mk src✝.toPrefunctor).map (MonoidalCategory.tensorHom f g)

Next tactic:
rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
        

Proof state:
case mk.mk.mk.mk.up.up.refl.up.up.refl
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
X X' : A
⊢ MonoidalCategory.tensorHom
        ((Functor.mk src✝.toPrefunctor).map { down := { down := (_ : { as := X }.as = { as := X }.as) } })
        ((Functor.mk src✝.toPrefunctor).map { down := { down := (_ : { as := X' }.as = { as := X' }.as) } }) ≫
      (fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := X } { as := X' } =
    (fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := X } { as := X' } ≫
      (Functor.mk src✝.toPrefunctor).map
        (MonoidalCategory.tensorHom { down := { down := (_ : { as := X }.as = { as := X }.as) } }
          { down := { down := (_ : { as := X' }.as = { as := X' }.as) } })

Next tactic:
ext
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
        ext
        

Proof state:
case mk.mk.mk.mk.up.up.refl.up.up.refl.w.h
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
X X' : A
x✝ : C
⊢ (MonoidalCategory.tensorHom
            ((Functor.mk src✝.toPrefunctor).map { down := { down := (_ : { as := X }.as = { as := X }.as) } })
            ((Functor.mk src✝.toPrefunctor).map { down := { down := (_ : { as := X' }.as = { as := X' }.as) } }) ≫
          (fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := X } { as := X' }).app
      x✝ =
    ((fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := X } { as := X' } ≫
          (Functor.mk src✝.toPrefunctor).map
            (MonoidalCategory.tensorHom { down := { down := (_ : { as := X }.as = { as := X }.as) } }
              { down := { down := (_ : { as := X' }.as = { as := X' }.as) } })).app
      x✝

Next tactic:
dsimp
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
        ext
        dsimp
        

Proof state:
case mk.mk.mk.mk.up.up.refl.up.up.refl.w.h
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
X X' : A
x✝ : C
⊢ (((Discrete.functor h.F).map { down := { down := (_ : X' = X') } }).app ((ShiftMkCore.F h X).obj x✝) ≫
        (ShiftMkCore.F h X').map (((Discrete.functor h.F).map { down := { down := (_ : X = X) } }).app x✝)) ≫
      (ShiftMkCore.add h X X').inv.app x✝ =
    (ShiftMkCore.add h X X').inv.app x✝ ≫
      ((Discrete.functor h.F).map
            (MonoidalCategory.tensorHom { down := { down := (_ : X = X) } } { down := { down := (_ : X' = X') } })).app
        x✝

Next tactic:
simp
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
        ext
        dsimp
        simp
      associativity := by
        

Proof state:
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
⊢ ∀ (X Y Z : Discrete A),
    MonoidalCategory.tensorHom ((fun m n => (ShiftMkCore.add h m.as n.as).inv) X Y)
          (𝟙 ((Functor.mk src✝.toPrefunctor).obj Z)) ≫
        (fun m n => (ShiftMkCore.add h m.as n.as).inv) (MonoidalCategory.tensorObj X Y) Z ≫
          (Functor.mk src✝.toPrefunctor).map (MonoidalCategory.associator X Y Z).hom =
      (MonoidalCategory.associator ((Functor.mk src✝.toPrefunctor).obj X) ((Functor.mk src✝.toPrefunctor).obj Y)
            ((Functor.mk src✝.toPrefunctor).obj Z)).hom ≫
        MonoidalCategory.tensorHom (𝟙 ((Functor.mk src✝.toPrefunctor).obj X))
            ((fun m n => (ShiftMkCore.add h m.as n.as).inv) Y Z) ≫
          (fun m n => (ShiftMkCore.add h m.as n.as).inv) X (MonoidalCategory.tensorObj Y Z)

Next tactic:
rintro ⟨m₁⟩ ⟨m₂⟩ ⟨m₃⟩
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
        ext
        dsimp
        simp
      associativity := by
        rintro ⟨m₁⟩ ⟨m₂⟩ ⟨m₃⟩
        

Proof state:
case mk.mk.mk
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
m₁ m₂ m₃ : A
⊢ MonoidalCategory.tensorHom ((fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := m₁ } { as := m₂ })
        (𝟙 ((Functor.mk src✝.toPrefunctor).obj { as := m₃ })) ≫
      (fun m n => (ShiftMkCore.add h m.as n.as).inv) (MonoidalCategory.tensorObj { as := m₁ } { as := m₂ })
          { as := m₃ } ≫
        (Functor.mk src✝.toPrefunctor).map (MonoidalCategory.associator { as := m₁ } { as := m₂ } { as := m₃ }).hom =
    (MonoidalCategory.associator ((Functor.mk src✝.toPrefunctor).obj { as := m₁ })
          ((Functor.mk src✝.toPrefunctor).obj { as := m₂ }) ((Functor.mk src✝.toPrefunctor).obj { as := m₃ })).hom ≫
      MonoidalCategory.tensorHom (𝟙 ((Functor.mk src✝.toPrefunctor).obj { as := m₁ }))
          ((fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := m₂ } { as := m₃ }) ≫
        (fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := m₁ }
          (MonoidalCategory.tensorObj { as := m₂ } { as := m₃ })

Next tactic:
ext X
/-- Constructs a `HasShift C A` instance from `ShiftMkCore`. -/
@[simps]
def hasShiftMk (h : ShiftMkCore C A) : HasShift C A :=
  ⟨{ Discrete.functor h.F with
      ε := h.zero.inv
      μ := fun m n => (h.add m.as n.as).inv
      μ_natural := by
        rintro ⟨X⟩ ⟨Y⟩ ⟨X'⟩ ⟨Y'⟩ ⟨⟨⟨rfl⟩⟩⟩ ⟨⟨⟨rfl⟩⟩⟩
        ext
        dsimp
        simp
      associativity := by
        rintro ⟨m₁⟩ ⟨m₂⟩ ⟨m₃⟩
        ext X
        

Proof state:
case mk.mk.mk.w.h
C : Type u
A : Type u_1
inst✝¹ : Category.{v, u} C
inst✝ : AddMonoid A
h : ShiftMkCore C A
src✝ : Discrete A ⥤ C ⥤ C := Discrete.functor h.F
m₁ m₂ m₃ : A
X : C
⊢ (MonoidalCategory.tensorHom ((fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := m₁ } { as := m₂ })
            (𝟙 ((Functor.mk src✝.toPrefunctor).obj { as := m₃ })) ≫
          (fun m n => (ShiftMkCore.add h m.as n.as).inv) (MonoidalCategory.tensorObj { as := m₁ } { as := m₂ })
              { as := m₃ } ≫
            (Functor.mk src✝.toPrefunctor).map
              (MonoidalCategory.associator { as := m₁ } { as := m₂ } { as := m₃ }).hom).app
      X =
    ((MonoidalCategory.associator ((Functor.mk src✝.toPrefunctor).obj { as := m₁ })
              ((Functor.mk src✝.toPrefunctor).obj { as := m₂ }) ((Functor.mk src✝.toPrefunctor).obj { as := m₃ })).hom ≫
          MonoidalCategory.tensorHom (𝟙 ((Functor.mk src✝.toPrefunctor).obj { as := m₁ }))
              ((fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := m₂ } { as := m₃ }) ≫
            (fun m n => (ShiftMkCore.add h m.as n.as).inv) { as := m₁ }
              (MonoidalCategory.tensorObj { as := m₂ } { as := m₃ })).app
      X

Next tactic:
simp [endofunctorMonoidalCategory, h.assoc_inv_app_assoc]