Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit f7905f0

Browse files
committed
feat(order/concept): Concept lattices (#12286)
Define `concept`, the type of concepts of a relation, and prove it forms a complete lattice.
1 parent b226b4b commit f7905f0

File tree

2 files changed

+280
-0
lines changed

2 files changed

+280
-0
lines changed

docs/references.bib

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,21 @@ @Book{ conway2001
392392
mrnumber = {1803095}
393393
}
394394

395+
@Book{ davey_priestley,
396+
author = {Davey, B. A. and Priestley, H. A.},
397+
title = {Introduction to lattices and order},
398+
edition = {Second},
399+
publisher = {Cambridge University Press, New York},
400+
year = {2002},
401+
pages = {xii+298},
402+
isbn = {0-521-78451-4},
403+
MRCLASS = {06-01 (68Q55)},
404+
mrclass = {1902334},
405+
mrreviewer = {T. S. Blyth},
406+
doi = {10.1017/CBO9780511809088},
407+
url = {https://doi.org/10.1017/CBO9780511809088},
408+
}
409+
395410
@InProceedings{ deligne_formulaire,
396411
author = {Deligne, P.},
397412
title = {Courbes elliptiques: formulaire d'apr\`es {J}. {T}ate},

src/order/concept.lean

Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
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 data.set.lattice
7+
8+
/-!
9+
# Formal concept analysis
10+
11+
This file defines concept lattices. A concept of a relation `r : α → β → Prop` is a pair of sets
12+
`s : set α` and `t : set β` such that `s` is the set of all `a : α` that are related to all elements
13+
of `t`, and `t` is the set of all `b : β` that are related to all elements of `s`.
14+
15+
Ordering the concepts of a relation `r` by inclusion on the first component gives rise to a
16+
*concept lattice*. Every concept lattice is complete and in fact every complete lattice arises as
17+
the concept lattice of its `≤`.
18+
19+
## Implementation notes
20+
21+
Concept lattices are usually defined from a *context*, that is the triple `(α, β, r)`, but the type
22+
of `r` determines `α` and `β` already, so we do not define contexts as a separate object.
23+
24+
## TODO
25+
26+
Prove the fundamental theorem of concept lattices.
27+
28+
## References
29+
30+
* [Davey, Priestley *Introduction to Lattices and Order*][davey_priestley]
31+
32+
## Tags
33+
34+
concept, formal concept analysis, intent, extend, attribute
35+
-/
36+
37+
open function order_dual set
38+
39+
variables {ι : Sort*} {α β γ : Type*} {κ : ι → Sort*} (r : α → β → Prop) {s s₁ s₂ : set α}
40+
{t t₁ t₂ : set β}
41+
42+
/-! ### Intent and extent -/
43+
44+
/-- The intent closure of `s : set α` along a relation `r : α → β → Prop` is the set of all elements
45+
which `r` relates to all elements of `s`. -/
46+
def intent_closure (s : set α) : set β := {b | ∀ ⦃a⦄, a ∈ s → r a b}
47+
48+
/-- The extent closure of `t : set β` along a relation `r : α → β → Prop` is the set of all elements
49+
which `r` relates to all elements of `t`. -/
50+
def extent_closure (t : set β) : set α := {a | ∀ ⦃b⦄, b ∈ t → r a b}
51+
52+
variables {r}
53+
54+
lemma subset_intent_closure_iff_subset_extent_closure :
55+
t ⊆ intent_closure r s ↔ s ⊆ extent_closure r t :=
56+
⟨λ h a ha b hb, h hb ha, λ h b hb a ha, h ha hb⟩
57+
58+
variables (r)
59+
60+
lemma gc_intent_closure_extent_closure :
61+
galois_connection (to_dual ∘ intent_closure r) (extent_closure r ∘ of_dual) :=
62+
λ s t, subset_intent_closure_iff_subset_extent_closure
63+
64+
lemma intent_closure_swap (t : set β) : intent_closure (swap r) t = extent_closure r t := rfl
65+
lemma extent_closure_swap (s : set α) : extent_closure (swap r) s = intent_closure r s := rfl
66+
67+
@[simp] lemma intent_closure_empty : intent_closure r ∅ = univ :=
68+
eq_univ_of_forall $ λ _ _, false.elim
69+
70+
@[simp] lemma extent_closure_empty : extent_closure r ∅ = univ := intent_closure_empty _
71+
72+
@[simp] lemma intent_closure_union (s₁ s₂ : set α) :
73+
intent_closure r (s₁ ∪ s₂) = intent_closure r s₁ ∩ intent_closure r s₂ :=
74+
set.ext $ λ _, ball_or_left_distrib
75+
76+
@[simp] lemma extent_closure_union (t₁ t₂ : set β) :
77+
extent_closure r (t₁ ∪ t₂) = extent_closure r t₁ ∩ extent_closure r t₂ :=
78+
intent_closure_union _ _ _
79+
80+
@[simp] lemma intent_closure_Union (f : ι → set α) :
81+
intent_closure r (⋃ i, f i) = ⋂ i, intent_closure r (f i) :=
82+
(gc_intent_closure_extent_closure r).l_supr
83+
84+
@[simp] lemma extent_closure_Union (f : ι → set β) :
85+
extent_closure r (⋃ i, f i) = ⋂ i, extent_closure r (f i) :=
86+
intent_closure_Union _ _
87+
88+
@[simp] lemma intent_closure_Union₂ (f : Π i, κ i → set α) :
89+
intent_closure r (⋃ i j, f i j) = ⋂ i j, intent_closure r (f i j) :=
90+
(gc_intent_closure_extent_closure r).l_supr₂
91+
92+
@[simp] lemma extent_closure_Union₂ (f : Π i, κ i → set β) :
93+
extent_closure r (⋃ i j, f i j) = ⋂ i j, extent_closure r (f i j) :=
94+
intent_closure_Union₂ _ _
95+
96+
lemma subset_extent_closure_intent_closure (s : set α) :
97+
s ⊆ extent_closure r (intent_closure r s) :=
98+
(gc_intent_closure_extent_closure r).le_u_l _
99+
100+
lemma subset_intent_closure_extent_closure (t : set β) :
101+
t ⊆ intent_closure r (extent_closure r t) :=
102+
subset_extent_closure_intent_closure _ t
103+
104+
@[simp] lemma intent_closure_extent_closure_intent_closure (s : set α) :
105+
intent_closure r (extent_closure r $ intent_closure r s) = intent_closure r s :=
106+
(gc_intent_closure_extent_closure r).l_u_l_eq_l _
107+
108+
@[simp] lemma extent_closure_intent_closure_extent_closure (t : set β) :
109+
extent_closure r (intent_closure r $ extent_closure r t) = extent_closure r t :=
110+
intent_closure_extent_closure_intent_closure _ t
111+
112+
lemma intent_closure_anti : antitone (intent_closure r) :=
113+
(gc_intent_closure_extent_closure r).monotone_l
114+
115+
lemma extent_closure_anti : antitone (extent_closure r) := intent_closure_anti _
116+
117+
/-! ### Concepts -/
118+
119+
variables (α β)
120+
121+
/-- The formal concepts of a relation. A concept of `r : α → β → Prop` is a pair of sets `s`, `t`
122+
such that `s` is the set of all elements that are `r`-related to all of `t` and `t` is the set of
123+
all elements that are `r`-related to all of `s`. -/
124+
structure concept extends set α × set β :=
125+
(closure_fst : intent_closure r fst = snd)
126+
(closure_snd : extent_closure r snd = fst)
127+
128+
namespace concept
129+
variables {r α β} {c d : concept α β r}
130+
131+
attribute [simp] closure_fst closure_snd
132+
133+
@[ext] lemma ext (h : c.fst = d.fst) : c = d :=
134+
begin
135+
obtain ⟨⟨s₁, t₁⟩, h₁, _⟩ := c,
136+
obtain ⟨⟨s₂, t₂⟩, h₂, _⟩ := d,
137+
dsimp at h₁ h₂ h,
138+
subst h,
139+
subst h₁,
140+
subst h₂,
141+
end
142+
143+
lemma ext' (h : c.snd = d.snd) : c = d :=
144+
begin
145+
obtain ⟨⟨s₁, t₁⟩, _, h₁⟩ := c,
146+
obtain ⟨⟨s₂, t₂⟩, _, h₂⟩ := d,
147+
dsimp at h₁ h₂ h,
148+
subst h,
149+
subst h₁,
150+
subst h₂,
151+
end
152+
153+
lemma fst_injective : injective (λ c : concept α β r, c.fst) := λ c d, ext
154+
lemma snd_injective : injective (λ c : concept α β r, c.snd) := λ c d, ext'
155+
156+
instance : has_sup (concept α β r) :=
157+
⟨λ c d, { fst := extent_closure r (c.snd ∩ d.snd),
158+
snd := c.snd ∩ d.snd,
159+
closure_fst := by rw [←c.closure_fst, ←d.closure_fst, ←intent_closure_union,
160+
intent_closure_extent_closure_intent_closure],
161+
closure_snd := rfl }⟩
162+
163+
instance : has_inf (concept α β r) :=
164+
⟨λ c d, { fst := c.fst ∩ d.fst,
165+
snd := intent_closure r (c.fst ∩ d.fst),
166+
closure_fst := rfl,
167+
closure_snd := by rw [←c.closure_snd, ←d.closure_snd, ←extent_closure_union,
168+
extent_closure_intent_closure_extent_closure] }⟩
169+
170+
instance : semilattice_inf (concept α β r) := fst_injective.semilattice_inf _ $ λ _ _, rfl
171+
172+
@[simp] lemma fst_subset_fst_iff : c.fst ⊆ d.fst ↔ c ≤ d := iff.rfl
173+
@[simp] lemma fst_ssubset_fst_iff : c.fst ⊂ d.fst ↔ c < d := iff.rfl
174+
175+
@[simp] lemma snd_subset_snd_iff : c.snd ⊆ d.snd ↔ d ≤ c :=
176+
begin
177+
refine ⟨λ h, _, λ h, _⟩,
178+
{ rw [←fst_subset_fst_iff, ←c.closure_snd, ←d.closure_snd],
179+
exact extent_closure_anti _ h },
180+
{ rw [←c.closure_fst, ←d.closure_fst],
181+
exact intent_closure_anti _ h }
182+
end
183+
184+
@[simp] lemma snd_ssubset_snd_iff : c.snd ⊂ d.snd ↔ d < c :=
185+
by rw [ssubset_iff_subset_not_subset, lt_iff_le_not_le, snd_subset_snd_iff, snd_subset_snd_iff]
186+
187+
lemma strict_mono_fst : strict_mono (prod.fst ∘ to_prod : concept α β r → set α) :=
188+
λ c d, fst_ssubset_fst_iff.2
189+
190+
lemma strict_anti_snd : strict_anti (prod.snd ∘ to_prod : concept α β r → set β) :=
191+
λ c d, snd_ssubset_snd_iff.2
192+
193+
instance : lattice (concept α β r) :=
194+
{ sup := (⊔),
195+
le_sup_left := λ c d, snd_subset_snd_iff.1 $ inter_subset_left _ _,
196+
le_sup_right := λ c d, snd_subset_snd_iff.1 $ inter_subset_right _ _,
197+
sup_le := λ c d e, by { simp_rw ←snd_subset_snd_iff, exact subset_inter },
198+
..concept.semilattice_inf }
199+
200+
instance : bounded_order (concept α β r) :=
201+
{ top := ⟨⟨univ, intent_closure r univ⟩, rfl, eq_univ_of_forall $ λ a b hb, hb trivial⟩,
202+
le_top := λ _, subset_univ _,
203+
bot := ⟨⟨extent_closure r univ, univ⟩, eq_univ_of_forall $ λ b a ha, ha trivial, rfl⟩,
204+
bot_le := λ _, snd_subset_snd_iff.1 $ subset_univ _ }
205+
206+
instance : has_Sup (concept α β r) :=
207+
⟨λ S, { fst := extent_closure r (⋂ c ∈ S, (c : concept _ _ _).snd),
208+
snd := ⋂ c ∈ S, (c : concept _ _ _).snd,
209+
closure_fst := by simp_rw [←closure_fst, ←intent_closure_Union₂,
210+
intent_closure_extent_closure_intent_closure],
211+
closure_snd := rfl }⟩
212+
213+
instance : has_Inf (concept α β r) :=
214+
⟨λ S, { fst := ⋂ c ∈ S, (c : concept _ _ _).fst,
215+
snd := intent_closure r (⋂ c ∈ S, (c : concept _ _ _).fst),
216+
closure_fst := rfl,
217+
closure_snd := by simp_rw [←closure_snd, ←extent_closure_Union₂,
218+
extent_closure_intent_closure_extent_closure] }⟩
219+
220+
instance : complete_lattice (concept α β r) :=
221+
{ Sup := Sup,
222+
le_Sup := λ S c hc, snd_subset_snd_iff.1 $ bInter_subset_of_mem hc,
223+
Sup_le := λ S c hc, snd_subset_snd_iff.1 $ subset_Inter₂ $ λ d hd, snd_subset_snd_iff.2 $ hc d hd,
224+
Inf := Inf,
225+
Inf_le := λ S c, bInter_subset_of_mem,
226+
le_Inf := λ S c, subset_Inter₂,
227+
..concept.lattice, ..concept.bounded_order }
228+
229+
@[simp] lemma top_fst : (⊤ : concept α β r).fst = univ := rfl
230+
@[simp] lemma top_snd : (⊤ : concept α β r).snd = intent_closure r univ := rfl
231+
@[simp] lemma bot_fst : (⊥ : concept α β r).fst = extent_closure r univ := rfl
232+
@[simp] lemma bot_snd : (⊥ : concept α β r).snd = univ := rfl
233+
@[simp] lemma sup_fst (c d : concept α β r) : (c ⊔ d).fst = extent_closure r (c.snd ∩ d.snd) := rfl
234+
@[simp] lemma sup_snd (c d : concept α β r) : (c ⊔ d).snd = c.snd ∩ d.snd := rfl
235+
@[simp] lemma inf_fst (c d : concept α β r) : (c ⊓ d).fst = c.fst ∩ d.fst := rfl
236+
@[simp] lemma inf_snd (c d : concept α β r) : (c ⊓ d).snd = intent_closure r (c.fst ∩ d.fst) := rfl
237+
@[simp] lemma Sup_fst (S : set (concept α β r)) :
238+
(Sup S).fst = extent_closure r ⋂ c ∈ S, (c : concept _ _ _).snd := rfl
239+
@[simp] lemma Sup_snd (S : set (concept α β r)) : (Sup S).snd = ⋂ c ∈ S, (c : concept _ _ _).snd :=
240+
rfl
241+
@[simp] lemma Inf_fst (S : set (concept α β r)) : (Inf S).fst = ⋂ c ∈ S, (c : concept _ _ _).fst :=
242+
rfl
243+
@[simp] lemma Inf_snd (S : set (concept α β r)) :
244+
(Inf S).snd = intent_closure r ⋂ c ∈ S, (c : concept _ _ _).fst := rfl
245+
246+
instance : inhabited (concept α β r) := ⟨⊥⟩
247+
248+
/-- Swap the sets of a concept to make it a concept of the dual context. -/
249+
@[simps] def swap (c : concept α β r) : concept β α (swap r) :=
250+
⟨c.to_prod.swap, c.closure_snd, c.closure_fst⟩
251+
252+
@[simp] lemma swap_swap (c : concept α β r) : c.swap.swap = c := ext rfl
253+
254+
@[simp] lemma swap_le_swap_iff : c.swap ≤ d.swap ↔ d ≤ c := snd_subset_snd_iff
255+
@[simp] lemma swap_lt_swap_iff : c.swap < d.swap ↔ d < c := snd_ssubset_snd_iff
256+
257+
/-- The dual of a concept lattice is isomorphic to the concept lattice of the dual context. -/
258+
@[simps] def swap_equiv : order_dual (concept α β r) ≃o concept β α (function.swap r) :=
259+
{ to_fun := swap ∘ of_dual,
260+
inv_fun := to_dual ∘ swap,
261+
left_inv := swap_swap,
262+
right_inv := swap_swap,
263+
map_rel_iff' := λ c d, swap_le_swap_iff }
264+
265+
end concept

0 commit comments

Comments
 (0)