Skip to content

Commit b7012a6

Browse files
feat: port Order.Heyting.Boundary (#844)
mathlib SHA: 70d50ecfd4900dd6d328da39ab7ebd516abe4025 Porting notes: 1. Needed to fix the proof of `boundary_le_boundary_sup_sup_boundary_inf_left` as simp produced a different term than in mathlib3 2. The `scoped` notation doesn't automatically introduce the notation into the current scope. ~~3. The lint error seems like a bug. Can anyone confirm?~~ Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>
1 parent 5bdee75 commit b7012a6

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ import Mathlib.Order.Compare
206206
import Mathlib.Order.Disjoint
207207
import Mathlib.Order.GameAdd
208208
import Mathlib.Order.Heyting.Basic
209+
import Mathlib.Order.Heyting.Boundary
209210
import Mathlib.Order.Iterate
210211
import Mathlib.Order.Lattice
211212
import Mathlib.Order.Max
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
/-
2+
Copyright (c) 2022 Yaël Dillies. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Yaël Dillies
5+
-/
6+
import Mathlib.Order.BooleanAlgebra
7+
import Mathlib.Tactic.ScopedNS
8+
9+
/-!
10+
# Co-Heyting boundary
11+
12+
The boundary of an element of a co-Heyting algebra is the intersection of its Heyting negation with
13+
itself. The boundary in the co-Heyting algebra of closed sets coincides with the topological
14+
boundary.
15+
16+
## Main declarations
17+
18+
* `Coheyting.boundary`: Co-Heyting boundary. `Coheyting.boundary a = a ⊓ ¬a`
19+
20+
## Notation
21+
22+
`∂ a` is notation for `Coheyting.boundary a` in locale `Heyting`.
23+
-/
24+
25+
26+
variable {α : Type _}
27+
28+
namespace Coheyting
29+
30+
variable [CoheytingAlgebra α] {a b : α}
31+
32+
/-- The boundary of an element of a co-Heyting algebra is the intersection of its Heyting negation
33+
with itself. Note that this is always `⊥` for a boolean algebra. -/
34+
def boundary (a : α) : α :=
35+
a ⊓ ¬a
36+
#align coheyting.boundary Coheyting.boundary
37+
38+
/-- The boundary of an element of a co-Heyting algebra. -/
39+
scoped[Heyting] prefix:120 "∂ " => Coheyting.boundary
40+
-- Porting note: Should the notation be automatically included in the current scope?
41+
open Heyting
42+
43+
-- Porting note: Should hnot be named hNot?
44+
theorem inf_hnot_self (a : α) : a ⊓ ¬a = ∂ a :=
45+
rfl
46+
#align coheyting.inf_hnot_self Coheyting.inf_hnot_self
47+
48+
theorem boundary_le : ∂ a ≤ a :=
49+
inf_le_left
50+
#align coheyting.boundary_le Coheyting.boundary_le
51+
52+
theorem boundary_le_hnot : ∂ a ≤ ¬a :=
53+
inf_le_right
54+
#align coheyting.boundary_le_hnot Coheyting.boundary_le_hnot
55+
56+
@[simp]
57+
theorem boundary_bot : ∂ (⊥ : α) = ⊥ :=
58+
bot_inf_eq
59+
#align coheyting.boundary_bot Coheyting.boundary_bot
60+
61+
@[simp]
62+
theorem boundary_top : ∂ (⊤ : α) = ⊥ := by rw [boundary, hnot_top, inf_bot_eq]
63+
#align coheyting.boundary_top Coheyting.boundary_top
64+
65+
theorem boundary_hnot_le (a : α) : ∂ (¬a) ≤ ∂ a :=
66+
inf_comm.trans_le <| inf_le_inf_right _ hnot_hnot_le
67+
#align coheyting.boundary_hnot_le Coheyting.boundary_hnot_le
68+
69+
@[simp]
70+
theorem boundary_hnot_hnot (a : α) : ∂ (¬¬a) = ∂ (¬a) := by
71+
simp_rw [boundary, hnot_hnot_hnot, inf_comm]
72+
#align coheyting.boundary_hnot_hnot Coheyting.boundary_hnot_hnot
73+
74+
@[simp]
75+
theorem hnot_boundary (a : α) : ¬∂ a = ⊤ := by rw [boundary, hnot_inf_distrib, sup_hnot_self]
76+
#align coheyting.hnot_boundary Coheyting.hnot_boundary
77+
78+
/-- **Leibniz rule** for the co-Heyting boundary. -/
79+
theorem boundary_inf (a b : α) : ∂ (a ⊓ b) = ∂ a ⊓ b ⊔ a ⊓ ∂ b := by
80+
unfold boundary
81+
rw [hnot_inf_distrib, inf_sup_left, inf_right_comm, ← inf_assoc]
82+
#align coheyting.boundary_inf Coheyting.boundary_inf
83+
84+
theorem boundary_inf_le : ∂ (a ⊓ b) ≤ ∂ a ⊔ ∂ b :=
85+
(boundary_inf _ _).trans_le <| sup_le_sup inf_le_left inf_le_right
86+
#align coheyting.boundary_inf_le Coheyting.boundary_inf_le
87+
88+
theorem boundary_sup_le : ∂ (a ⊔ b) ≤ ∂ a ⊔ ∂ b := by
89+
rw [boundary, inf_sup_right]
90+
exact
91+
sup_le_sup (inf_le_inf_left _ <| hnot_anti le_sup_left)
92+
(inf_le_inf_left _ <| hnot_anti le_sup_right)
93+
#align coheyting.boundary_sup_le Coheyting.boundary_sup_le
94+
95+
/- The intuitionistic version of `Coheyting.boundary_le_boundary_sup_sup_boundary_inf_left`. Either
96+
proof can be obtained from the other using the equivalence of Heyting algebras and intuitionistic
97+
logic and duality between Heyting and co-Heyting algebras. It is crucial that the following proof be
98+
intuitionistic. -/
99+
example (a b : Prop) : (a ∧ b ∨ ¬(a ∧ b)) ∧ ((a ∨ b) ∨ ¬(a ∨ b)) → a ∨ ¬a := by
100+
rintro ⟨⟨ha, _⟩ | hnab, (ha | hb) | hnab⟩ <;> try exact Or.inl ha
101+
· exact Or.inr fun ha => hnab ⟨ha, hb⟩
102+
· exact Or.inr fun ha => hnab <| Or.inl ha
103+
104+
theorem boundary_le_boundary_sup_sup_boundary_inf_left : ∂ a ≤ ∂ (a ⊔ b) ⊔ ∂ (a ⊓ b) := by
105+
-- Porting note: the following simp generates the same term as mathlib3 if you remove
106+
-- sup_inf_right from both. With sup_inf_right included, mathlib4 and mathlib3 generate
107+
-- different terms
108+
simp only [boundary, sup_inf_left, sup_inf_right, sup_right_idem, le_inf_iff, sup_assoc,
109+
@sup_comm _ _ _ a]
110+
refine ⟨⟨⟨?_, ?_⟩, ⟨?_, ?_⟩⟩, ?_, ?_⟩ <;> try { exact le_sup_of_le_left inf_le_left } <;>
111+
refine inf_le_of_right_le ?_
112+
· rw [hnot_le_iff_codisjoint_right, codisjoint_left_comm]
113+
exact codisjoint_hnot_left
114+
· refine le_sup_of_le_right ?_
115+
rw [hnot_le_iff_codisjoint_right]
116+
exact codisjoint_hnot_right.mono_right (hnot_anti inf_le_left)
117+
#align
118+
coheyting.boundary_le_boundary_sup_sup_boundary_inf_left
119+
Coheyting.boundary_le_boundary_sup_sup_boundary_inf_left
120+
121+
theorem boundary_le_boundary_sup_sup_boundary_inf_right : ∂ b ≤ ∂ (a ⊔ b) ⊔ ∂ (a ⊓ b) := by
122+
rw [@sup_comm _ _ a, inf_comm]
123+
exact boundary_le_boundary_sup_sup_boundary_inf_left
124+
#align
125+
coheyting.boundary_le_boundary_sup_sup_boundary_inf_right
126+
Coheyting.boundary_le_boundary_sup_sup_boundary_inf_right
127+
128+
theorem boundary_sup_sup_boundary_inf (a b : α) : ∂ (a ⊔ b) ⊔ ∂ (a ⊓ b) = ∂ a ⊔ ∂ b :=
129+
le_antisymm (sup_le boundary_sup_le boundary_inf_le) <|
130+
sup_le boundary_le_boundary_sup_sup_boundary_inf_left
131+
boundary_le_boundary_sup_sup_boundary_inf_right
132+
#align coheyting.boundary_sup_sup_boundary_inf Coheyting.boundary_sup_sup_boundary_inf
133+
134+
@[simp]
135+
theorem boundary_idem (a : α) : ∂ ∂ a = ∂ a := by rw [boundary, hnot_boundary, inf_top_eq]
136+
#align coheyting.boundary_idem Coheyting.boundary_idem
137+
138+
theorem hnot_hnot_sup_boundary (a : α) : ¬¬a ⊔ ∂ a = a := by
139+
rw [boundary, sup_inf_left, hnot_sup_self, inf_top_eq, sup_eq_right]
140+
exact hnot_hnot_le
141+
#align coheyting.hnot_hnot_sup_boundary Coheyting.hnot_hnot_sup_boundary
142+
143+
theorem hnot_eq_top_iff_exists_boundary : ¬a = ⊤ ↔ ∃ b, ∂ b = a :=
144+
fun h => ⟨a, by rw [boundary, h, inf_top_eq]⟩, by
145+
rintro ⟨b, rfl⟩
146+
exact hnot_boundary _⟩
147+
#align coheyting.hnot_eq_top_iff_exists_boundary Coheyting.hnot_eq_top_iff_exists_boundary
148+
149+
end Coheyting
150+
151+
open Heyting
152+
153+
section BooleanAlgebra
154+
155+
variable [BooleanAlgebra α]
156+
157+
@[simp]
158+
theorem Coheyting.boundary_eq_bot (a : α) : ∂ a = ⊥ :=
159+
inf_compl_eq_bot
160+
#align coheyting.boundary_eq_bot Coheyting.boundary_eq_bot
161+
162+
end BooleanAlgebra

0 commit comments

Comments
 (0)