l3lab/ntp-mathlib huggingface dataset:
/-- The composition in the opposite direction is equal to the identity if and only if `F` preserves
    the biproduct, see `preservesBinaryBiproduct_of_monoBiprodComparison`. -/
@[reassoc (attr := simp)]
theorem biprodComparison'_comp_biprodComparison :
    biprodComparison' F X Y ≫ biprodComparison F X Y = 𝟙 (F.obj X ⊞ F.obj Y) := by
  ext <;> 

Proof state:
case h₁.h₀
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
X Y : C
inst✝² : HasBinaryBiproduct X Y
inst✝¹ : HasBinaryBiproduct (F.obj X) (F.obj Y)
inst✝ : PreservesZeroMorphisms F
⊢ (biprod.inr ≫ biprodComparison' F X Y ≫ biprodComparison F X Y) ≫ biprod.fst =
    (biprod.inr ≫ 𝟙 (F.obj X ⊞ F.obj Y)) ≫ biprod.fst

Next tactic:
simp [← Functor.map_comp]
/-- The composition in the opposite direction is equal to the identity if and only if `F` preserves
    the biproduct, see `preservesBinaryBiproduct_of_monoBiprodComparison`. -/
@[reassoc (attr := simp)]
theorem biprodComparison'_comp_biprodComparison :
    biprodComparison' F X Y ≫ biprodComparison F X Y = 𝟙 (F.obj X ⊞ F.obj Y) := by
  ext <;> 

Proof state:
case h₁.h₁
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
X Y : C
inst✝² : HasBinaryBiproduct X Y
inst✝¹ : HasBinaryBiproduct (F.obj X) (F.obj Y)
inst✝ : PreservesZeroMorphisms F
⊢ (biprod.inr ≫ biprodComparison' F X Y ≫ biprodComparison F X Y) ≫ biprod.snd =
    (biprod.inr ≫ 𝟙 (F.obj X ⊞ F.obj Y)) ≫ biprod.snd

Next tactic:
simp [← Functor.map_comp]
/-- `biprodComparison F X Y` is a split epi. -/
@[simps]
def splitEpiBiprodComparison : SplitEpi (biprodComparison F X Y) where
  section_ := biprodComparison' F X Y
  id := by 

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
X Y : C
inst✝² : HasBinaryBiproduct X Y
inst✝¹ : HasBinaryBiproduct (F.obj X) (F.obj Y)
inst✝ : PreservesZeroMorphisms F
⊢ biprodComparison' F X Y ≫ biprodComparison F X Y = 𝟙 (F.obj X ⊞ F.obj Y)

Next tactic:
aesop
/-- `biprodComparison' F X Y` is a split mono. -/
@[simps]
def splitMonoBiprodComparison' : SplitMono (biprodComparison' F X Y) where
  retraction := biprodComparison F X Y
  id := by 

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
X Y : C
inst✝² : HasBinaryBiproduct X Y
inst✝¹ : HasBinaryBiproduct (F.obj X) (F.obj Y)
inst✝ : PreservesZeroMorphisms F
⊢ biprodComparison' F X Y ≫ biprodComparison F X Y = 𝟙 (F.obj X ⊞ F.obj Y)

Next tactic:
aesop
theorem biproduct.map_lift_mapBiprod (g : ∀ j, W ⟶ f j) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    F.map (biproduct.lift g) ≫ (F.mapBiproduct f).hom = biproduct.lift fun j => F.map (g j) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → W ⟶ f j
⊢ F.map (lift g) ≫ (mapBiproduct F f).hom = lift fun j => F.map (g j)

Next tactic:
ext j
theorem biproduct.map_lift_mapBiprod (g : ∀ j, W ⟶ f j) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    F.map (biproduct.lift g) ≫ (F.mapBiproduct f).hom = biproduct.lift fun j => F.map (g j) := by
  ext j
  

Proof state:
case w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → W ⟶ f j
j : J
⊢ (F.map (lift g) ≫ (mapBiproduct F f).hom) ≫ π (F.obj ∘ f) j = (lift fun j => F.map (g j)) ≫ π (F.obj ∘ f) j

Next tactic:
dsimp only [Function.comp_def]
theorem biproduct.map_lift_mapBiprod (g : ∀ j, W ⟶ f j) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    F.map (biproduct.lift g) ≫ (F.mapBiproduct f).hom = biproduct.lift fun j => F.map (g j) := by
  ext j
  dsimp only [Function.comp_def]
  

Proof state:
case w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → W ⟶ f j
j : J
⊢ (F.map (lift g) ≫ (mapBiproduct F f).hom) ≫ π (fun x => F.obj (f x)) j =
    (lift fun j => F.map (g j)) ≫ π (fun x => F.obj (f x)) j

Next tactic:
haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
theorem biproduct.map_lift_mapBiprod (g : ∀ j, W ⟶ f j) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    F.map (biproduct.lift g) ≫ (F.mapBiproduct f).hom = biproduct.lift fun j => F.map (g j) := by
  ext j
  dsimp only [Function.comp_def]
  haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
  

Proof state:
case w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → W ⟶ f j
j : J
this : HasBiproduct fun j => F.obj (f j)
⊢ (F.map (lift g) ≫ (mapBiproduct F f).hom) ≫ π (fun x => F.obj (f x)) j =
    (lift fun j => F.map (g j)) ≫ π (fun x => F.obj (f x)) j

Next tactic:
simp only [mapBiproduct_hom, Category.assoc, biproduct.lift_π, ← F.map_comp]
theorem biproduct.mapBiproduct_inv_map_desc (g : ∀ j, f j ⟶ W) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    (F.mapBiproduct f).inv ≫ F.map (biproduct.desc g) = biproduct.desc fun j => F.map (g j) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → f j ⟶ W
⊢ (mapBiproduct F f).inv ≫ F.map (desc g) = desc fun j => F.map (g j)

Next tactic:
ext j
theorem biproduct.mapBiproduct_inv_map_desc (g : ∀ j, f j ⟶ W) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    (F.mapBiproduct f).inv ≫ F.map (biproduct.desc g) = biproduct.desc fun j => F.map (g j) := by
  ext j
  

Proof state:
case w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → f j ⟶ W
j : J
⊢ ι (F.obj ∘ f) j ≫ (mapBiproduct F f).inv ≫ F.map (desc g) = ι (F.obj ∘ f) j ≫ desc fun j => F.map (g j)

Next tactic:
dsimp only [Function.comp_def]
theorem biproduct.mapBiproduct_inv_map_desc (g : ∀ j, f j ⟶ W) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    (F.mapBiproduct f).inv ≫ F.map (biproduct.desc g) = biproduct.desc fun j => F.map (g j) := by
  ext j
  dsimp only [Function.comp_def]
  

Proof state:
case w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → f j ⟶ W
j : J
⊢ ι (fun x => F.obj (f x)) j ≫ (mapBiproduct F f).inv ≫ F.map (desc g) =
    ι (fun x => F.obj (f x)) j ≫ desc fun j => F.map (g j)

Next tactic:
haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
theorem biproduct.mapBiproduct_inv_map_desc (g : ∀ j, f j ⟶ W) :
    -- Porting note: twice we need haveI to tell Lean about hasBiproduct_of_preserves F f
    haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
    (F.mapBiproduct f).inv ≫ F.map (biproduct.desc g) = biproduct.desc fun j => F.map (g j) := by
  ext j
  dsimp only [Function.comp_def]
  haveI : HasBiproduct fun j => F.obj (f j) := hasBiproduct_of_preserves F f
  

Proof state:
case w
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → f j ⟶ W
j : J
this : HasBiproduct fun j => F.obj (f j)
⊢ ι (fun x => F.obj (f x)) j ≫ (mapBiproduct F f).inv ≫ F.map (desc g) =
    ι (fun x => F.obj (f x)) j ≫ desc fun j => F.map (g j)

Next tactic:
simp only [mapBiproduct_inv, ← Category.assoc, biproduct.ι_desc ,← F.map_comp]
theorem biproduct.mapBiproduct_hom_desc (g : ∀ j, f j ⟶ W) :
    ((F.mapBiproduct f).hom ≫ biproduct.desc fun j => F.map (g j)) = F.map (biproduct.desc g) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
J : Type w₁
f : J → C
inst✝¹ : HasBiproduct f
inst✝ : PreservesBiproduct f F
W : C
g : (j : J) → f j ⟶ W
⊢ ((mapBiproduct F f).hom ≫ desc fun j => F.map (g j)) = F.map (desc g)

Next tactic:
rw [← biproduct.mapBiproduct_inv_map_desc, Iso.hom_inv_id_assoc]
theorem biprod.map_lift_mapBiprod (f : W ⟶ X) (g : W ⟶ Y) :
    F.map (biprod.lift f g) ≫ (F.mapBiprod X Y).hom = biprod.lift (F.map f) (F.map g) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : W ⟶ X
g : W ⟶ Y
⊢ F.map (lift f g) ≫ (mapBiprod F X Y).hom = lift (F.map f) (F.map g)

Next tactic:
ext
theorem biprod.map_lift_mapBiprod (f : W ⟶ X) (g : W ⟶ Y) :
    F.map (biprod.lift f g) ≫ (F.mapBiprod X Y).hom = biprod.lift (F.map f) (F.map g) := by
  ext <;> 

Proof state:
case h₀
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : W ⟶ X
g : W ⟶ Y
⊢ (F.map (lift f g) ≫ (mapBiprod F X Y).hom) ≫ fst = lift (F.map f) (F.map g) ≫ fst

Next tactic:
simp [mapBiprod, ← F.map_comp]
theorem biprod.map_lift_mapBiprod (f : W ⟶ X) (g : W ⟶ Y) :
    F.map (biprod.lift f g) ≫ (F.mapBiprod X Y).hom = biprod.lift (F.map f) (F.map g) := by
  ext <;> 

Proof state:
case h₁
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : W ⟶ X
g : W ⟶ Y
⊢ (F.map (lift f g) ≫ (mapBiprod F X Y).hom) ≫ snd = lift (F.map f) (F.map g) ≫ snd

Next tactic:
simp [mapBiprod, ← F.map_comp]
theorem biprod.lift_mapBiprod (f : W ⟶ X) (g : W ⟶ Y) :
    biprod.lift (F.map f) (F.map g) ≫ (F.mapBiprod X Y).inv = F.map (biprod.lift f g) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : W ⟶ X
g : W ⟶ Y
⊢ lift (F.map f) (F.map g) ≫ (mapBiprod F X Y).inv = F.map (lift f g)

Next tactic:
rw [← biprod.map_lift_mapBiprod, Category.assoc, Iso.hom_inv_id, Category.comp_id]
theorem biprod.mapBiprod_inv_map_desc (f : X ⟶ W) (g : Y ⟶ W) :
    (F.mapBiprod X Y).inv ≫ F.map (biprod.desc f g) = biprod.desc (F.map f) (F.map g) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : X ⟶ W
g : Y ⟶ W
⊢ (mapBiprod F X Y).inv ≫ F.map (desc f g) = desc (F.map f) (F.map g)

Next tactic:
ext
theorem biprod.mapBiprod_inv_map_desc (f : X ⟶ W) (g : Y ⟶ W) :
    (F.mapBiprod X Y).inv ≫ F.map (biprod.desc f g) = biprod.desc (F.map f) (F.map g) := by
  ext <;> 

Proof state:
case h₀
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : X ⟶ W
g : Y ⟶ W
⊢ inl ≫ (mapBiprod F X Y).inv ≫ F.map (desc f g) = inl ≫ desc (F.map f) (F.map g)

Next tactic:
simp [mapBiprod, ← F.map_comp]
theorem biprod.mapBiprod_inv_map_desc (f : X ⟶ W) (g : Y ⟶ W) :
    (F.mapBiprod X Y).inv ≫ F.map (biprod.desc f g) = biprod.desc (F.map f) (F.map g) := by
  ext <;> 

Proof state:
case h₁
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : X ⟶ W
g : Y ⟶ W
⊢ inr ≫ (mapBiprod F X Y).inv ≫ F.map (desc f g) = inr ≫ desc (F.map f) (F.map g)

Next tactic:
simp [mapBiprod, ← F.map_comp]
theorem biprod.mapBiprod_hom_desc (f : X ⟶ W) (g : Y ⟶ W) :
    (F.mapBiprod X Y).hom ≫ biprod.desc (F.map f) (F.map g) = F.map (biprod.desc f g) := by
  

Proof state:
C : Type u₁
inst✝⁶ : Category.{v₁, u₁} C
D : Type u₂
inst✝⁵ : Category.{v₂, u₂} D
inst✝⁴ : HasZeroMorphisms C
inst✝³ : HasZeroMorphisms D
F : C ⥤ D
inst✝² : PreservesZeroMorphisms F
X Y : C
inst✝¹ : HasBinaryBiproduct X Y
inst✝ : PreservesBinaryBiproduct X Y F
W : C
f : X ⟶ W
g : Y ⟶ W
⊢ (mapBiprod F X Y).hom ≫ desc (F.map f) (F.map g) = F.map (desc f g)

Next tactic:
rw [← biprod.mapBiprod_inv_map_desc, Iso.hom_inv_id_assoc]
theorem eq_iff_not_lt_of_le {α} [PartialOrder α] {x y : α} : x ≤ y → y = x ↔ ¬x < y := by
  

Proof state:
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α✝ → α✝ → Prop
α : Type u_3
inst✝ : PartialOrder α
x y : α
⊢ x ≤ y → y = x ↔ ¬x < y

Next tactic:
rw [lt_iff_le_and_ne, not_and, Classical.not_not, eq_comm]
theorem min_def' [LinearOrder α] (a b : α) : min a b = if b ≤ a then b else a := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
⊢ min a b = if b ≤ a then b else a

Next tactic:
rw [min_def]
theorem min_def' [LinearOrder α] (a b : α) : min a b = if b ≤ a then b else a := by
  rw [min_def]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
⊢ (if a ≤ b then a else b) = if b ≤ a then b else a

Next tactic:
rcases lt_trichotomy a b with (lt | eq | gt)
theorem min_def' [LinearOrder α] (a b : α) : min a b = if b ≤ a then b else a := by
  rw [min_def]
  rcases lt_trichotomy a b with (lt | eq | gt)
  · 

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
lt : a < b
⊢ (if a ≤ b then a else b) = if b ≤ a then b else a

Next tactic:
rw [if_pos lt.le, if_neg (not_le.mpr lt)]
theorem min_def' [LinearOrder α] (a b : α) : min a b = if b ≤ a then b else a := by
  rw [min_def]
  rcases lt_trichotomy a b with (lt | eq | gt)
  · rw [if_pos lt.le, if_neg (not_le.mpr lt)]
  · 

Proof state:
case inr.inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
eq : a = b
⊢ (if a ≤ b then a else b) = if b ≤ a then b else a

Next tactic:
rw [if_pos eq.le, if_pos eq.ge, eq]
theorem min_def' [LinearOrder α] (a b : α) : min a b = if b ≤ a then b else a := by
  rw [min_def]
  rcases lt_trichotomy a b with (lt | eq | gt)
  · rw [if_pos lt.le, if_neg (not_le.mpr lt)]
  · rw [if_pos eq.le, if_pos eq.ge, eq]
  · 

Proof state:
case inr.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
gt : b < a
⊢ (if a ≤ b then a else b) = if b ≤ a then b else a

Next tactic:
rw [if_neg (not_le.mpr gt.gt), if_pos gt.le]
theorem max_def' [LinearOrder α] (a b : α) : max a b = if b ≤ a then a else b := by
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
⊢ max a b = if b ≤ a then a else b

Next tactic:
rw [max_def]
theorem max_def' [LinearOrder α] (a b : α) : max a b = if b ≤ a then a else b := by
  rw [max_def]
  

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
⊢ (if a ≤ b then b else a) = if b ≤ a then a else b

Next tactic:
rcases lt_trichotomy a b with (lt | eq | gt)
theorem max_def' [LinearOrder α] (a b : α) : max a b = if b ≤ a then a else b := by
  rw [max_def]
  rcases lt_trichotomy a b with (lt | eq | gt)
  · 

Proof state:
case inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
lt : a < b
⊢ (if a ≤ b then b else a) = if b ≤ a then a else b

Next tactic:
rw [if_pos lt.le, if_neg (not_le.mpr lt)]
theorem max_def' [LinearOrder α] (a b : α) : max a b = if b ≤ a then a else b := by
  rw [max_def]
  rcases lt_trichotomy a b with (lt | eq | gt)
  · rw [if_pos lt.le, if_neg (not_le.mpr lt)]
  · 

Proof state:
case inr.inl
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
eq : a = b
⊢ (if a ≤ b then b else a) = if b ≤ a then a else b

Next tactic:
rw [if_pos eq.le, if_pos eq.ge, eq]
theorem max_def' [LinearOrder α] (a b : α) : max a b = if b ≤ a then a else b := by
  rw [max_def]
  rcases lt_trichotomy a b with (lt | eq | gt)
  · rw [if_pos lt.le, if_neg (not_le.mpr lt)]
  · rw [if_pos eq.le, if_pos eq.ge, eq]
  · 

Proof state:
case inr.inr
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : LinearOrder α
a b : α
gt : b < a
⊢ (if a ≤ b then b else a) = if b ≤ a then a else b

Next tactic:
rw [if_neg (not_le.mpr gt.gt), if_pos gt.le]
/-- To prove associativity of a commutative binary operation `○`, we only to check
`(a ○ b) ○ c ≤ a ○ (b ○ c)` for all `a`, `b`, `c`. -/
theorem associative_of_commutative_of_le {f : α → α → α} (comm : Commutative f)
    (assoc : ∀ a b c, f (f a b) c ≤ f a (f b c)) : Associative f := fun a b c ↦
  le_antisymm (assoc _ _ _) <| by
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : PartialOrder α
f : α → α → α
comm : Commutative f
assoc : ∀ (a b c : α), f (f a b) c ≤ f a (f b c)
a b c : α
⊢ f a (f b c) ≤ f (f a b) c

Next tactic:
rw [comm, comm b, comm _ c, comm a]
/-- To prove associativity of a commutative binary operation `○`, we only to check
`(a ○ b) ○ c ≤ a ○ (b ○ c)` for all `a`, `b`, `c`. -/
theorem associative_of_commutative_of_le {f : α → α → α} (comm : Commutative f)
    (assoc : ∀ a b c, f (f a b) c ≤ f a (f b c)) : Associative f := fun a b c ↦
  le_antisymm (assoc _ _ _) <| by
    rw [comm, comm b, comm _ c, comm a]
    

Proof state:
ι : Type u_1
α : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α → α → Prop
inst✝ : PartialOrder α
f : α → α → α
comm : Commutative f
assoc : ∀ (a b c : α), f (f a b) c ≤ f a (f b c)
a b c : α
⊢ f (f c b) a ≤ f c (f b a)

Next tactic:
exact assoc _ _ _
@[ext]
theorem Preorder.toLE_injective {α : Type*} : Function.Injective (@Preorder.toLE α) :=
  fun A B h ↦ match A, B with
  | { lt := A_lt, lt_iff_le_not_le := A_iff, .. },
    { lt := B_lt, lt_iff_le_not_le := B_iff, .. } => by
    

Proof state:
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α✝ → α✝ → Prop
α : Type u_3
A B : Preorder α
le✝¹ A_lt : α → α → Prop
le_refl✝¹ : ∀ (a : α), a ≤ a
le_trans✝¹ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
A_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
le✝ B_lt : α → α → Prop
le_refl✝ : ∀ (a : α), a ≤ a
le_trans✝ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
B_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
h : toLE = toLE
⊢ mk le_refl✝¹ le_trans✝¹ = mk le_refl✝ le_trans✝

Next tactic:
cases h
@[ext]
theorem Preorder.toLE_injective {α : Type*} : Function.Injective (@Preorder.toLE α) :=
  fun A B h ↦ match A, B with
  | { lt := A_lt, lt_iff_le_not_le := A_iff, .. },
    { lt := B_lt, lt_iff_le_not_le := B_iff, .. } => by
    cases h
    

Proof state:
case refl
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α✝ → α✝ → Prop
α : Type u_3
A B : Preorder α
le✝ A_lt : α → α → Prop
le_refl✝¹ : ∀ (a : α), a ≤ a
le_trans✝¹ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
A_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
B_lt : α → α → Prop
le_refl✝ : ∀ (a : α), a ≤ a
le_trans✝ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
B_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
⊢ mk le_refl✝¹ le_trans✝¹ = mk le_refl✝ le_trans✝

Next tactic:
have : A_lt = B_lt := by
      funext a b
      show (LT.mk A_lt).lt a b = (LT.mk B_lt).lt a b
      rw [A_iff, B_iff]
@[ext]
theorem Preorder.toLE_injective {α : Type*} : Function.Injective (@Preorder.toLE α) :=
  fun A B h ↦ match A, B with
  | { lt := A_lt, lt_iff_le_not_le := A_iff, .. },
    { lt := B_lt, lt_iff_le_not_le := B_iff, .. } => by
    cases h
    have : A_lt = B_lt := by
      

Proof state:
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α✝ → α✝ → Prop
α : Type u_3
A B : Preorder α
le✝ A_lt : α → α → Prop
le_refl✝¹ : ∀ (a : α), a ≤ a
le_trans✝¹ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
A_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
B_lt : α → α → Prop
le_refl✝ : ∀ (a : α), a ≤ a
le_trans✝ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
B_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
⊢ A_lt = B_lt

Next tactic:
funext a b
@[ext]
theorem Preorder.toLE_injective {α : Type*} : Function.Injective (@Preorder.toLE α) :=
  fun A B h ↦ match A, B with
  | { lt := A_lt, lt_iff_le_not_le := A_iff, .. },
    { lt := B_lt, lt_iff_le_not_le := B_iff, .. } => by
    cases h
    have : A_lt = B_lt := by
      funext a b
      

Proof state:
case h.h
ι : Type u_1
α✝ : Type u
β : Type v
γ : Type w
π : ι → Type u_2
r : α✝ → α✝ → Prop
α : Type u_3
A B : Preorder α
le✝ A_lt : α → α → Prop
le_refl✝¹ : ∀ (a : α), a ≤ a
le_trans✝¹ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
A_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
B_lt : α → α → Prop
le_refl✝ : ∀ (a : α), a ≤ a
le_trans✝ : ∀ (a b c : α), a ≤ b → b ≤ c → a ≤ c
B_iff : ∀ (a b : α), a < b ↔ a ≤ b ∧ ¬b ≤ a
a b : α
⊢ A_lt a b = B_lt a b

Next tactic:
show (LT.mk A_lt).lt a b = (LT.mk B_lt).lt a b