-- Mathlib/CategoryTheory/Limits/Shapes/Images.lean
theorem image.preComp_comp {W : C} (h : Z ⟶ W) [HasImage (g ≫ h)] [HasImage (f ≫ g ≫ h)]
    [HasImage h] [HasImage ((f ≫ g) ≫ h)] :
    image.preComp f (g ≫ h) ≫ image.preComp g h =
      image.eqToHom (Category.assoc f g h).symm ≫ image.preComp (f ≫ g) h

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ lift (MonoFactorisation.mk (image (g ≫ h)) (ι (g ≫ h)) (f ≫ factorThruImage (g ≫ h)) ⋯) ≫ ι (g ≫ h) =
    (lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
        lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯)) ≫
      ι h

Tactic:
rw [Category.assoc,image.lift_fac]

Result:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ ι (f ≫ g ≫ h) =
    lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
      lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯) ≫ ι h

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ (preComp f (g ≫ h) ≫ preComp g h) ≫ ι h = (eqToHom ⋯ ≫ preComp (f ≫ g) h) ≫ ι h

Tactic:
dsimp [image.preComp, image.eqToHom]

Result:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ (lift (MonoFactorisation.mk (image (g ≫ h)) (ι (g ≫ h)) (f ≫ factorThruImage (g ≫ h)) ⋯) ≫
        lift (MonoFactorisation.mk (image h) (ι h) (g ≫ factorThruImage h) ⋯)) ≫
      ι h =
    (lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
        lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯)) ≫
      ι h

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ (lift (MonoFactorisation.mk (image (g ≫ h)) (ι (g ≫ h)) (f ≫ factorThruImage (g ≫ h)) ⋯) ≫
        lift (MonoFactorisation.mk (image h) (ι h) (g ≫ factorThruImage h) ⋯)) ≫
      ι h =
    (lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
        lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯)) ≫
      ι h

Tactic:
repeat (rw [Category.assoc,image.lift_fac])

Result:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ ι (f ≫ g ≫ h) =
    lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
      lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯) ≫ ι h

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ ι (f ≫ g ≫ h) =
    lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
      lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯) ≫ ι h

Tactic:
rw [image.lift_fac,image.lift_fac]

Result:
no goals

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ preComp f (g ≫ h) ≫ preComp g h = eqToHom ⋯ ≫ preComp (f ≫ g) h

Tactic:
apply (cancel_mono (image.ι h)).1

Result:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ (preComp f (g ≫ h) ≫ preComp g h) ≫ ι h = (eqToHom ⋯ ≫ preComp (f ≫ g) h) ≫ ι h

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ lift (MonoFactorisation.mk (image (g ≫ h)) (ι (g ≫ h)) (f ≫ factorThruImage (g ≫ h)) ⋯) ≫ ι (g ≫ h) =
    (lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
        lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯)) ≫
      ι h

Tactic:
(rw [Category.assoc,image.lift_fac])

Result:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y : C
f : X ⟶ Y
Z : C
g : Y ⟶ Z
W : C
h : Z ⟶ W
inst✝³ : HasImage (g ≫ h)
inst✝² : HasImage (f ≫ g ≫ h)
inst✝¹ : HasImage h
inst✝ : HasImage ((f ≫ g) ≫ h)
⊢ ι (f ≫ g ≫ h) =
    lift (MonoFactorisation.mk (image ((f ≫ g) ≫ h)) (ι ((f ≫ g) ≫ h)) (factorThruImage ((f ≫ g) ≫ h)) ⋯) ≫
      lift (MonoFactorisation.mk (image h) (ι h) ((f ≫ g) ≫ factorThruImage h) ⋯) ≫ ι h