-- Mathlib/CategoryTheory/Shift/Pullback.lean
lemma pullbackShiftFunctorAdd'_inv_app :
    (shiftFunctorAdd' _ a₁ a₂ a₃ h).inv.app X =
      (shiftFunctor (PullbackShift C φ) a₂).map ((pullbackShiftIso C φ a₁ b₁ h₁).hom.app X) ≫
        (pullbackShiftIso C φ a₂ b₂ h₂).hom.app _ ≫
        (shiftFunctorAdd' C b₁ b₂ b₃ (by rw [h₁, h₂, h₃, ← h, φ.map_add])).inv.app X ≫
        (pullbackShiftIso C φ a₃ b₃ h₃).inv.app X

Proof state:
C : Type u_1
inst✝³ : Category.{?u.25018, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ a₃ : A
h : a₁ + a₂ = a₃
b₁ b₂ b₃ : B
h₁ : b₁ = φ a₁
h₂ : b₂ = φ a₂
h₃ : b₃ = φ a₃
⊢ b₁ + b₂ = b₃

Tactic:
rw [h₁, h₂, h₃, ← h, φ.map_add]

Result:
no goals

Proof state:
case e_a
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ ((shiftMonoidalFunctor C B).map (Functor.LaxMonoidal.μ (Discrete.addMonoidalFunctor φ) { as := a₁ } { as := a₂ })).app
      X =
    (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Tactic:
rw [Discrete.addMonoidalFunctor_μ]

Result:
case e_a
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ ((shiftMonoidalFunctor C B).map (Discrete.eqToHom ⋯)).app X =
    (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Proof state:
case e_a.e_self
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (shiftMonoidalFunctor C B).map (eqToHom ⋯) = (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv

Tactic:
apply eqToHom_map

Result:
no goals

Proof state:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
b₃ : B
h₃ : b₃ = φ (a₁ + a₂)
⊢ b₃ = φ a₁ + φ a₂

Tactic:
rw [h₃, φ.map_add]

Result:
no goals

Proof state:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (Functor.LaxMonoidal.μ (shiftMonoidalFunctor C B) ((Discrete.addMonoidalFunctor φ).obj { as := a₁ })
            ((Discrete.addMonoidalFunctor φ).obj { as := a₂ })).app
        X ≫
      ((shiftMonoidalFunctor C B).map
            (Functor.LaxMonoidal.μ (Discrete.addMonoidalFunctor φ) { as := a₁ } { as := a₂ })).app
        X =
    (shiftFunctorAdd C (φ a₁) (φ a₂)).inv.app X ≫ (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Tactic:
congr 1

Result:
case e_a
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ ((shiftMonoidalFunctor C B).map (Functor.LaxMonoidal.μ (Discrete.addMonoidalFunctor φ) { as := a₁ } { as := a₂ })).app
      X =
    (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Proof state:
case e_a
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ ((shiftMonoidalFunctor C B).map (Discrete.eqToHom ⋯)).app X =
    (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Tactic:
dsimp [Discrete.eqToHom]

Result:
case e_a
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ ((shiftMonoidalFunctor C B).map (eqToHom ⋯)).app X = (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Proof state:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (shiftFunctorAdd' (PullbackShift C φ) a₁ a₂ (a₁ + a₂) ⋯).inv.app X =
    (shiftFunctor (PullbackShift C φ) a₂).map ((pullbackShiftIso C φ a₁ (φ a₁) ⋯).hom.app X) ≫
      (pullbackShiftIso C φ a₂ (φ a₂) ⋯).hom.app ((shiftFunctor C (φ a₁)).obj X) ≫
        (shiftFunctorAdd' C (φ a₁) (φ a₂) (φ a₁ + φ a₂) ⋯).inv.app X ≫
          (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Tactic:
simp only [Functor.comp_obj, NatTrans.naturality_assoc]

Result:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (shiftFunctorAdd' (PullbackShift C φ) a₁ a₂ (a₁ + a₂) ⋯).inv.app X =
    (pullbackShiftIso C φ a₂ (φ a₂) ⋯).hom.app ((shiftFunctor (PullbackShift C φ) a₁).obj X) ≫
      (shiftFunctor C (φ a₂)).map ((pullbackShiftIso C φ a₁ (φ a₁) ⋯).hom.app X) ≫
        (shiftFunctorAdd' C (φ a₁) (φ a₂) (φ a₁ + φ a₂) ⋯).inv.app X ≫
          (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Proof state:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (shiftFunctorAdd' (PullbackShift C φ) a₁ a₂ (a₁ + a₂) ⋯).inv.app X =
    (pullbackShiftIso C φ a₂ (φ a₂) ⋯).hom.app ((shiftFunctor (PullbackShift C φ) a₁).obj X) ≫
      (shiftFunctor C (φ a₂)).map ((pullbackShiftIso C φ a₁ (φ a₁) ⋯).hom.app X) ≫
        (shiftFunctorAdd' C (φ a₁) (φ a₂) (φ a₁ + φ a₂) ⋯).inv.app X ≫
          (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Tactic:
erw [Functor.map_id, id_comp, id_comp, shiftFunctorAdd'_eq_shiftFunctorAdd,
  shiftFunctorAdd'_eq_shiftFunctorAdd]

Result:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (shiftFunctorAdd (PullbackShift C φ) a₁ a₂).inv.app X =
    (shiftFunctorAdd C (φ a₁) (φ a₂)).inv.app X ≫ (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Proof state:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (shiftFunctorAdd (PullbackShift C φ) a₁ a₂).inv.app X =
    (shiftFunctorAdd C (φ a₁) (φ a₂)).inv.app X ≫ (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X

Tactic:
change _ ≫ _ = _

Result:
C : Type u_1
inst✝³ : Category.{u_4, u_1} C
A : Type u_2
B : Type u_3
inst✝² : AddMonoid A
inst✝¹ : AddMonoid B
φ : A →+ B
inst✝ : HasShift C B
X : PullbackShift C φ
a₁ a₂ : A
h₃ : φ a₁ + φ a₂ = φ (a₁ + a₂)
⊢ (Functor.LaxMonoidal.μ (shiftMonoidalFunctor C B) ((Discrete.addMonoidalFunctor φ).obj { as := a₁ })
            ((Discrete.addMonoidalFunctor φ).obj { as := a₂ })).app
        X ≫
      ((shiftMonoidalFunctor C B).map
            (Functor.LaxMonoidal.μ (Discrete.addMonoidalFunctor φ) { as := a₁ } { as := a₂ })).app
        X =
    (shiftFunctorAdd C (φ a₁) (φ a₂)).inv.app X ≫ (pullbackShiftIso C φ (a₁ + a₂) (φ a₁ + φ a₂) h₃).inv.app X