l3lab/ntp-mathlib huggingface dataset:
/-- Taking kernels is an order-reversing map from the quotient objects of `X` to the subobjects of
    `X`. -/
@[simps]
def kernelOrderHom [HasKernels C] (X : C) : (Subobject (op X))ᵒᵈ →o Subobject X where
  toFun :=
    Subobject.lift (fun A f _ => Subobject.mk (kernel.ι f.unop))
      (by
        rintro A B f g hf hg i rfl
        refine' Subobject.mk_eq_mk_of_comm _ _ _ _
        · exact
            IsLimit.conePointUniqueUpToIso (limit.isLimit _)
              (isKernelCompMono (limit.isLimit (parallelPair g.unop 0)) i.unop.hom rfl)
        · dsimp
          simp only [← Iso.eq_inv_comp, limit.conePointUniqueUpToIso_inv_comp,
            Fork.ofι_π_app])
  monotone' :=
    Subobject.ind₂ _ <| by
      intro A B f g hf hg h
      dsimp only [Subobject.lift_mk]
      refine' Subobject.mk_le_mk_of_comm (kernel.lift g.unop (kernel.ι f.unop) _) _
      · rw [← Subobject.ofMkLEMk_comp h, unop_comp, kernel.condition_assoc, zero_comp]
      · exact Quiver.Hom.op_inj (by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
inst✝² : HasZeroMorphisms C
f✝ : X✝ ⟶ Y
inst✝¹ : HasKernel f✝
inst✝ : HasKernels C
X : C
A B : Cᵒᵖ
f : A ⟶ op X
g : B ⟶ op X
hf : Mono f
hg : Mono g
h : Subobject.mk f ≤ Subobject.mk g
⊢ (kernel.lift g.unop (kernel.ι f.unop) (_ : kernel.ι f.unop ≫ g.unop = 0) ≫ kernel.ι g.unop).op = (kernel.ι f.unop).op

Next tactic:
simp
@[reassoc (attr := simp)]
theorem imageSubobject_arrow : (imageSubobjectIso f).hom ≫ image.ι f = (imageSubobject f).arrow :=
  by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ (imageSubobjectIso f).hom ≫ image.ι f = arrow (imageSubobject f)

Next tactic:
simp [imageSubobjectIso]
@[reassoc (attr := simp)]
theorem imageSubobject_arrow' : (imageSubobjectIso f).inv ≫ (imageSubobject f).arrow = image.ι f :=
  by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ (imageSubobjectIso f).inv ≫ arrow (imageSubobject f) = image.ι f

Next tactic:
simp [imageSubobjectIso]
instance [HasEqualizers C] : Epi (factorThruImageSubobject f) := by
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasEqualizers C
⊢ Epi (factorThruImageSubobject f)

Next tactic:
dsimp [factorThruImageSubobject]
instance [HasEqualizers C] : Epi (factorThruImageSubobject f) := by
  dsimp [factorThruImageSubobject]
  

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasEqualizers C
⊢ Epi (factorThruImage f ≫ (imageSubobjectIso f).inv)

Next tactic:
apply epi_comp
@[reassoc (attr := simp), elementwise (attr := simp)]
theorem imageSubobject_arrow_comp : factorThruImageSubobject f ≫ (imageSubobject f).arrow = f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
⊢ factorThruImageSubobject f ≫ arrow (imageSubobject f) = f

Next tactic:
simp [factorThruImageSubobject, imageSubobject_arrow]
theorem imageSubobject_arrow_comp_eq_zero [HasZeroMorphisms C] {X Y Z : C} {f : X ⟶ Y} {g : Y ⟶ Z}
    [HasImage f] [Epi (factorThruImageSubobject f)] (h : f ≫ g = 0) :
    (imageSubobject f).arrow ≫ g = 0 :=
  zero_of_epi_comp (factorThruImageSubobject f) <| by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
inst✝² : HasZeroMorphisms C
X Y Z : C
f : X ⟶ Y
g : Y ⟶ Z
inst✝¹ : HasImage f
inst✝ : Epi (factorThruImageSubobject f)
h : f ≫ g = 0
⊢ factorThruImageSubobject f ≫ arrow (imageSubobject f) ≫ g = 0

Next tactic:
simp [h]
theorem imageSubobject_factors_comp_self {W : C} (k : W ⟶ X) : (imageSubobject f).Factors (k ≫ f) :=
  ⟨k ≫ factorThruImage f, by 

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
⊢ (k ≫ factorThruImage f) ≫ MonoOver.arrow (MonoOver.mk' (image.ι f)) = k ≫ f

Next tactic:
simp
@[simp]
theorem factorThruImageSubobject_comp_self {W : C} (k : W ⟶ X) (h) :
    (imageSubobject f).factorThru (k ≫ f) h = k ≫ factorThruImageSubobject f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
h : Factors (imageSubobject f) (k ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ f) h = k ≫ factorThruImageSubobject f

Next tactic:
ext
@[simp]
theorem factorThruImageSubobject_comp_self {W : C} (k : W ⟶ X) (h) :
    (imageSubobject f).factorThru (k ≫ f) h = k ≫ factorThruImageSubobject f := by
  ext
  

Proof state:
case h
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W : C
k : W ⟶ X
h : Factors (imageSubobject f) (k ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ f) h ≫ arrow (imageSubobject f) =
    (k ≫ factorThruImageSubobject f) ≫ arrow (imageSubobject f)

Next tactic:
simp
@[simp]
theorem factorThruImageSubobject_comp_self_assoc {W W' : C} (k : W ⟶ W') (k' : W' ⟶ X) (h) :
    (imageSubobject f).factorThru (k ≫ k' ≫ f) h = k ≫ k' ≫ factorThruImageSubobject f := by
  

Proof state:
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W W' : C
k : W ⟶ W'
k' : W' ⟶ X
h : Factors (imageSubobject f) (k ≫ k' ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ k' ≫ f) h = k ≫ k' ≫ factorThruImageSubobject f

Next tactic:
ext
@[simp]
theorem factorThruImageSubobject_comp_self_assoc {W W' : C} (k : W ⟶ W') (k' : W' ⟶ X) (h) :
    (imageSubobject f).factorThru (k ≫ k' ≫ f) h = k ≫ k' ≫ factorThruImageSubobject f := by
  ext
  

Proof state:
case h
C : Type u
inst✝¹ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝ : HasImage f
W W' : C
k : W ⟶ W'
k' : W' ⟶ X
h : Factors (imageSubobject f) (k ≫ k' ≫ f)
⊢ factorThru (imageSubobject f) (k ≫ k' ≫ f) h ≫ arrow (imageSubobject f) =
    (k ≫ k' ≫ factorThruImageSubobject f) ≫ arrow (imageSubobject f)

Next tactic:
simp
/-- The image of `h ≫ f` is always a smaller subobject than the image of `f`. -/
theorem imageSubobject_comp_le {X' : C} (h : X' ⟶ X) (f : X ⟶ Y) [HasImage f] [HasImage (h ≫ f)] :
    imageSubobject (h ≫ f) ≤ imageSubobject f :=
  Subobject.mk_le_mk_of_comm (image.preComp h f) (by 

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

Next tactic:
simp
@[simp]
theorem imageSubobject_zero_arrow : (imageSubobject (0 : X ⟶ Y)).arrow = 0 := by
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
⊢ arrow (imageSubobject 0) = 0

Next tactic:
rw [← imageSubobject_arrow]
@[simp]
theorem imageSubobject_zero_arrow : (imageSubobject (0 : X ⟶ Y)).arrow = 0 := by
  rw [← imageSubobject_arrow]
  

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
⊢ (imageSubobjectIso 0).hom ≫ image.ι 0 = 0

Next tactic:
simp
@[simp]
theorem imageSubobject_zero {A B : C} : imageSubobject (0 : A ⟶ B) = ⊥ :=
  Subobject.eq_of_comm (imageSubobjectIso _ ≪≫ imageZero ≪≫ Subobject.botCoeIsoZero.symm) (by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
X Y Z : C
f : X ⟶ Y
inst✝² : HasImage f
inst✝¹ : HasZeroMorphisms C
inst✝ : HasZeroObject C
A B : C
⊢ (imageSubobjectIso 0 ≪≫ imageZero ≪≫ botCoeIsoZero.symm).hom ≫ arrow ⊥ = arrow (imageSubobject 0)

Next tactic:
simp
/-- The morphism `imageSubobject (h ≫ f) ⟶ imageSubobject f`
is an epimorphism when `h` is an epimorphism.
In general this does not imply that `imageSubobject (h ≫ f) = imageSubobject f`,
although it will when the ambient category is abelian.
 -/
instance imageSubobject_comp_le_epi_of_epi {X' : C} (h : X' ⟶ X) [Epi h] (f : X ⟶ Y) [HasImage f]
    [HasImage (h ≫ f)] : Epi (Subobject.ofLE _ _ (imageSubobject_comp_le h f)) := by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ Epi (ofLE (imageSubobject (h ≫ f)) (imageSubobject f) (_ : imageSubobject (h ≫ f) ≤ imageSubobject f))

Next tactic:
rw [ofLE_mk_le_mk_of_comm (image.preComp h f)]
/-- The morphism `imageSubobject (h ≫ f) ⟶ imageSubobject f`
is an epimorphism when `h` is an epimorphism.
In general this does not imply that `imageSubobject (h ≫ f) = imageSubobject f`,
although it will when the ambient category is abelian.
 -/
instance imageSubobject_comp_le_epi_of_epi {X' : C} (h : X' ⟶ X) [Epi h] (f : X ⟶ Y) [HasImage f]
    [HasImage (h ≫ f)] : Epi (Subobject.ofLE _ _ (imageSubobject_comp_le h f)) := by
  rw [ofLE_mk_le_mk_of_comm (image.preComp h f)]
  · 

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ Epi ((underlyingIso (image.ι (h ≫ f))).hom ≫ image.preComp h f ≫ (underlyingIso (image.ι f)).inv)

Next tactic:
infer_instance
/-- The morphism `imageSubobject (h ≫ f) ⟶ imageSubobject f`
is an epimorphism when `h` is an epimorphism.
In general this does not imply that `imageSubobject (h ≫ f) = imageSubobject f`,
although it will when the ambient category is abelian.
 -/
instance imageSubobject_comp_le_epi_of_epi {X' : C} (h : X' ⟶ X) [Epi h] (f : X ⟶ Y) [HasImage f]
    [HasImage (h ≫ f)] : Epi (Subobject.ofLE _ _ (imageSubobject_comp_le h f)) := by
  rw [ofLE_mk_le_mk_of_comm (image.preComp h f)]
  · infer_instance
  · 

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝⁴ : HasImage f✝
inst✝³ : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝² : Epi h
f : X ⟶ Y
inst✝¹ : HasImage f
inst✝ : HasImage (h ≫ f)
⊢ image.preComp h f ≫ image.ι f = image.ι (h ≫ f)

Next tactic:
simp
@[reassoc (attr := simp)]
theorem imageSubobjectCompIso_hom_arrow (f : X ⟶ Y) [HasImage f] {Y' : C} (h : Y ⟶ Y') [IsIso h] :
    (imageSubobjectCompIso f h).hom ≫ (imageSubobject f).arrow =
      (imageSubobject (f ≫ h)).arrow ≫ inv h :=
  by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
f : X ⟶ Y
inst✝¹ : HasImage f
Y' : C
h : Y ⟶ Y'
inst✝ : IsIso h
⊢ (imageSubobjectCompIso f h).hom ≫ arrow (imageSubobject f) = arrow (imageSubobject (f ≫ h)) ≫ inv h

Next tactic:
simp [imageSubobjectCompIso]
@[reassoc (attr := simp)]
theorem imageSubobjectCompIso_inv_arrow (f : X ⟶ Y) [HasImage f] {Y' : C} (h : Y ⟶ Y') [IsIso h] :
    (imageSubobjectCompIso f h).inv ≫ (imageSubobject (f ≫ h)).arrow =
      (imageSubobject f).arrow ≫ h :=
  by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
f : X ⟶ Y
inst✝¹ : HasImage f
Y' : C
h : Y ⟶ Y'
inst✝ : IsIso h
⊢ (imageSubobjectCompIso f h).inv ≫ arrow (imageSubobject (f ≫ h)) = arrow (imageSubobject f) ≫ h

Next tactic:
simp [imageSubobjectCompIso]
theorem imageSubobject_mono (f : X ⟶ Y) [Mono f] : imageSubobject f = Subobject.mk f :=
  eq_of_comm (imageSubobjectIso f ≪≫ imageMonoIsoSource f ≪≫ (underlyingIso f).symm) (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝¹ : HasImage f✝
f : X ⟶ Y
inst✝ : Mono f
⊢ (imageSubobjectIso f ≪≫ imageMonoIsoSource f ≪≫ (underlyingIso f).symm).hom ≫ arrow (Subobject.mk f) =
    arrow (imageSubobject f)

Next tactic:
simp
/-- Precomposing by an isomorphism does not change the image subobject. -/
theorem imageSubobject_iso_comp [HasEqualizers C] {X' : C} (h : X' ⟶ X) [IsIso h] (f : X ⟶ Y)
    [HasImage f] : imageSubobject (h ≫ f) = imageSubobject f :=
  le_antisymm (imageSubobject_comp_le h f)
    (Subobject.mk_le_mk_of_comm (inv (image.preComp h f)) (by 

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X Y Z : C
f✝ : X ⟶ Y
inst✝³ : HasImage f✝
inst✝² : HasEqualizers C
X' : C
h : X' ⟶ X
inst✝¹ : IsIso h
f : X ⟶ Y
inst✝ : HasImage f
⊢ inv (image.preComp h f) ≫ image.ι (h ≫ f) = image.ι f

Next tactic:
simp
theorem imageSubobject_le {A B : C} {X : Subobject B} (f : A ⟶ B) [HasImage f] (h : A ⟶ X)
    (w : h ≫ X.arrow = f) : imageSubobject f ≤ X :=
  Subobject.le_of_comm
    ((imageSubobjectIso f).hom ≫
      image.lift
        { I := (X : C)
          e := h
          m := X.arrow })
    (by 

Proof state:
C : Type u
inst✝² : Category.{v, u} C
X✝ Y Z : C
f✝ : X✝ ⟶ Y
inst✝¹ : HasImage f✝
A B : C
X : Subobject B
f : A ⟶ B
inst✝ : HasImage f
h : A ⟶ underlying.obj X
w : h ≫ arrow X = f
⊢ ((imageSubobjectIso f).hom ≫ image.lift (MonoFactorisation.mk (underlying.obj X) (arrow X) h)) ≫ arrow X =
    arrow (imageSubobject f)

Next tactic:
rw [assoc, image.lift_fac, imageSubobject_arrow]
theorem imageSubobject_le_mk {A B : C} {X : C} (g : X ⟶ B) [Mono g] (f : A ⟶ B) [HasImage f]
    (h : A ⟶ X) (w : h ≫ g = f) : imageSubobject f ≤ Subobject.mk g :=
  imageSubobject_le f (h ≫ (Subobject.underlyingIso g).inv) (by 

Proof state:
C : Type u
inst✝³ : Category.{v, u} C
X✝ Y Z : C
f✝ : X✝ ⟶ Y
inst✝² : HasImage f✝
A B X : C
g : X ⟶ B
inst✝¹ : Mono g
f : A ⟶ B
inst✝ : HasImage f
h : A ⟶ X
w : h ≫ g = f
⊢ (h ≫ (underlyingIso g).inv) ≫ arrow (Subobject.mk g) = f

Next tactic:
simp [w]
@[reassoc (attr := simp)]
theorem imageSubobjectMap_arrow {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z} [HasImage g]
    (sq : Arrow.mk f ⟶ Arrow.mk g) [HasImageMap sq] :
    imageSubobjectMap sq ≫ (imageSubobject g).arrow = (imageSubobject f).arrow ≫ sq.right := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ imageSubobjectMap sq ≫ arrow (imageSubobject g) = arrow (imageSubobject f) ≫ sq.right

Next tactic:
simp only [imageSubobjectMap, Category.assoc, imageSubobject_arrow']
@[reassoc (attr := simp)]
theorem imageSubobjectMap_arrow {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z} [HasImage g]
    (sq : Arrow.mk f ⟶ Arrow.mk g) [HasImageMap sq] :
    imageSubobjectMap sq ≫ (imageSubobject g).arrow = (imageSubobject f).arrow ≫ sq.right := by
  simp only [imageSubobjectMap, Category.assoc, imageSubobject_arrow']
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (imageSubobjectIso f).hom ≫ image.map sq ≫ image.ι g = arrow (imageSubobject f) ≫ sq.right

Next tactic:
erw [image.map_ι, ← Category.assoc, imageSubobject_arrow]
theorem image_map_comp_imageSubobjectIso_inv {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z}
    [HasImage g] (sq : Arrow.mk f ⟶ Arrow.mk g) [HasImageMap sq] :
    image.map sq ≫ (imageSubobjectIso _).inv =
      (imageSubobjectIso _).inv ≫ imageSubobjectMap sq := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ image.map sq ≫ (imageSubobjectIso (Arrow.mk g).hom).inv = (imageSubobjectIso f).inv ≫ imageSubobjectMap sq

Next tactic:
ext
theorem image_map_comp_imageSubobjectIso_inv {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z}
    [HasImage g] (sq : Arrow.mk f ⟶ Arrow.mk g) [HasImageMap sq] :
    image.map sq ≫ (imageSubobjectIso _).inv =
      (imageSubobjectIso _).inv ≫ imageSubobjectMap sq := by
  ext
  

Proof state:
case h
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (image.map sq ≫ (imageSubobjectIso (Arrow.mk g).hom).inv) ≫ arrow (imageSubobject (Arrow.mk g).hom) =
    ((imageSubobjectIso f).inv ≫ imageSubobjectMap sq) ≫ arrow (imageSubobject (Arrow.mk g).hom)

Next tactic:
simpa using image.map_ι sq
theorem imageSubobjectIso_comp_image_map {W X Y Z : C} {f : W ⟶ X} [HasImage f] {g : Y ⟶ Z}
    [HasImage g] (sq : Arrow.mk f ⟶ Arrow.mk g) [HasImageMap sq] :
    (imageSubobjectIso _).hom ≫ image.map sq =
      imageSubobjectMap sq ≫ (imageSubobjectIso _).hom := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
X✝ Y✝ Z✝ : C
f✝ : X✝ ⟶ Y✝
inst✝³ : HasImage f✝
W X Y Z : C
f : W ⟶ X
inst✝² : HasImage f
g : Y ⟶ Z
inst✝¹ : HasImage g
sq : Arrow.mk f ⟶ Arrow.mk g
inst✝ : HasImageMap sq
⊢ (imageSubobjectIso (Arrow.mk f).hom).hom ≫ image.map sq = imageSubobjectMap sq ≫ (imageSubobjectIso g).hom

Next tactic:
erw [← Iso.comp_inv_eq, Category.assoc, ← (imageSubobjectIso f).eq_inv_comp,
    image_map_comp_imageSubobjectIso_inv sq]
/-- If `a ≤ b`, then `b` does not cover `a` iff there's an element in between. -/
theorem not_wcovby_iff (h : a ≤ b) : ¬a ⩿ b ↔ ∃ c, a < c ∧ c < b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c : α
h : a ≤ b
⊢ ¬a ⩿ b ↔ ∃ c, a < c ∧ c < b

Next tactic:
simp_rw [Wcovby, h, true_and_iff, not_forall, exists_prop, not_not]
theorem wcovby_iff_Ioo_eq : a ⩿ b ↔ a ≤ b ∧ Ioo a b = ∅ :=
  and_congr_right' <| by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c : α
⊢ (∀ ⦃c : α⦄, a < c → ¬c < b) ↔ Ioo a b = ∅

Next tactic:
simp [eq_empty_iff_forall_not_mem]
theorem Wcovby.image (f : α ↪o β) (hab : a ⩿ b) (h : (range f).OrdConnected) : f a ⩿ f b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c : α
f : α ↪o β
hab : a ⩿ b
h : OrdConnected (range ⇑f)
⊢ f a ⩿ f b

Next tactic:
refine' ⟨f.monotone hab.le, fun c ha hb => _⟩
theorem Wcovby.image (f : α ↪o β) (hab : a ⩿ b) (h : (range f).OrdConnected) : f a ⩿ f b := by
  refine' ⟨f.monotone hab.le, fun c ha hb => _⟩
  

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c✝ : α
f : α ↪o β
hab : a ⩿ b
h : OrdConnected (range ⇑f)
c : β
ha : f a < c
hb : c < f b
⊢ False

Next tactic:
obtain ⟨c, rfl⟩ := h.out (mem_range_self _) (mem_range_self _) ⟨ha.le, hb.le⟩
theorem Wcovby.image (f : α ↪o β) (hab : a ⩿ b) (h : (range f).OrdConnected) : f a ⩿ f b := by
  refine' ⟨f.monotone hab.le, fun c ha hb => _⟩
  obtain ⟨c, rfl⟩ := h.out (mem_range_self _) (mem_range_self _) ⟨ha.le, hb.le⟩
  

Proof state:
case intro
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c✝ : α
f : α ↪o β
hab : a ⩿ b
h : OrdConnected (range ⇑f)
c : α
ha : f a < f c
hb : f c < f b
⊢ False

Next tactic:
rw [f.lt_iff_lt] at ha hb
theorem Wcovby.image (f : α ↪o β) (hab : a ⩿ b) (h : (range f).OrdConnected) : f a ⩿ f b := by
  refine' ⟨f.monotone hab.le, fun c ha hb => _⟩
  obtain ⟨c, rfl⟩ := h.out (mem_range_self _) (mem_range_self _) ⟨ha.le, hb.le⟩
  rw [f.lt_iff_lt] at ha hb
  

Proof state:
case intro
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c✝ : α
f : α ↪o β
hab : a ⩿ b
h : OrdConnected (range ⇑f)
c : α
ha : a < c
hb : c < b
⊢ False

Next tactic:
exact hab.2 ha hb
theorem Wcovby.eq_or_eq (h : a ⩿ b) (h2 : a ≤ c) (h3 : c ≤ b) : c = a ∨ c = b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
h2 : a ≤ c
h3 : c ≤ b
⊢ c = a ∨ c = b

Next tactic:
rcases h2.eq_or_lt with (h2 | h2)
theorem Wcovby.eq_or_eq (h : a ⩿ b) (h2 : a ≤ c) (h3 : c ≤ b) : c = a ∨ c = b := by
  rcases h2.eq_or_lt with (h2 | h2); · 

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
h2✝ : a ≤ c
h3 : c ≤ b
h2 : a = c
⊢ c = a ∨ c = b

Next tactic:
exact Or.inl h2.symm
theorem Wcovby.eq_or_eq (h : a ⩿ b) (h2 : a ≤ c) (h3 : c ≤ b) : c = a ∨ c = b := by
  rcases h2.eq_or_lt with (h2 | h2); · exact Or.inl h2.symm
  

Proof state:
case inr
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
h2✝ : a ≤ c
h3 : c ≤ b
h2 : a < c
⊢ c = a ∨ c = b

Next tactic:
rcases h3.eq_or_lt with (h3 | h3)
theorem Wcovby.eq_or_eq (h : a ⩿ b) (h2 : a ≤ c) (h3 : c ≤ b) : c = a ∨ c = b := by
  rcases h2.eq_or_lt with (h2 | h2); · exact Or.inl h2.symm
  rcases h3.eq_or_lt with (h3 | h3); · 

Proof state:
case inr.inl
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
h2✝ : a ≤ c
h3✝ : c ≤ b
h2 : a < c
h3 : c = b
⊢ c = a ∨ c = b

Next tactic:
exact Or.inr h3
theorem Wcovby.eq_or_eq (h : a ⩿ b) (h2 : a ≤ c) (h3 : c ≤ b) : c = a ∨ c = b := by
  rcases h2.eq_or_lt with (h2 | h2); · exact Or.inl h2.symm
  rcases h3.eq_or_lt with (h3 | h3); · exact Or.inr h3
  

Proof state:
case inr.inr
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
h2✝ : a ≤ c
h3✝ : c ≤ b
h2 : a < c
h3 : c < b
⊢ c = a ∨ c = b

Next tactic:
exact (h.2 h2 h3).elim
theorem Wcovby.le_and_le_iff (h : a ⩿ b) : a ≤ c ∧ c ≤ b ↔ c = a ∨ c = b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
⊢ a ≤ c ∧ c ≤ b ↔ c = a ∨ c = b

Next tactic:
refine' ⟨fun h2 => h.eq_or_eq h2.1 h2.2, _⟩
theorem Wcovby.le_and_le_iff (h : a ⩿ b) : a ≤ c ∧ c ≤ b ↔ c = a ∨ c = b := by
  refine' ⟨fun h2 => h.eq_or_eq h2.1 h2.2, _⟩; 

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
⊢ c = a ∨ c = b → a ≤ c ∧ c ≤ b

Next tactic:
rintro (rfl | rfl)
theorem Wcovby.le_and_le_iff (h : a ⩿ b) : a ≤ c ∧ c ≤ b ↔ c = a ∨ c = b := by
  refine' ⟨fun h2 => h.eq_or_eq h2.1 h2.2, _⟩; rintro (rfl | rfl);
  

Proof state:
case inl
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
b c : α
h : c ⩿ b
⊢ c ≤ c ∧ c ≤ b
case inr α : Type u_1 β : Type u_2 inst✝ : PartialOrder α a c : α h : a ⩿ c ⊢ a ≤ c ∧ c ≤ c

Next tactic:
exacts [⟨le_rfl, h.le⟩, ⟨h.le, le_rfl⟩]
theorem Wcovby.Icc_eq (h : a ⩿ b) : Icc a b = {a, b} := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
⊢ Icc a b = {a, b}

Next tactic:
ext c
theorem Wcovby.Icc_eq (h : a ⩿ b) : Icc a b = {a, b} := by
  ext c
  

Proof state:
case h
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c✝ : α
h : a ⩿ b
c : α
⊢ c ∈ Icc a b ↔ c ∈ {a, b}

Next tactic:
exact h.le_and_le_iff
theorem Wcovby.Ico_subset (h : a ⩿ b) : Ico a b ⊆ {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
⊢ Ico a b ⊆ {a}

Next tactic:
rw [← Icc_diff_right, h.Icc_eq, diff_singleton_subset_iff, pair_comm]
theorem Wcovby.Ioc_subset (h : a ⩿ b) : Ioc a b ⊆ {b} := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⩿ b
⊢ Ioc a b ⊆ {b}

Next tactic:
rw [← Icc_diff_left, h.Icc_eq, diff_singleton_subset_iff]
/-- If `a < b`, then `b` does not cover `a` iff there's an element in between. -/
theorem not_covby_iff (h : a < b) : ¬a ⋖ b ↔ ∃ c, a < c ∧ c < b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LT α
a b : α
h : a < b
⊢ ¬a ⋖ b ↔ ∃ c, a < c ∧ c < b

Next tactic:
simp_rw [Covby, h, true_and_iff, not_forall, exists_prop, not_not]
theorem covby_iff_Ioo_eq : a ⋖ b ↔ a < b ∧ Ioo a b = ∅ :=
  and_congr_right' <| by 

Proof state:
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
a b c : α
⊢ (∀ ⦃c : α⦄, a < c → ¬c < b) ↔ Ioo a b = ∅

Next tactic:
simp [eq_empty_iff_forall_not_mem]
theorem wcovby_iff_covby_or_eq : a ⩿ b ↔ a ⋖ b ∨ a = b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
⊢ a ⩿ b ↔ a ⋖ b ∨ a = b

Next tactic:
rw [le_antisymm_iff, wcovby_iff_covby_or_le_and_le]
theorem Covby.Ico_eq (h : a ⋖ b) : Ico a b = {a} := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⋖ b
⊢ Ico a b = {a}

Next tactic:
rw [← Ioo_union_left h.lt, h.Ioo_eq, empty_union]
theorem Covby.Ioc_eq (h : a ⋖ b) : Ioc a b = {b} := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : PartialOrder α
a b c : α
h : a ⋖ b
⊢ Ioc a b = {b}

Next tactic:
rw [← Ioo_union_right h.lt, h.Ioo_eq, empty_union]
theorem Covby.Ioi_eq (h : a ⋖ b) : Ioi a = Ici b := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b c : α
h : a ⋖ b
⊢ Ioi a = Ici b

Next tactic:
rw [← Ioo_union_Ici_eq_Ioi h.lt, h.Ioo_eq, empty_union]
theorem Covby.Iio_eq (h : a ⋖ b) : Iio b = Iic a := by
  

Proof state:
α : Type u_1
β : Type u_2
inst✝ : LinearOrder α
a b c : α
h : a ⋖ b
⊢ Iio b = Iic a

Next tactic:
rw [← Iic_union_Ioo_eq_Iio h.lt, h.Ioo_eq, union_empty]