-- Mathlib/CategoryTheory/Shift/Basic.lean
@[reassoc]
lemma shiftFunctorComm_hom_app_comp_shift_shiftFunctorAdd_hom_app (m₁ m₂ m₃ : A) (X : C) :
    (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫
    ((shiftFunctorAdd C m₂ m₃).hom.app X)⟦m₁⟧' =
  (shiftFunctorAdd C m₂ m₃).hom.app (X⟦m₁⟧) ≫
    ((shiftFunctorComm C m₁ m₂).hom.app X)⟦m₃⟧' ≫
    (shiftFunctorComm C m₁ m₃).hom.app (X⟦m₂⟧)

Proof state:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫
      (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X) =
    (shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
      (shiftFunctor C m₃).map (𝟙 ((shiftFunctor C m₂).obj ((shiftFunctor C m₁).obj X)))

Tactic:
simp only [Functor.map_id, Category.comp_id,
  shiftFunctorComm_eq C _ _ _ rfl, ← shiftFunctorAdd'_eq_shiftFunctorAdd]

Result:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ ((shiftFunctorAdd' C m₁ (m₂ + m₃) (m₁ + (m₂ + m₃)) ⋯).symm ≪≫
              shiftFunctorAdd' C (m₂ + m₃) m₁ (m₁ + (m₂ + m₃)) ⋯).hom.app
        X ≫
      (shiftFunctor C m₁).map ((shiftFunctorAdd' C m₂ m₃ (m₂ + m₃) ⋯).hom.app X) ≫
        ((shiftFunctorAdd' C m₁ m₃ (m₁ + m₃) ⋯).symm ≪≫ shiftFunctorAdd' C m₃ m₁ (m₁ + m₃) ⋯).inv.app
            ((shiftFunctor C m₂).obj X) ≫
          (shiftFunctor C m₃).map
            (((shiftFunctorAdd' C m₁ m₂ (m₁ + m₂) ⋯).symm ≪≫ shiftFunctorAdd' C m₂ m₁ (m₁ + m₂) ⋯).inv.app X) =
    (shiftFunctorAdd' C m₂ m₃ (m₂ + m₃) ⋯).hom.app ((shiftFunctor C m₁).obj X)

Proof state:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ m₂ + m₁ + m₃ = m₁ + (m₂ + m₃)

Tactic:
rw [add_comm m₂ m₁, add_assoc]

Result:
no goals

Proof state:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ ((shiftFunctorAdd' C m₁ (m₂ + m₃) (m₁ + (m₂ + m₃)) ⋯).inv.app X ≫
        (shiftFunctorAdd' C (m₂ + m₃) m₁ (m₁ + (m₂ + m₃)) ⋯).hom.app X) ≫
      (shiftFunctor C m₁).map ((shiftFunctorAdd' C m₂ m₃ (m₂ + m₃) ⋯).hom.app X) ≫
        ((shiftFunctorAdd' C m₃ m₁ (m₁ + m₃) ⋯).inv.app ((shiftFunctor C m₂).obj X) ≫
            (shiftFunctorAdd' C m₁ m₃ (m₁ + m₃) ⋯).hom.app ((shiftFunctor C m₂).obj X)) ≫
          (shiftFunctor C m₃).map
            ((shiftFunctorAdd' C m₂ m₁ (m₁ + m₂) ⋯).inv.app X ≫ (shiftFunctorAdd' C m₁ m₂ (m₁ + m₂) ⋯).hom.app X) =
    (shiftFunctorAdd' C m₂ m₃ (m₂ + m₃) ⋯).hom.app ((shiftFunctor C m₁).obj X)

Tactic:
simp only [Category.assoc, Iso.hom_inv_id_app_assoc, Iso.inv_hom_id_app_assoc,
  ← Functor.map_comp,
  shiftFunctorAdd'_assoc_hom_app_assoc m₂ m₃ m₁ (m₂ + m₃) (m₁ + m₃) (m₁ + (m₂ + m₃)) rfl
    (add_comm m₃ m₁) (add_comm _ m₁) X,
  ← shiftFunctorAdd'_assoc_hom_app_assoc m₂ m₁ m₃ (m₁ + m₂) (m₁ + m₃)
    (m₁ + (m₂ + m₃)) (add_comm _ _) rfl (by rw [add_comm m₂ m₁, add_assoc]) X,
  shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃
    (m₁ + m₂) (m₂ + m₃) (m₁ + (m₂ + m₃)) rfl rfl (add_assoc _ _ _) X]

Result:
no goals

Proof state:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫ (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X) =
    (shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
      (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).hom.app X) ≫
        (shiftFunctorComm C m₁ m₃).hom.app ((shiftFunctor C m₂).obj X)

Tactic:
rw [← cancel_mono ((shiftFunctorComm C m₁ m₃).inv.app (X⟦m₂⟧)),
  ← cancel_mono (((shiftFunctorComm C m₁ m₂).inv.app X)⟦m₃⟧')]

Result:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (((shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫ (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X)) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X)) ≫
      (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X) =
    (((shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).hom.app X) ≫
            (shiftFunctorComm C m₁ m₃).hom.app ((shiftFunctor C m₂).obj X)) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X)) ≫
      (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X)

Proof state:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫
      (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X) =
    (shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
      (shiftFunctor C m₃).map (𝟙 ((shiftFunctor C m₁ ⋙ shiftFunctor C m₂).obj X))

Tactic:
dsimp

Result:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫
      (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X) =
    (shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
      (shiftFunctor C m₃).map (𝟙 ((shiftFunctor C m₂).obj ((shiftFunctor C m₁).obj X)))

Proof state:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (((shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫ (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X)) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X)) ≫
      (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X) =
    (((shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).hom.app X) ≫
            (shiftFunctorComm C m₁ m₃).hom.app ((shiftFunctor C m₂).obj X)) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X)) ≫
      (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X)

Tactic:
simp only [Category.assoc, Iso.hom_inv_id_app]

Result:
C : Type u
A : Type u_1
inst✝² : Category.{v, u} C
inst✝¹ : AddCommMonoid A
inst✝ : HasShift C A
m₁ m₂ m₃ : A
X : C
⊢ (shiftFunctorComm C m₁ (m₂ + m₃)).hom.app X ≫
      (shiftFunctor C m₁).map ((shiftFunctorAdd C m₂ m₃).hom.app X) ≫
        (shiftFunctorComm C m₁ m₃).inv.app ((shiftFunctor C m₂).obj X) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X) =
    (shiftFunctorAdd C m₂ m₃).hom.app ((shiftFunctor C m₁).obj X) ≫
      (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).hom.app X) ≫
        𝟙 ((shiftFunctor C m₁ ⋙ shiftFunctor C m₃).obj ((shiftFunctor C m₂).obj X)) ≫
          (shiftFunctor C m₃).map ((shiftFunctorComm C m₁ m₂).inv.app X)