l3lab/ntp-mathlib huggingface dataset:
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · 

Proof state:
case intro.h.hD
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
this : { val := y, property := hy } ∈ Subring.center ↥R
⊢ x * y = y * x

Next tactic:
rw [Subring.mem_center_iff] at this
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · rw [Subring.mem_center_iff] at this
    

Proof state:
case intro.h.hD
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
this : ∀ (g : ↥R), g * { val := y, property := hy } = { val := y, property := hy } * g
⊢ x * y = y * x

Next tactic:
simpa using this ⟨x, hx⟩
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · rw [Subring.mem_center_iff] at this
    simpa using this ⟨x, hx⟩
  

Proof state:
case this
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
⊢ { val := y, property := hy } ∈ Subring.center ↥R

Next tactic:
let R_dr : DivisionRing R := Fintype.divisionRingOfIsDomain R
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · rw [Subring.mem_center_iff] at this
    simpa using this ⟨x, hx⟩
  let R_dr : DivisionRing R := Fintype.divisionRingOfIsDomain R
  

Proof state:
case this
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
R_dr : DivisionRing ↥R := divisionRingOfIsDomain ↥R
⊢ { val := y, property := hy } ∈ Subring.center ↥R

Next tactic:
rw [IH (Fintype.card R) _ R inferInstance rfl]
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · rw [Subring.mem_center_iff] at this
    simpa using this ⟨x, hx⟩
  let R_dr : DivisionRing R := Fintype.divisionRingOfIsDomain R
  rw [IH (Fintype.card R) _ R inferInstance rfl]
  · 

Proof state:
case this
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
R_dr : DivisionRing ↥R := divisionRingOfIsDomain ↥R
⊢ { val := y, property := hy } ∈ ⊤

Next tactic:
trivial
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · rw [Subring.mem_center_iff] at this
    simpa using this ⟨x, hx⟩
  let R_dr : DivisionRing R := Fintype.divisionRingOfIsDomain R
  rw [IH (Fintype.card R) _ R inferInstance rfl]
  · trivial
  

Proof state:
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
R_dr : DivisionRing ↥R := divisionRingOfIsDomain ↥R
⊢ card ↥R < n

Next tactic:
rw [← hn, ← Subring.card_top D]
private theorem center_eq_top [Finite D] : Subring.center D = ⊤ := by
  classical
  cases nonempty_fintype D
  induction' hn : Fintype.card D using Nat.strong_induction_on with n IH generalizing D
  apply InductionHyp.center_eq_top
  intro R hR x y hx hy
  suffices : (⟨y, hy⟩ : R) ∈ Subring.center R
  · rw [Subring.mem_center_iff] at this
    simpa using this ⟨x, hx⟩
  let R_dr : DivisionRing R := Fintype.divisionRingOfIsDomain R
  rw [IH (Fintype.card R) _ R inferInstance rfl]
  · trivial
  rw [← hn, ← Subring.card_top D]
  

Proof state:
n : ℕ
IH :
  ∀ m < n,
    ∀ (D : Type u_1) [inst : DivisionRing D] [inst_1 : Finite D] (val : Fintype D), card D = m → Subring.center D = ⊤
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
val✝ : Fintype D
hn : card D = n
R : Subring D
hR : R < ⊤
x y : D
hx : x ∈ R
hy : y ∈ R
R_dr : DivisionRing ↥R := divisionRingOfIsDomain ↥R
⊢ card ↥R < card ↥⊤

