l3lab/ntp-mathlib huggingface dataset:
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
m₁ m₂ m₃ : A
X : C
h :
  (shiftFunctorAdd D (m₁ + m₂) m₃).hom.app (F.obj X) ≫
      (shiftFunctor D m₃).map ((shiftFunctorAdd D m₁ m₂).hom.app (F.obj X)) =
    (shiftFunctorAdd' D m₁ (m₂ + m₃) (m₁ + m₂ + m₃) (_ : m₁ + (m₂ + m₃) = m₁ + m₂ + m₃)).hom.app (F.obj X) ≫
      (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X))
⊢ F.map
        ((hasShiftOfFullyFaithful_add F s i (m₁ + m₂) m₃).hom.app X ≫
          (s m₃).map ((hasShiftOfFullyFaithful_add F s i m₁ m₂).hom.app X)) ≫
      (i m₃).hom.app ((s m₂).obj ((s m₁).obj X)) =
    F.map
        (eqToHom (_ : (s (m₁ + m₂ + m₃)).obj X = (s (m₁ + (m₂ + m₃))).obj X) ≫
          (hasShiftOfFullyFaithful_add F s i m₁ (m₂ + m₃)).hom.app X ≫
            (hasShiftOfFullyFaithful_add F s i m₂ m₃).hom.app ((s m₁).obj X)) ≫
      (i m₃).hom.app ((s m₂).obj ((s m₁).obj X))

Next tactic:
simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
m₁ m₂ m₃ : A
X : C
h :
  (shiftFunctorAdd D (m₁ + m₂) m₃).hom.app (F.obj X) ≫
      (shiftFunctor D m₃).map ((shiftFunctorAdd D m₁ m₂).hom.app (F.obj X)) =
    (shiftFunctorAdd' D m₁ (m₂ + m₃) (m₁ + m₂ + m₃) (_ : m₁ + (m₂ + m₃) = m₁ + m₂ + m₃)).hom.app (F.obj X) ≫
      (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X))
⊢ (i (m₁ + m₂ + m₃)).hom.app X ≫
      (shiftFunctorAdd D (m₁ + m₂) m₃).hom.app (F.obj X) ≫
        (shiftFunctor D m₃).map ((i (m₁ + m₂)).inv.app X) ≫
          (i m₃).inv.app ((s (m₁ + m₂)).obj X) ≫
            F.map ((s m₃).map ((hasShiftOfFullyFaithful_add F s i m₁ m₂).hom.app X)) ≫
              (i m₃).hom.app ((s m₂).obj ((s m₁).obj X)) =
    F.map (eqToHom (_ : (s (m₁ + m₂ + m₃)).obj X = (s (m₁ + (m₂ + m₃))).obj X)) ≫
      (i (m₁ + (m₂ + m₃))).hom.app X ≫
        (shiftFunctorAdd D m₁ (m₂ + m₃)).hom.app (F.obj X) ≫
          (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X)) ≫
            (shiftFunctor D m₃).map ((shiftFunctor D m₂).map ((i m₁).inv.app X)) ≫
              (shiftFunctor D m₃).map ((i m₂).inv.app ((s m₁).obj X))

Next tactic:
erw [(i m₃).hom.naturality]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
m₁ m₂ m₃ : A
X : C
h :
  (shiftFunctorAdd D (m₁ + m₂) m₃).hom.app (F.obj X) ≫
      (shiftFunctor D m₃).map ((shiftFunctorAdd D m₁ m₂).hom.app (F.obj X)) =
    (shiftFunctorAdd' D m₁ (m₂ + m₃) (m₁ + m₂ + m₃) (_ : m₁ + (m₂ + m₃) = m₁ + m₂ + m₃)).hom.app (F.obj X) ≫
      (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X))
