l3lab/ntp-mathlib huggingface dataset:
theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c a b : α
⊢ (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ

Next tactic:
refine' le_antisymm _ _
theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by
  refine' le_antisymm _ _
  · 

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c a b : α
⊢ (a ⇨ b)ᶜᶜ ≤ aᶜᶜ ⇨ bᶜᶜ

Next tactic:
rw [le_himp_iff, ← compl_compl_inf_distrib]
theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by
  refine' le_antisymm _ _
  · rw [le_himp_iff, ← compl_compl_inf_distrib]
    

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c a b : α
⊢ ((a ⇨ b) ⊓ a)ᶜᶜ ≤ bᶜᶜ

Next tactic:
exact compl_anti (compl_anti himp_inf_le)
theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by
  refine' le_antisymm _ _
  · rw [le_himp_iff, ← compl_compl_inf_distrib]
    exact compl_anti (compl_anti himp_inf_le)
  · 

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c a b : α
⊢ aᶜᶜ ⇨ bᶜᶜ ≤ (a ⇨ b)ᶜᶜ

Next tactic:
refine' le_compl_comm.1 ((compl_anti compl_sup_le_himp).trans _)
theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by
  refine' le_antisymm _ _
  · rw [le_himp_iff, ← compl_compl_inf_distrib]
    exact compl_anti (compl_anti himp_inf_le)
  · refine' le_compl_comm.1 ((compl_anti compl_sup_le_himp).trans _)
    

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c a b : α
⊢ (aᶜ ⊔ b)ᶜ ≤ (aᶜᶜ ⇨ bᶜᶜ)ᶜ

Next tactic:
rw [compl_sup_distrib, le_compl_iff_disjoint_right, disjoint_right_comm, ←
      le_compl_iff_disjoint_right]
theorem compl_compl_himp_distrib (a b : α) : (a ⇨ b)ᶜᶜ = aᶜᶜ ⇨ bᶜᶜ := by
  refine' le_antisymm _ _
  · rw [le_himp_iff, ← compl_compl_inf_distrib]
    exact compl_anti (compl_anti himp_inf_le)
  · refine' le_compl_comm.1 ((compl_anti compl_sup_le_himp).trans _)
    rw [compl_sup_distrib, le_compl_iff_disjoint_right, disjoint_right_comm, ←
      le_compl_iff_disjoint_right]
    

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c a b : α
⊢ aᶜᶜ ⊓ (aᶜᶜ ⇨ bᶜᶜ) ≤ bᶜᶜ

Next tactic:
exact inf_himp_le
instance : CoheytingAlgebra αᵒᵈ :=
  { OrderDual.lattice α, OrderDual.boundedOrder α with
    hnot := toDual ∘ compl ∘ ofDual,
    sdiff := fun a b => toDual (ofDual b ⇨ ofDual a),
    sdiff_le_iff := fun a b c => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c✝ : α
src✝¹ : Lattice αᵒᵈ := lattice α
src✝ : BoundedOrder αᵒᵈ := boundedOrder α
a b c : αᵒᵈ
⊢ a \ b ≤ c ↔ a ≤ b ⊔ c

Next tactic:
rw [sup_comm]
instance : CoheytingAlgebra αᵒᵈ :=
  { OrderDual.lattice α, OrderDual.boundedOrder α with
    hnot := toDual ∘ compl ∘ ofDual,
    sdiff := fun a b => toDual (ofDual b ⇨ ofDual a),
    sdiff_le_iff := fun a b c => by
      rw [sup_comm]
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : HeytingAlgebra α
a✝ b✝ c✝ : α
src✝¹ : Lattice αᵒᵈ := lattice α
src✝ : BoundedOrder αᵒᵈ := boundedOrder α
a b c : αᵒᵈ
⊢ a \ b ≤ c ↔ a ≤ c ⊔ b

Next tactic:
exact le_himp_iff
theorem hnot_inf_distrib (a b : α) : ￢(a ⊓ b) = ￢a ⊔ ￢b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢(a ⊓ b) = ￢a ⊔ ￢b

Next tactic:
simp_rw [← top_sdiff', sdiff_inf_distrib]
instance (priority := 100) CoheytingAlgebra.toDistribLattice : DistribLattice α :=
  { ‹CoheytingAlgebra α› with
    le_sup_inf :=
      fun a b c => by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c✝ : α
src✝ : CoheytingAlgebra α := inst✝
a b c : α
⊢ (a ⊔ b) ⊓ (a ⊔ c) ≤ a ⊔ b ⊓ c

Next tactic:
simp_rw [← sdiff_le_iff, le_inf_iff, sdiff_le_iff, ← le_inf_iff]
instance (priority := 100) CoheytingAlgebra.toDistribLattice : DistribLattice α :=
  { ‹CoheytingAlgebra α› with
    le_sup_inf :=
      fun a b c => by simp_rw [← sdiff_le_iff, le_inf_iff, sdiff_le_iff, ← le_inf_iff]; 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c✝ : α
src✝ : CoheytingAlgebra α := inst✝
a b c : α
⊢ (a ⊔ b) ⊓ (a ⊔ c) ≤ (a ⊔ b) ⊓ (a ⊔ c)

Next tactic:
rfl
@[simp]
theorem hnot_sdiff (a : α) : ￢a \ a = ￢a := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b c a : α
⊢ ￢a \ a = ￢a

Next tactic:
rw [← top_sdiff', sdiff_sdiff, sup_idem]
theorem hnot_sdiff_comm (a b : α) : ￢a \ b = ￢b \ a := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢a \ b = ￢b \ a

Next tactic:
simp_rw [← top_sdiff', sdiff_right_comm]
theorem hnot_le_iff_codisjoint_right : ￢a ≤ b ↔ Codisjoint a b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a b c : α
⊢ ￢a ≤ b ↔ Codisjoint a b

Next tactic:
rw [← top_sdiff', sdiff_le_iff, codisjoint_iff_le_sup]
theorem hnot_le_comm : ￢a ≤ b ↔ ￢b ≤ a := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a b c : α
⊢ ￢a ≤ b ↔ ￢b ≤ a

Next tactic:
rw [hnot_le_iff_codisjoint_right, hnot_le_iff_codisjoint_left]
@[simp]
theorem hnot_bot : ￢(⊥ : α) = ⊤ :=
  eq_of_forall_ge_iff fun a => by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b c a : α
⊢ ￢⊥ ≤ a ↔ ⊤ ≤ a

Next tactic:
rw [hnot_le_iff_codisjoint_left, codisjoint_bot, top_le_iff]
@[simp]
theorem hnot_top : ￢(⊤ : α) = ⊥ := by 

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a b c : α
⊢ ￢⊤ = ⊥

Next tactic:
rw [← top_sdiff', sdiff_self]
@[simp]
theorem codisjoint_hnot_hnot_left_iff : Codisjoint (￢￢a) b ↔ Codisjoint a b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a b c : α
⊢ Codisjoint (￢￢a) b ↔ Codisjoint a b

Next tactic:
simp_rw [← hnot_le_iff_codisjoint_right, hnot_hnot_hnot]
@[simp]
theorem codisjoint_hnot_hnot_right_iff : Codisjoint a (￢￢b) ↔ Codisjoint a b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a b c : α
⊢ Codisjoint a (￢￢b) ↔ Codisjoint a b

Next tactic:
simp_rw [← hnot_le_iff_codisjoint_left, hnot_hnot_hnot]
theorem hnot_hnot_sup_distrib (a b : α) : ￢￢(a ⊔ b) = ￢￢a ⊔ ￢￢b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢(a ⊔ b) = ￢￢a ⊔ ￢￢b

Next tactic:
refine' ((hnot_inf_distrib _ _).ge.trans <| hnot_anti le_hnot_inf_hnot).antisymm' _
theorem hnot_hnot_sup_distrib (a b : α) : ￢￢(a ⊔ b) = ￢￢a ⊔ ￢￢b := by
  refine' ((hnot_inf_distrib _ _).ge.trans <| hnot_anti le_hnot_inf_hnot).antisymm' _
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢(a ⊔ b) ≤ ￢￢a ⊔ ￢￢b

Next tactic:
rw [hnot_le_iff_codisjoint_left, codisjoint_assoc, codisjoint_hnot_hnot_left_iff,
    codisjoint_left_comm, codisjoint_hnot_hnot_left_iff, ← codisjoint_assoc, sup_comm]
theorem hnot_hnot_sup_distrib (a b : α) : ￢￢(a ⊔ b) = ￢￢a ⊔ ￢￢b := by
  refine' ((hnot_inf_distrib _ _).ge.trans <| hnot_anti le_hnot_inf_hnot).antisymm' _
  rw [hnot_le_iff_codisjoint_left, codisjoint_assoc, codisjoint_hnot_hnot_left_iff,
    codisjoint_left_comm, codisjoint_hnot_hnot_left_iff, ← codisjoint_assoc, sup_comm]
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ Codisjoint (a ⊔ b) (￢(a ⊔ b))

Next tactic:
exact codisjoint_hnot_right
theorem hnot_hnot_sdiff_distrib (a b : α) : ￢￢(a \ b) = ￢￢a \ ￢￢b := by
  

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢(a \ b) = ￢￢a \ ￢￢b

Next tactic:
refine' le_antisymm _ _
theorem hnot_hnot_sdiff_distrib (a b : α) : ￢￢(a \ b) = ￢￢a \ ￢￢b := by
  refine' le_antisymm _ _
  · 

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢(a \ b) ≤ ￢￢a \ ￢￢b

Next tactic:
refine' hnot_le_comm.1 ((hnot_anti sdiff_le_inf_hnot).trans' _)
theorem hnot_hnot_sdiff_distrib (a b : α) : ￢￢(a \ b) = ￢￢a \ ￢￢b := by
  refine' le_antisymm _ _
  · refine' hnot_le_comm.1 ((hnot_anti sdiff_le_inf_hnot).trans' _)
    

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢(￢￢a \ ￢￢b) ≤ ￢(a ⊓ ￢b)

Next tactic:
rw [hnot_inf_distrib, hnot_le_iff_codisjoint_right, codisjoint_left_comm, ←
      hnot_le_iff_codisjoint_right]
theorem hnot_hnot_sdiff_distrib (a b : α) : ￢￢(a \ b) = ￢￢a \ ￢￢b := by
  refine' le_antisymm _ _
  · refine' hnot_le_comm.1 ((hnot_anti sdiff_le_inf_hnot).trans' _)
    rw [hnot_inf_distrib, hnot_le_iff_codisjoint_right, codisjoint_left_comm, ←
      hnot_le_iff_codisjoint_right]
    

Proof state:
case refine'_1
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢a ≤ ￢￢a \ ￢￢b ⊔ ￢￢b

Next tactic:
exact le_sdiff_sup
theorem hnot_hnot_sdiff_distrib (a b : α) : ￢￢(a \ b) = ￢￢a \ ￢￢b := by
  refine' le_antisymm _ _
  · refine' hnot_le_comm.1 ((hnot_anti sdiff_le_inf_hnot).trans' _)
    rw [hnot_inf_distrib, hnot_le_iff_codisjoint_right, codisjoint_left_comm, ←
      hnot_le_iff_codisjoint_right]
    exact le_sdiff_sup
  · 

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢a \ ￢￢b ≤ ￢￢(a \ b)

Next tactic:
rw [sdiff_le_iff, ← hnot_hnot_sup_distrib]
theorem hnot_hnot_sdiff_distrib (a b : α) : ￢￢(a \ b) = ￢￢a \ ￢￢b := by
  refine' le_antisymm _ _
  · refine' hnot_le_comm.1 ((hnot_anti sdiff_le_inf_hnot).trans' _)
    rw [hnot_inf_distrib, hnot_le_iff_codisjoint_right, codisjoint_left_comm, ←
      hnot_le_iff_codisjoint_right]
    exact le_sdiff_sup
  · rw [sdiff_le_iff, ← hnot_hnot_sup_distrib]
    

Proof state:
case refine'_2
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c a b : α
⊢ ￢￢a ≤ ￢￢(b ⊔ a \ b)

Next tactic:
exact hnot_anti (hnot_anti le_sup_sdiff)
instance : HeytingAlgebra αᵒᵈ :=
  { OrderDual.lattice α, OrderDual.boundedOrder α with
    compl := toDual ∘ hnot ∘ ofDual,
    himp := fun a b => toDual (ofDual b \ ofDual a),
    le_himp_iff := fun a b c => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c✝ : α
src✝¹ : Lattice αᵒᵈ := lattice α
src✝ : BoundedOrder αᵒᵈ := boundedOrder α
a b c : αᵒᵈ
⊢ a ≤ b ⇨ c ↔ a ⊓ b ≤ c

Next tactic:
rw [inf_comm]
instance : HeytingAlgebra αᵒᵈ :=
  { OrderDual.lattice α, OrderDual.boundedOrder α with
    compl := toDual ∘ hnot ∘ ofDual,
    himp := fun a b => toDual (ofDual b \ ofDual a),
    le_himp_iff := fun a b c => by
      rw [inf_comm]
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝ : CoheytingAlgebra α
a✝ b✝ c✝ : α
src✝¹ : Lattice αᵒᵈ := lattice α
src✝ : BoundedOrder αᵒᵈ := boundedOrder α
a b c : αᵒᵈ
⊢ a ≤ b ⇨ c ↔ b ⊓ a ≤ c

Next tactic:
exact sdiff_le_iff
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
⊢ a ≤ b ⇨ c ↔ a ⊓ b ≤ c

Next tactic:
change _ ≤ ite _ _ _ ↔ _
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
⊢ (a ≤ if b ≤ c then ⊤ else c) ↔ a ⊓ b ≤ c

Next tactic:
split_ifs with h
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      split_ifs with h
      · 

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
h : b ≤ c
⊢ a ≤ ⊤ ↔ a ⊓ b ≤ c

Next tactic:
exact iff_of_true le_top (inf_le_of_right_le h)
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      split_ifs with h
      · exact iff_of_true le_top (inf_le_of_right_le h)
      · 

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
h : ¬b ≤ c
⊢ a ≤ c ↔ a ⊓ b ≤ c

Next tactic:
rw [inf_le_iff, or_iff_left h]
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      split_ifs with h
      · exact iff_of_true le_top (inf_le_of_right_le h)
      · rw [inf_le_iff, or_iff_left h],
    himp_bot := fun a => if_congr le_bot_iff rfl rfl, sdiff := fun a b => if a ≤ b then ⊥ else a,
    hnot := fun a => if a = ⊤ then ⊥ else ⊤,
    sdiff_le_iff := fun a b c => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
⊢ a \ b ≤ c ↔ a ≤ b ⊔ c

Next tactic:
change ite _ _ _ ≤ _ ↔ _
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      split_ifs with h
      · exact iff_of_true le_top (inf_le_of_right_le h)
      · rw [inf_le_iff, or_iff_left h],
    himp_bot := fun a => if_congr le_bot_iff rfl rfl, sdiff := fun a b => if a ≤ b then ⊥ else a,
    hnot := fun a => if a = ⊤ then ⊥ else ⊤,
    sdiff_le_iff := fun a b c => by
      change ite _ _ _ ≤ _ ↔ _
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
⊢ (if a ≤ b then ⊥ else a) ≤ c ↔ a ≤ b ⊔ c

Next tactic:
split_ifs with h
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      split_ifs with h
      · exact iff_of_true le_top (inf_le_of_right_le h)
      · rw [inf_le_iff, or_iff_left h],
    himp_bot := fun a => if_congr le_bot_iff rfl rfl, sdiff := fun a b => if a ≤ b then ⊥ else a,
    hnot := fun a => if a = ⊤ then ⊥ else ⊤,
    sdiff_le_iff := fun a b c => by
      change ite _ _ _ ≤ _ ↔ _
      split_ifs with h
      · 

Proof state:
case pos
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
h : a ≤ b
⊢ ⊥ ≤ c ↔ a ≤ b ⊔ c

Next tactic:
exact iff_of_true bot_le (le_sup_of_le_left h)
/-- A bounded linear order is a bi-Heyting algebra by setting
* `a ⇨ b = ⊤` if `a ≤ b` and `a ⇨ b = b` otherwise.
* `a \ b = ⊥` if `a ≤ b` and `a \ b = a` otherwise. -/
@[reducible]
def LinearOrder.toBiheytingAlgebra [LinearOrder α] [BoundedOrder α] : BiheytingAlgebra α :=
  { LinearOrder.toLattice, ‹BoundedOrder α› with
    himp := fun a b => if a ≤ b then ⊤ else b,
    compl := fun a => if a = ⊥ then ⊤ else ⊥,
    le_himp_iff := fun a b c => by
      change _ ≤ ite _ _ _ ↔ _
      split_ifs with h
      · exact iff_of_true le_top (inf_le_of_right_le h)
      · rw [inf_le_iff, or_iff_left h],
    himp_bot := fun a => if_congr le_bot_iff rfl rfl, sdiff := fun a b => if a ≤ b then ⊥ else a,
    hnot := fun a => if a = ⊤ then ⊥ else ⊤,
    sdiff_le_iff := fun a b c => by
      change ite _ _ _ ≤ _ ↔ _
      split_ifs with h
      · exact iff_of_true bot_le (le_sup_of_le_left h)
      · 

Proof state:
case neg
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : LinearOrder α
inst✝ : BoundedOrder α
src✝¹ : Lattice α := toLattice
src✝ : BoundedOrder α := inst✝
a b c : α
h : ¬a ≤ b
⊢ a ≤ c ↔ a ≤ b ⊔ c

Next tactic:
rw [le_sup_iff, or_iff_right h]
/-- Pullback a `GeneralizedHeytingAlgebra` along an injection. -/
@[reducible]
protected def Function.Injective.generalizedHeytingAlgebra [Sup α] [Inf α] [Top α]
    [HImp α] [GeneralizedHeytingAlgebra β] (f : α → β) (hf : Injective f)
    (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b)
    (map_top : f ⊤ = ⊤) (map_himp : ∀ a b, f (a ⇨ b) = f a ⇨ f b) : GeneralizedHeytingAlgebra α :=
  { hf.lattice f map_sup map_inf, ‹Top α›, ‹HImp α› with
    le_top := fun a => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : Sup α
inst✝³ : Inf α
inst✝² : Top α
inst✝¹ : HImp α
inst✝ : GeneralizedHeytingAlgebra β
f : α → β
hf : Injective f
map_sup : ∀ (a b : α), f (a ⊔ b) = f a ⊔ f b
map_inf : ∀ (a b : α), f (a ⊓ b) = f a ⊓ f b
map_top : f ⊤ = ⊤
map_himp : ∀ (a b : α), f (a ⇨ b) = f a ⇨ f b
src✝² : Lattice α := Injective.lattice f hf map_sup map_inf
src✝¹ : Top α := inst✝²
src✝ : HImp α := inst✝¹
a : α
⊢ a ≤ ⊤

Next tactic:
change f _ ≤ _
/-- Pullback a `GeneralizedHeytingAlgebra` along an injection. -/
@[reducible]
protected def Function.Injective.generalizedHeytingAlgebra [Sup α] [Inf α] [Top α]
    [HImp α] [GeneralizedHeytingAlgebra β] (f : α → β) (hf : Injective f)
    (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b)
    (map_top : f ⊤ = ⊤) (map_himp : ∀ a b, f (a ⇨ b) = f a ⇨ f b) : GeneralizedHeytingAlgebra α :=
  { hf.lattice f map_sup map_inf, ‹Top α›, ‹HImp α› with
    le_top := fun a => by
      change f _ ≤ _
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : Sup α
inst✝³ : Inf α
inst✝² : Top α
inst✝¹ : HImp α
inst✝ : GeneralizedHeytingAlgebra β
f : α → β
hf : Injective f
map_sup : ∀ (a b : α), f (a ⊔ b) = f a ⊔ f b
map_inf : ∀ (a b : α), f (a ⊓ b) = f a ⊓ f b
map_top : f ⊤ = ⊤
map_himp : ∀ (a b : α), f (a ⇨ b) = f a ⇨ f b
src✝² : Lattice α := Injective.lattice f hf map_sup map_inf
src✝¹ : Top α := inst✝²
src✝ : HImp α := inst✝¹
a : α
⊢ f a ≤ f ⊤

Next tactic:
rw [map_top]
/-- Pullback a `GeneralizedHeytingAlgebra` along an injection. -/
@[reducible]
protected def Function.Injective.generalizedHeytingAlgebra [Sup α] [Inf α] [Top α]
    [HImp α] [GeneralizedHeytingAlgebra β] (f : α → β) (hf : Injective f)
    (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b)
    (map_top : f ⊤ = ⊤) (map_himp : ∀ a b, f (a ⇨ b) = f a ⇨ f b) : GeneralizedHeytingAlgebra α :=
  { hf.lattice f map_sup map_inf, ‹Top α›, ‹HImp α› with
    le_top := fun a => by
      change f _ ≤ _
      rw [map_top]
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : Sup α
inst✝³ : Inf α
inst✝² : Top α
inst✝¹ : HImp α
inst✝ : GeneralizedHeytingAlgebra β
f : α → β
hf : Injective f
map_sup : ∀ (a b : α), f (a ⊔ b) = f a ⊔ f b
map_inf : ∀ (a b : α), f (a ⊓ b) = f a ⊓ f b
map_top : f ⊤ = ⊤
map_himp : ∀ (a b : α), f (a ⇨ b) = f a ⇨ f b
src✝² : Lattice α := Injective.lattice f hf map_sup map_inf
src✝¹ : Top α := inst✝²
src✝ : HImp α := inst✝¹
a : α
⊢ f a ≤ ⊤

Next tactic:
exact le_top
/-- Pullback a `GeneralizedHeytingAlgebra` along an injection. -/
@[reducible]
protected def Function.Injective.generalizedHeytingAlgebra [Sup α] [Inf α] [Top α]
    [HImp α] [GeneralizedHeytingAlgebra β] (f : α → β) (hf : Injective f)
    (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b)
    (map_top : f ⊤ = ⊤) (map_himp : ∀ a b, f (a ⇨ b) = f a ⇨ f b) : GeneralizedHeytingAlgebra α :=
  { hf.lattice f map_sup map_inf, ‹Top α›, ‹HImp α› with
    le_top := fun a => by
      change f _ ≤ _
      rw [map_top]
      exact le_top,
    le_himp_iff := fun a b c => by
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : Sup α
inst✝³ : Inf α
inst✝² : Top α
inst✝¹ : HImp α
inst✝ : GeneralizedHeytingAlgebra β
f : α → β
hf : Injective f
map_sup : ∀ (a b : α), f (a ⊔ b) = f a ⊔ f b
map_inf : ∀ (a b : α), f (a ⊓ b) = f a ⊓ f b
map_top : f ⊤ = ⊤
map_himp : ∀ (a b : α), f (a ⇨ b) = f a ⇨ f b
src✝² : Lattice α := Injective.lattice f hf map_sup map_inf
src✝¹ : Top α := inst✝²
src✝ : HImp α := inst✝¹
a b c : α
⊢ a ≤ b ⇨ c ↔ a ⊓ b ≤ c

Next tactic:
change f _ ≤ _ ↔ f _ ≤ _
/-- Pullback a `GeneralizedHeytingAlgebra` along an injection. -/
@[reducible]
protected def Function.Injective.generalizedHeytingAlgebra [Sup α] [Inf α] [Top α]
    [HImp α] [GeneralizedHeytingAlgebra β] (f : α → β) (hf : Injective f)
    (map_sup : ∀ a b, f (a ⊔ b) = f a ⊔ f b) (map_inf : ∀ a b, f (a ⊓ b) = f a ⊓ f b)
    (map_top : f ⊤ = ⊤) (map_himp : ∀ a b, f (a ⇨ b) = f a ⇨ f b) : GeneralizedHeytingAlgebra α :=
  { hf.lattice f map_sup map_inf, ‹Top α›, ‹HImp α› with
    le_top := fun a => by
      change f _ ≤ _
      rw [map_top]
      exact le_top,
    le_himp_iff := fun a b c => by
      change f _ ≤ _ ↔ f _ ≤ _
      

Proof state:
ι : Type u_1
α : Type u_2
β : Type u_3
inst✝⁴ : Sup α
inst✝³ : Inf α
inst✝² : Top α
inst✝¹ : HImp α
inst✝ : GeneralizedHeytingAlgebra β
f : α → β
hf : Injective f
map_sup : ∀ (a b : α), f (a ⊔ b) = f a ⊔ f b
map_inf : ∀ (a b : α), f (a ⊓ b) = f a ⊓ f b
map_top : f ⊤ = ⊤
map_himp : ∀ (a b : α), f (a ⇨ b) = f a ⇨ f b
src✝² : Lattice α := Injective.lattice f hf map_sup map_inf
src✝¹ : Top α := inst✝²
src✝ : HImp α := inst✝¹
a b c : α
⊢ f a ≤ f (b ⇨ c) ↔ f (a ⊓ b) ≤ f c

Next tactic:
erw [map_himp, map_inf, le_himp_iff]