Next tactic:
exact Set.card_lt_card hR
/-- A finite division ring is a field. See `Finite.isDomain_to_isField` and
`Fintype.divisionRingOfIsDomain` for more general statements, but these create data, and therefore
may cause diamonds if used improperly. -/
instance (priority := 100) littleWedderburn (D : Type*) [DivisionRing D] [Finite D] : Field D :=
  { ‹DivisionRing D› with
    mul_comm := fun x y ↦ by 

Proof state:
D : Type u_1
inst✝¹ : DivisionRing D
inst✝ : Finite D
src✝ : DivisionRing D := inst✝¹
x y : D
⊢ x * y = y * x

Next tactic:
simp [Subring.mem_center_iff.mp ?_ x, center_eq_top D]
/-- A finite domain is a field. See also `littleWedderburn` and `Fintype.divisionRingOfIsDomain`. -/
theorem Finite.isDomain_to_isField (D : Type*) [Finite D] [Ring D] [IsDomain D] : IsField D := by
  

Proof state:
D : Type u_1
inst✝² : Finite D
inst✝¹ : Ring D
inst✝ : IsDomain D
⊢ IsField D

Next tactic:
classical
  cases nonempty_fintype D
  let _ := Fintype.divisionRingOfIsDomain D
  let _ := littleWedderburn D
  exact Field.toIsField D
/-- A finite domain is a field. See also `littleWedderburn` and `Fintype.divisionRingOfIsDomain`. -/
theorem Finite.isDomain_to_isField (D : Type*) [Finite D] [Ring D] [IsDomain D] : IsField D := by
  classical
  

Proof state:
D : Type u_1
inst✝² : Finite D
inst✝¹ : Ring D
inst✝ : IsDomain D
⊢ IsField D

Next tactic:
cases nonempty_fintype D
/-- A finite domain is a field. See also `littleWedderburn` and `Fintype.divisionRingOfIsDomain`. -/
theorem Finite.isDomain_to_isField (D : Type*) [Finite D] [Ring D] [IsDomain D] : IsField D := by
  classical
  cases nonempty_fintype D
  

Proof state:
case intro
D : Type u_1
inst✝² : Finite D
inst✝¹ : Ring D
inst✝ : IsDomain D
val✝ : Fintype D
⊢ IsField D

Next tactic:
let _ := Fintype.divisionRingOfIsDomain D
/-- A finite domain is a field. See also `littleWedderburn` and `Fintype.divisionRingOfIsDomain`. -/
theorem Finite.isDomain_to_isField (D : Type*) [Finite D] [Ring D] [IsDomain D] : IsField D := by
  classical
  cases nonempty_fintype D
  let _ := Fintype.divisionRingOfIsDomain D
  

Proof state:
case intro
D : Type u_1
inst✝² : Finite D
inst✝¹ : Ring D
inst✝ : IsDomain D
val✝ : Fintype D
x✝ : DivisionRing D := divisionRingOfIsDomain D
⊢ IsField D

Next tactic:
let _ := littleWedderburn D
/-- A finite domain is a field. See also `littleWedderburn` and `Fintype.divisionRingOfIsDomain`. -/
theorem Finite.isDomain_to_isField (D : Type*) [Finite D] [Ring D] [IsDomain D] : IsField D := by
  classical
  cases nonempty_fintype D
  let _ := Fintype.divisionRingOfIsDomain D
  let _ := littleWedderburn D
  

Proof state:
case intro
D : Type u_1
inst✝² : Finite D
inst✝¹ : Ring D
inst✝ : IsDomain D
val✝ : Fintype D
x✝¹ : DivisionRing D := divisionRingOfIsDomain D
x✝ : Field D := littleWedderburn D
⊢ IsField D

Next tactic:
exact Field.toIsField D
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatSupCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : SupBotHom _ _)
  inv := (e.symm : SupBotHom _ _)
  hom_inv_id := by 