⊢ (i (m₁ + m₂ + m₃)).hom.app X ≫
      (shiftFunctorAdd D (m₁ + m₂) m₃).hom.app (F.obj X) ≫
        (shiftFunctor D m₃).map ((i (m₁ + m₂)).inv.app X) ≫
          (i m₃).inv.app ((s (m₁ + m₂)).obj X) ≫
            (i m₃).hom.app ((s (m₁ + m₂)).obj X) ≫
              (F ⋙ shiftFunctor D m₃).map ((hasShiftOfFullyFaithful_add F s i m₁ m₂).hom.app X) =
    F.map (eqToHom (_ : (s (m₁ + m₂ + m₃)).obj X = (s (m₁ + (m₂ + m₃))).obj X)) ≫
      (i (m₁ + (m₂ + m₃))).hom.app X ≫
        (shiftFunctorAdd D m₁ (m₂ + m₃)).hom.app (F.obj X) ≫
          (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X)) ≫
            (shiftFunctor D m₃).map ((shiftFunctor D m₂).map ((i m₁).inv.app X)) ≫
              (shiftFunctor D m₃).map ((i m₂).inv.app ((s m₁).obj X))

Next tactic:
rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
m₁ m₂ m₃ : A
X : C
h :
  (shiftFunctorAdd D (m₁ + m₂) m₃).hom.app (F.obj X) ≫
      (shiftFunctor D m₃).map ((shiftFunctorAdd D m₁ m₂).hom.app (F.obj X)) =
    (shiftFunctorAdd' D m₁ (m₂ + m₃) (m₁ + m₂ + m₃) (_ : m₁ + (m₂ + m₃) = m₁ + m₂ + m₃)).hom.app (F.obj X) ≫
      (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X))
⊢ (eqToHom (_ : (s (m₁ + m₂ + m₃) ⋙ F).obj X = (s (m₁ + (m₂ + m₃)) ⋙ F).obj X) ≫
        (i (m₁ + (m₂ + m₃))).hom.app X ≫
          eqToHom (_ : (F ⋙ shiftFunctor D (m₁ + (m₂ + m₃))).obj X = (F ⋙ shiftFunctor D (m₁ + m₂ + m₃)).obj X)) ≫
      (shiftFunctorAdd' D m₁ (m₂ + m₃) (m₁ + m₂ + m₃) (_ : m₁ + (m₂ + m₃) = m₁ + m₂ + m₃)).hom.app (F.obj X) ≫
        (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X)) ≫
          (shiftFunctor D m₃).map ((shiftFunctor D m₂).map ((i m₁).inv.app X) ≫ (i m₂).inv.app ((s m₁).obj X)) =
    F.map (eqToHom (_ : (s (m₁ + m₂ + m₃)).obj X = (s (m₁ + (m₂ + m₃))).obj X)) ≫
      (i (m₁ + (m₂ + m₃))).hom.app X ≫
        (shiftFunctorAdd D m₁ (m₂ + m₃)).hom.app (F.obj X) ≫
          (shiftFunctorAdd D m₂ m₃).hom.app ((shiftFunctor D m₁).obj (F.obj X)) ≫
            (shiftFunctor D m₃).map ((shiftFunctor D m₂).map ((i m₁).inv.app X)) ≫
              (shiftFunctor D m₃).map ((i m₂).inv.app ((s m₁).obj X))