Proof state:
α β : SemilatSupCat
e : α.X ≃o β.X
⊢ { toSupHom := { toFun := ⇑e, map_sup' := (_ : ∀ (a b : α.X), e (a ⊔ b) = e a ⊔ e b) }, map_bot' := (_ : e ⊥ = ⊥) } ≫
      {
        toSupHom :=
          { toFun := ⇑(OrderIso.symm e),
            map_sup' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊔ b) = (OrderIso.symm e) a ⊔ (OrderIso.symm e) b) },
        map_bot' := (_ : (OrderIso.symm e) ⊥ = ⊥) } =
    𝟙 α

Next tactic:
ext
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatSupCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : SupBotHom _ _)
  inv := (e.symm : SupBotHom _ _)
  hom_inv_id := by ext; 

Proof state:
case w
α β : SemilatSupCat
e : α.X ≃o β.X
x✝ : (forget SemilatSupCat).obj α
⊢ ({ toSupHom := { toFun := ⇑e, map_sup' := (_ : ∀ (a b : α.X), e (a ⊔ b) = e a ⊔ e b) }, map_bot' := (_ : e ⊥ = ⊥) } ≫
        {
          toSupHom :=
            { toFun := ⇑(OrderIso.symm e),
              map_sup' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊔ b) = (OrderIso.symm e) a ⊔ (OrderIso.symm e) b) },
          map_bot' := (_ : (OrderIso.symm e) ⊥ = ⊥) })
      x✝ =
    (𝟙 α) x✝

Next tactic:
exact e.symm_apply_apply _
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatSupCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : SupBotHom _ _)
  inv := (e.symm : SupBotHom _ _)
  hom_inv_id := by ext; exact e.symm_apply_apply _
  inv_hom_id := by 

Proof state:
α β : SemilatSupCat
e : α.X ≃o β.X
⊢ {
        toSupHom :=
          { toFun := ⇑(OrderIso.symm e),
            map_sup' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊔ b) = (OrderIso.symm e) a ⊔ (OrderIso.symm e) b) },
        map_bot' := (_ : (OrderIso.symm e) ⊥ = ⊥) } ≫
      { toSupHom := { toFun := ⇑e, map_sup' := (_ : ∀ (a b : α.X), e (a ⊔ b) = e a ⊔ e b) },
        map_bot' := (_ : e ⊥ = ⊥) } =
    𝟙 β

Next tactic:
ext
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatSupCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : SupBotHom _ _)
  inv := (e.symm : SupBotHom _ _)
  hom_inv_id := by ext; exact e.symm_apply_apply _
  inv_hom_id := by ext; 

Proof state:
case w
α β : SemilatSupCat
e : α.X ≃o β.X
x✝ : (forget SemilatSupCat).obj β
⊢ ({
          toSupHom :=
            { toFun := ⇑(OrderIso.symm e),
              map_sup' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊔ b) = (OrderIso.symm e) a ⊔ (OrderIso.symm e) b) },
          map_bot' := (_ : (OrderIso.symm e) ⊥ = ⊥) } ≫
        { toSupHom := { toFun := ⇑e, map_sup' := (_ : ∀ (a b : α.X), e (a ⊔ b) = e a ⊔ e b) },
          map_bot' := (_ : e ⊥ = ⊥) })
      x✝ =
    (𝟙 β) x✝

Next tactic:
exact e.apply_symm_apply _
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatInfCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : InfTopHom _ _)
  inv := (e.symm :  InfTopHom _ _)
  hom_inv_id := by 

Proof state:
α β : SemilatInfCat
e : α.X ≃o β.X
⊢ { toInfHom := { toFun := ⇑e, map_inf' := (_ : ∀ (a b : α.X), e (a ⊓ b) = e a ⊓ e b) }, map_top' := (_ : e ⊤ = ⊤) } ≫
      {
        toInfHom :=
          { toFun := ⇑(OrderIso.symm e),
            map_inf' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊓ b) = (OrderIso.symm e) a ⊓ (OrderIso.symm e) b) },
        map_top' := (_ : (OrderIso.symm e) ⊤ = ⊤) } =
    𝟙 α

Next tactic:
ext
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatInfCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : InfTopHom _ _)
  inv := (e.symm :  InfTopHom _ _)
  hom_inv_id := by ext; 

Proof state:
case w
α β : SemilatInfCat
e : α.X ≃o β.X
x✝ : (forget SemilatInfCat).obj α
⊢ ({ toInfHom := { toFun := ⇑e, map_inf' := (_ : ∀ (a b : α.X), e (a ⊓ b) = e a ⊓ e b) }, map_top' := (_ : e ⊤ = ⊤) } ≫
        {
          toInfHom :=
            { toFun := ⇑(OrderIso.symm e),
              map_inf' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊓ b) = (OrderIso.symm e) a ⊓ (OrderIso.symm e) b) },
          map_top' := (_ : (OrderIso.symm e) ⊤ = ⊤) })
      x✝ =
    (𝟙 α) x✝

Next tactic:
exact e.symm_apply_apply _
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatInfCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : InfTopHom _ _)
  inv := (e.symm :  InfTopHom _ _)
  hom_inv_id := by ext; exact e.symm_apply_apply _
  inv_hom_id := by 

Proof state:
α β : SemilatInfCat
e : α.X ≃o β.X
⊢ {
        toInfHom :=
          { toFun := ⇑(OrderIso.symm e),
            map_inf' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊓ b) = (OrderIso.symm e) a ⊓ (OrderIso.symm e) b) },
        map_top' := (_ : (OrderIso.symm e) ⊤ = ⊤) } ≫
      { toInfHom := { toFun := ⇑e, map_inf' := (_ : ∀ (a b : α.X), e (a ⊓ b) = e a ⊓ e b) },
        map_top' := (_ : e ⊤ = ⊤) } =
    𝟙 β

Next tactic:
ext
/-- Constructs an isomorphism of lattices from an order isomorphism between them. -/
@[simps]
def Iso.mk {α β : SemilatInfCat.{u}} (e : α ≃o β) : α ≅ β where
  hom := (e : InfTopHom _ _)
  inv := (e.symm :  InfTopHom _ _)
  hom_inv_id := by ext; exact e.symm_apply_apply _
  inv_hom_id := by ext; 

Proof state:
case w
α β : SemilatInfCat
e : α.X ≃o β.X
x✝ : (forget SemilatInfCat).obj β
⊢ ({
          toInfHom :=
            { toFun := ⇑(OrderIso.symm e),
              map_inf' := (_ : ∀ (a b : β.X), (OrderIso.symm e) (a ⊓ b) = (OrderIso.symm e) a ⊓ (OrderIso.symm e) b) },
          map_top' := (_ : (OrderIso.symm e) ⊤ = ⊤) } ≫
        { toInfHom := { toFun := ⇑e, map_inf' := (_ : ∀ (a b : α.X), e (a ⊓ b) = e a ⊓ e b) },
          map_top' := (_ : e ⊤ = ⊤) })
      x✝ =
    (𝟙 β) x✝

Next tactic:
exact e.apply_symm_apply _
/-- To show a reflexive relation `r : α → α → Prop` holds over `x y : α`,
it suffices to show it holds when `x ≠ y`. -/
theorem Reflexive.rel_of_ne_imp (h : Reflexive r) {x y : α} (hr : x ≠ y → r x y) : r x y := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → α → Prop
h : Reflexive r
x y : α
hr : x ≠ y → r x y
⊢ r x y

Next tactic:
by_cases hxy : x = y
/-- To show a reflexive relation `r : α → α → Prop` holds over `x y : α`,
it suffices to show it holds when `x ≠ y`. -/
theorem Reflexive.rel_of_ne_imp (h : Reflexive r) {x y : α} (hr : x ≠ y → r x y) : r x y := by
  by_cases hxy : x = y
  · 

Proof state:
case pos
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → α → Prop
h : Reflexive r
x y : α
hr : x ≠ y → r x y
hxy : x = y
⊢ r x y

Next tactic:
exact hxy ▸ h x
/-- To show a reflexive relation `r : α → α → Prop` holds over `x y : α`,
it suffices to show it holds when `x ≠ y`. -/
theorem Reflexive.rel_of_ne_imp (h : Reflexive r) {x y : α} (hr : x ≠ y → r x y) : r x y := by
  by_cases hxy : x = y
  · exact hxy ▸ h x
  · 

Proof state:
case neg
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → α → Prop
h : Reflexive r
x y : α
hr : x ≠ y → r x y
hxy : ¬x = y
⊢ r x y

Next tactic:
exact hr hxy
theorem iff_comp {r : Prop → α → Prop} : (· ↔ ·) ∘r r = r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : Prop → α → Prop
⊢ (fun x x_1 => x ↔ x_1) ∘r r = r

Next tactic:
have : (· ↔ ·) = (· = ·) := by funext a b; exact iff_eq_eq
theorem iff_comp {r : Prop → α → Prop} : (· ↔ ·) ∘r r = r := by
  have : (· ↔ ·) = (· = ·) := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : Prop → α → Prop
⊢ (fun x x_1 => x ↔ x_1) = fun x x_1 => x = x_1

Next tactic:
funext a b
theorem iff_comp {r : Prop → α → Prop} : (· ↔ ·) ∘r r = r := by
  have : (· ↔ ·) = (· = ·) := by funext a b; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : Prop → α → Prop
a b : Prop
⊢ (a ↔ b) = (a = b)

Next tactic:
exact iff_eq_eq
theorem iff_comp {r : Prop → α → Prop} : (· ↔ ·) ∘r r = r := by
  have : (· ↔ ·) = (· = ·) := by funext a b; exact iff_eq_eq
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : Prop → α → Prop
this : (fun x x_1 => x ↔ x_1) = fun x x_1 => x = x_1
⊢ (fun x x_1 => x ↔ x_1) ∘r r = r

Next tactic:
rw [this, eq_comp]
theorem comp_iff {r : α → Prop → Prop} : r ∘r (· ↔ ·) = r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : α → Prop → Prop
⊢ (r ∘r fun x x_1 => x ↔ x_1) = r

Next tactic:
have : (· ↔ ·) = (· = ·) := by funext a b; exact iff_eq_eq
theorem comp_iff {r : α → Prop → Prop} : r ∘r (· ↔ ·) = r := by
  have : (· ↔ ·) = (· = ·) := by 

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : α → Prop → Prop
⊢ (fun x x_1 => x ↔ x_1) = fun x x_1 => x = x_1

Next tactic:
funext a b
theorem comp_iff {r : α → Prop → Prop} : r ∘r (· ↔ ·) = r := by
  have : (· ↔ ·) = (· = ·) := by funext a b; 

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : α → Prop → Prop
a b : Prop
⊢ (a ↔ b) = (a = b)

Next tactic:
exact iff_eq_eq
theorem comp_iff {r : α → Prop → Prop} : r ∘r (· ↔ ·) = r := by
  have : (· ↔ ·) = (· = ·) := by funext a b; exact iff_eq_eq
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r✝ : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
r : α → Prop → Prop
this : (fun x x_1 => x ↔ x_1) = fun x x_1 => x = x_1
⊢ (r ∘r fun x x_1 => x ↔ x_1) = r

Next tactic:
rw [this, comp_eq]
theorem comp_assoc : (r ∘r p) ∘r q = r ∘r p ∘r q := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
⊢ (r ∘r p) ∘r q = r ∘r p ∘r q

Next tactic:
funext a d
theorem comp_assoc : (r ∘r p) ∘r q = r ∘r p ∘r q := by
  funext a d
  

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
a : α
d : δ
⊢ ((r ∘r p) ∘r q) a d = (r ∘r p ∘r q) a d

Next tactic:
apply propext
theorem comp_assoc : (r ∘r p) ∘r q = r ∘r p ∘r q := by
  funext a d
  apply propext
  

Proof state:
case h.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
a : α
d : δ
⊢ ((r ∘r p) ∘r q) a d ↔ (r ∘r p ∘r q) a d

Next tactic:
constructor
theorem comp_assoc : (r ∘r p) ∘r q = r ∘r p ∘r q := by
  funext a d
  apply propext
  constructor
  

Proof state:
case h.h.a.mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
a : α
d : δ
⊢ ((r ∘r p) ∘r q) a d → (r ∘r p ∘r q) a d
case h.h.a.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
a : α
d : δ
⊢ (r ∘r p ∘r q) a d → ((r ∘r p) ∘r q) a d

Next tactic:
exact fun ⟨c, ⟨b, hab, hbc⟩, hcd⟩ ↦ ⟨b, hab, c, hbc, hcd⟩
theorem comp_assoc : (r ∘r p) ∘r q = r ∘r p ∘r q := by
  funext a d
  apply propext
  constructor
  exact fun ⟨c, ⟨b, hab, hbc⟩, hcd⟩ ↦ ⟨b, hab, c, hbc, hcd⟩
  

Proof state:
case h.h.a.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
a : α
d : δ
⊢ (r ∘r p ∘r q) a d → ((r ∘r p) ∘r q) a d

Next tactic:
exact fun ⟨b, hab, c, hbc, hcd⟩ ↦ ⟨c, ⟨b, hab, hbc⟩, hcd⟩
theorem flip_comp : flip (r ∘r p) = flip p ∘r flip r := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
⊢ flip (r ∘r p) = flip p ∘r flip r

Next tactic:
funext c a
theorem flip_comp : flip (r ∘r p) = flip p ∘r flip r := by
  funext c a
  

Proof state:
case h.h
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
c : γ
a : α
⊢ flip (r ∘r p) c a = (flip p ∘r flip r) c a

Next tactic:
apply propext
theorem flip_comp : flip (r ∘r p) = flip p ∘r flip r := by
  funext c a
  apply propext
  

Proof state:
case h.h.a
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
c : γ
a : α
⊢ flip (r ∘r p) c a ↔ (flip p ∘r flip r) c a

Next tactic:
constructor
theorem flip_comp : flip (r ∘r p) = flip p ∘r flip r := by
  funext c a
  apply propext
  constructor
  

Proof state:
case h.h.a.mp
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
c : γ
a : α
⊢ flip (r ∘r p) c a → (flip p ∘r flip r) c a
case h.h.a.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
c : γ
a : α
⊢ (flip p ∘r flip r) c a → flip (r ∘r p) c a

Next tactic:
exact fun ⟨b, hab, hbc⟩ ↦ ⟨b, hbc, hab⟩
theorem flip_comp : flip (r ∘r p) = flip p ∘r flip r := by
  funext c a
  apply propext
  constructor
  exact fun ⟨b, hab, hbc⟩ ↦ ⟨b, hbc, hab⟩
  

Proof state:
case h.h.a.mpr
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
r : α → β → Prop
p : β → γ → Prop
q : γ → δ → Prop
c : γ
a : α
⊢ (flip p ∘r flip r) c a → flip (r ∘r p) c a

Next tactic:
exact fun ⟨b, hbc, hab⟩ ↦ ⟨b, hab, hbc⟩
/-- If `f : α → β` is a fibration between relations `rα` and `rβ`, and `a : α` is
  accessible under `rα`, then `f a` is accessible under `rβ`. -/
theorem _root_.Acc.of_fibration (fib : Fibration rα rβ f) {a} (ha : Acc rα a) : Acc rβ (f a) := by
  

Proof state:
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
rα : α → α → Prop
rβ : β → β → Prop
f : α → β
fib : Fibration rα rβ f
a : α
ha : Acc rα a
⊢ Acc rβ (f a)

Next tactic:
induction' ha with a _ ih
/-- If `f : α → β` is a fibration between relations `rα` and `rβ`, and `a : α` is
  accessible under `rα`, then `f a` is accessible under `rβ`. -/
theorem _root_.Acc.of_fibration (fib : Fibration rα rβ f) {a} (ha : Acc rα a) : Acc rβ (f a) := by
  induction' ha with a _ ih
  

Proof state:
case intro
α : Type u_1
β : Type u_2
γ : Type u_3
δ : Type u_4
ε : Type u_5
ζ : Type u_6
rα : α → α → Prop
rβ : β → β → Prop
f : α → β
fib : Fibration rα rβ f
a✝ a : α
h✝ : ∀ (y : α), rα y a → Acc rα y
ih : ∀ (y : α), rα y a → Acc rβ (f y)
⊢ Acc rβ (f a)

Next tactic:
refine' Acc.intro (f a) fun b hr ↦ _