Next tactic:
simp [shiftFunctorAdd', eqToHom_map]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        simp [shiftFunctorAdd', eqToHom_map])
      zero_add_hom_app := fun n X => F.map_injective (by
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
n : A
X : C
⊢ F.map ((hasShiftOfFullyFaithful_add F s i 0 n).hom.app X) =
    F.map
      (eqToHom (_ : (s (0 + n)).obj X = (s n).obj ((𝟭 C).obj X)) ≫
        (s n).map ((hasShiftOfFullyFaithful_zero F s i).inv.app X))

Next tactic:
have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n)
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        simp [shiftFunctorAdd', eqToHom_map])
      zero_add_hom_app := fun n X => F.map_injective (by
        have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n)
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
n : A
X : C
this :
  (i (0 + n)).hom.app X =
    eqToHom (_ : (s (0 + n) ⋙ F).obj X = (s n ⋙ F).obj X) ≫
      (i n).hom.app X ≫ eqToHom (_ : (F ⋙ shiftFunctor D n).obj X = (F ⋙ shiftFunctor D (0 + n)).obj X)
⊢ F.map ((hasShiftOfFullyFaithful_add F s i 0 n).hom.app X) =
    F.map
      (eqToHom (_ : (s (0 + n)).obj X = (s n).obj ((𝟭 C).obj X)) ≫
        (s n).map ((hasShiftOfFullyFaithful_zero F s i).inv.app X))

Next tactic:
rw [← cancel_mono ((i n).hom.app ((s 0).obj X)) ]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        simp [shiftFunctorAdd', eqToHom_map])
      zero_add_hom_app := fun n X => F.map_injective (by
        have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n)
        rw [← cancel_mono ((i n).hom.app ((s 0).obj X)) ]
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
n : A
X : C
this :
  (i (0 + n)).hom.app X =
    eqToHom (_ : (s (0 + n) ⋙ F).obj X = (s n ⋙ F).obj X) ≫
      (i n).hom.app X ≫ eqToHom (_ : (F ⋙ shiftFunctor D n).obj X = (F ⋙ shiftFunctor D (0 + n)).obj X)
⊢ F.map ((hasShiftOfFullyFaithful_add F s i 0 n).hom.app X) ≫ (i n).hom.app ((s 0).obj X) =
    F.map
        (eqToHom (_ : (s (0 + n)).obj X = (s n).obj ((𝟭 C).obj X)) ≫
          (s n).map ((hasShiftOfFullyFaithful_zero F s i).inv.app X)) ≫
      (i n).hom.app ((s 0).obj X)

Next tactic:
simp [this, map_hasShiftOfFullyFaithful_add_hom_app,
          shiftFunctorAdd_zero_add_hom_app, eqToHom_map]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        simp [shiftFunctorAdd', eqToHom_map])
      zero_add_hom_app := fun n X => F.map_injective (by
        have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n)
        rw [← cancel_mono ((i n).hom.app ((s 0).obj X)) ]
        simp [this, map_hasShiftOfFullyFaithful_add_hom_app,
          shiftFunctorAdd_zero_add_hom_app, eqToHom_map]
        

Proof state:
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
n : A
X : C
this :
  (i (0 + n)).hom.app X =
    eqToHom (_ : (s (0 + n) ⋙ F).obj X = (s n ⋙ F).obj X) ≫
      (i n).hom.app X ≫ eqToHom (_ : (F ⋙ shiftFunctor D n).obj X = (F ⋙ shiftFunctor D (0 + n)).obj X)
⊢ eqToHom (_ : (s (0 + n) ⋙ F).obj X = (s n ⋙ F).obj X) ≫
      (i n).hom.app X ≫
        (shiftFunctor D n).map ((shiftFunctorZero D A).inv.app (F.obj X)) ≫ (shiftFunctor D n).map ((i 0).inv.app X) =
    eqToHom (_ : F.obj ((s (0 + n)).obj X) = F.obj ((s n).obj X)) ≫
      F.map ((s n).map ((hasShiftOfFullyFaithful_zero F s i).inv.app X)) ≫ (i n).hom.app ((s 0).obj X)

Next tactic:
congr 1
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        simp [shiftFunctorAdd', eqToHom_map])
      zero_add_hom_app := fun n X => F.map_injective (by
        have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n)
        rw [← cancel_mono ((i n).hom.app ((s 0).obj X)) ]
        simp [this, map_hasShiftOfFullyFaithful_add_hom_app,
          shiftFunctorAdd_zero_add_hom_app, eqToHom_map]
        congr 1
        

Proof state:
case e_a
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
n : A
X : C
this :
  (i (0 + n)).hom.app X =
    eqToHom (_ : (s (0 + n) ⋙ F).obj X = (s n ⋙ F).obj X) ≫
      (i n).hom.app X ≫ eqToHom (_ : (F ⋙ shiftFunctor D n).obj X = (F ⋙ shiftFunctor D (0 + n)).obj X)
⊢ (i n).hom.app X ≫
      (shiftFunctor D n).map ((shiftFunctorZero D A).inv.app (F.obj X)) ≫ (shiftFunctor D n).map ((i 0).inv.app X) =
    F.map ((s n).map ((hasShiftOfFullyFaithful_zero F s i).inv.app X)) ≫ (i n).hom.app ((s 0).obj X)

Next tactic:
erw [(i n).hom.naturality]
/-- Given a family of endomorphisms of `C` which are intertwined by a fully faithful `F : C ⥤ D`
with shift functors on `D`, we can promote that family to shift functors on `C`. -/
def hasShiftOfFullyFaithful :
    HasShift C A :=
  hasShiftMk C A
    { F := s
      zero := hasShiftOfFullyFaithful_zero F s i
      add := hasShiftOfFullyFaithful_add F s i
      assoc_hom_app := fun m₁ m₂ m₃ X => F.map_injective (by
        have h := shiftFunctorAdd'_assoc_hom_app m₁ m₂ m₃ _ _ (m₁+m₂+m₃) rfl rfl rfl (F.obj X)
        simp only [shiftFunctorAdd'_eq_shiftFunctorAdd] at h
        rw [← cancel_mono ((i m₃).hom.app ((s m₂).obj ((s m₁).obj X)))]
        simp only [Functor.comp_obj, Functor.map_comp, map_hasShiftOfFullyFaithful_add_hom_app,
          Category.assoc, Iso.inv_hom_id_app_assoc, NatTrans.naturality_assoc, Functor.comp_map,
          Iso.inv_hom_id_app, Category.comp_id]
        erw [(i m₃).hom.naturality]
        rw [Functor.comp_map, map_hasShiftOfFullyFaithful_add_hom_app,
          Functor.map_comp, Functor.map_comp, Iso.inv_hom_id_app_assoc,
          ← Functor.map_comp_assoc _ ((i (m₁ + m₂)).inv.app X), Iso.inv_hom_id_app,
          Functor.map_id, Category.id_comp, reassoc_of% h,
          dcongr_arg (fun a => (i a).hom.app X) (add_assoc m₁ m₂ m₃)]
        simp [shiftFunctorAdd', eqToHom_map])
      zero_add_hom_app := fun n X => F.map_injective (by
        have this := dcongr_arg (fun a => (i a).hom.app X) (zero_add n)
        rw [← cancel_mono ((i n).hom.app ((s 0).obj X)) ]
        simp [this, map_hasShiftOfFullyFaithful_add_hom_app,
          shiftFunctorAdd_zero_add_hom_app, eqToHom_map]
        congr 1
        erw [(i n).hom.naturality]
        

Proof state:
case e_a
C : Type u
A : Type u_1
inst✝⁵ : Category.{v, u} C
D : Type u_2
inst✝⁴ : Category.{?u.290838, u_2} D
inst✝³ : AddMonoid A
inst✝² : HasShift D A
F : C ⥤ D
inst✝¹ : Full F
inst✝ : Faithful F
s : A → C ⥤ C
i : (i : A) → s i ⋙ F ≅ F ⋙ shiftFunctor D i
n : A
X : C
this :
  (i (0 + n)).hom.app X =
    eqToHom (_ : (s (0 + n) ⋙ F).obj X = (s n ⋙ F).obj X) ≫
      (i n).hom.app X ≫ eqToHom (_ : (F ⋙ shiftFunctor D n).obj X = (F ⋙ shiftFunctor D (0 + n)).obj X)
⊢ (i n).hom.app X ≫
      (shiftFunctor D n).map ((shiftFunctorZero D A).inv.app (F.obj X)) ≫ (shiftFunctor D n).map ((i 0).inv.app X) =
    (i n).hom.app X ≫ (F ⋙ shiftFunctor D n).map ((hasShiftOfFullyFaithful_zero F s i).inv.app X)

Next tactic:
dsimp