This repository was archived by the owner on Jul 2, 2026. It is now read-only.
forked from gotrevor/Foundation
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCluster.lean
More file actions
376 lines (297 loc) · 11 KB
/
Copy pathCluster.lean
File metadata and controls
376 lines (297 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
module
public import Foundation.Modal.Kripke.Root
public import Mathlib.Data.Finite.Card
@[expose] public section
def IsEquiv.equivalence [IsEquiv α r] : Equivalence r where
refl := Std.Refl.refl
symm {_ _} := by apply Std.Symm.symm
trans {_ _ _} := by apply IsTrans.trans
namespace LO.Modal
namespace Kripke
def clusterEquiv (F : Kripke.Frame) (x y : F.World) := x = y ∨ (x ≺ y ∧ y ≺ x)
section
variable {F : Kripke.Frame} {x y z : F.World}
instance : Std.Refl (clusterEquiv F) := by tauto;
instance : Std.Symm (clusterEquiv F) := ⟨by
rintro x y (rfl | ⟨Rxy, Ryx⟩);
. apply refl;
. right; exact ⟨Ryx, Rxy⟩;
⟩
instance [F.IsTransitive] : IsTrans _ (clusterEquiv F) := ⟨by
rintro x y z (rfl | ⟨Rxy, Ryx⟩) (rfl | ⟨Ryz, Rzy⟩);
. apply refl;
. right; exact ⟨Ryz, Rzy⟩;
. right; exact ⟨Rxy, Ryx⟩;
. right;
constructor;
. exact _root_.trans Rxy Ryz;
. exact _root_.trans Rzy Ryx;
⟩
instance [F.IsTransitive] : IsEquiv _ (clusterEquiv F) where
end
abbrev Cluster (F : Frame) [F.IsTransitive] := Quotient (⟨clusterEquiv F, IsEquiv.equivalence⟩)
namespace Cluster
variable {F : Frame} [F.IsTransitive] {x y : F.World} {C : Cluster F}
instance [Finite F] : Finite (Cluster F) := Finite.of_surjective (λ x => ⟦x⟧) $ by
intro C;
obtain ⟨x, rfl⟩ := Quotient.exists_rep C;
use x;
@[simp]
lemma iff_eq_cluster : (⟦x⟧ : Cluster F) = ⟦y⟧ ↔ (x = y ∨ (x ≺ y ∧ y ≺ x)) := by
simp only [Quotient.eq, clusterEquiv];
protected abbrev rel : Rel (Cluster F) (Cluster F) := Quotient.lift₂ (λ x y => x ≺ y) $ by
rintro x₁ y₁ x₂ y₂ (rfl | ⟨Rx₁x₂, Rx₂x₁⟩) (rfl | ⟨Ry₁y₂, Ry₂y₁⟩);
. rfl;
. apply eq_iff_iff.mpr;
constructor;
. intro Rx₁y₁;
exact _root_.trans Rx₁y₁ Ry₁y₂;
. intro Rx₁y₂;
exact _root_.trans Rx₁y₂ Ry₂y₁;
. apply eq_iff_iff.mpr;
constructor;
. intro Rx₁y₁;
exact _root_.trans Rx₂x₁ Rx₁y₁;
. intro Rx₂y₁;
exact _root_.trans Rx₁x₂ Rx₂y₁;
. apply eq_iff_iff.mpr;
constructor;
. intro Rx₁y₁;
exact _root_.trans Rx₂x₁ $ _root_.trans Rx₁y₁ Ry₁y₂;
. intro Rx₂y₂;
exact _root_.trans (_root_.trans Rx₁x₂ Rx₂y₂) Ry₂y₁;
local infix:50 " ≼ " => Cluster.rel
instance : IsTrans (Cluster F) (· ≼ ·) := ⟨by
rintro X Y Z RXY RYZ;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
obtain ⟨y, rfl⟩ := Quotient.exists_rep Y;
obtain ⟨z, rfl⟩ := Quotient.exists_rep Z;
simp only [Cluster.rel, Quotient.lift_mk] at RXY RYZ;
apply _root_.trans RXY RYZ;
⟩
instance : IsAntisymm (Cluster F) (· ≼ ·) := ⟨by
rintro X Y RXY RYX;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
obtain ⟨y, rfl⟩ := Quotient.exists_rep Y;
simp only [Cluster.rel, Quotient.lift_mk] at RXY RYX;
apply iff_eq_cluster.mpr;
right;
tauto;
⟩
instance [F.IsReflexive] : IsRefl (Cluster F) (· ≼ ·) := ⟨by
rintro X;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
simp only [Cluster.rel, Quotient.lift_mk];
apply Std.Refl.refl;
⟩
instance [Std.Total F] : IsTotal (Cluster F) (· ≼ ·) := ⟨by
rintro X Y;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
obtain ⟨y, rfl⟩ := Quotient.exists_rep Y;
rcases total_of (· ≺ ·) x y with Rxy | Rxy <;> tauto;
⟩
protected abbrev strict_rel : Rel (Cluster F) (Cluster F) := λ X Y => X ≼ Y ∧ X ≠ Y
local infix:50 " ≺ " => Cluster.strict_rel
instance : IsTrans (Cluster F) (· ≺ ·) := ⟨by
rintro X Y Z ⟨RXY, _⟩ ⟨RYZ, _⟩;
constructor;
. exact _root_.trans RXY RYZ;
. by_contra hC;
subst hC;
have : X = Y := antisymm RXY RYZ;
contradiction;
⟩
instance : IsIrrefl (Cluster F) (· ≺ ·) := ⟨by
rintro X;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
simp [Cluster.strict_rel, Quotient.lift_mk];
⟩
instance : IsAsymm (Cluster F) (· ≺ ·) := ⟨by
intro X Y ⟨RXY, _⟩;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
obtain ⟨y, rfl⟩ := Quotient.exists_rep Y;
simp_all [Cluster.strict_rel, Quotient.lift_mk, clusterEquiv];
⟩
instance : IsStrictOrder (Cluster F) (· ≺ ·) where
instance [IsTrichotomous _ F] : IsTrichotomous (Cluster F) (· ≺ ·) := ⟨by
rintro X Y;
obtain ⟨x, rfl⟩ := Quotient.exists_rep X;
obtain ⟨y, rfl⟩ := Quotient.exists_rep Y;
rcases (trichotomous (r := (· ≺ ·)) x y) with Rxy | rfl | Rxy <;> tauto;
⟩
instance [IsTrichotomous _ F] : IsStrictTotalOrder (Cluster F) (· ≺ ·) where
protected abbrev mem : Cluster F → F.World → Prop := λ C x => C = ⟦x⟧
instance : Membership (F.World) (Cluster F) := ⟨Cluster.mem⟩
@[simp]
lemma mem_iff : x ∈ C ↔ C = ⟦x⟧ := by
obtain ⟨c, rfl⟩ := Quotient.exists_rep C;
simp only [Quotient.eq, clusterEquiv, Cluster.mem, Membership.mem];
@[simp]
lemma mem_iff₂ : x ∈ (⟦y⟧ : Cluster F) ↔ y = x ∨ y ≺ x ∧ x ≺ y := by
constructor;
. intro h;
replace h := mem_iff.mp h;
simpa using h;
. intro h;
apply mem_iff.mpr;
simpa using h;
lemma mem_same_cluster (hx : x ∈ C) (hy : y ∈ C): y = x ∨ (y ≺ x ∧ x ≺ y) := by
obtain ⟨c, rfl⟩ := Quotient.exists_rep C;
replace hx := mem_iff₂.mp hx;
replace hy := mem_iff₂.mp hy;
rcases hx with rfl | ⟨Rcx, Rxc⟩ <;>
rcases hy with rfl | ⟨Rcy, Ryc⟩;
. tauto;
. tauto;
. tauto;
. right;
constructor;
. exact _root_.trans Ryc Rcx;
. exact _root_.trans Rxc Rcy;
lemma refl_in_cluster_of_more_than_one (h : ∃ x y, x ≠ y ∧ x ∈ C ∧ y ∈ C) : ∀ z, z ∈ C → z ≺ z := by
obtain ⟨c, rfl⟩ := Quotient.exists_rep C;
obtain ⟨x, y, hxy, hx, hy⟩ := h;
intro z hz;
simp only [mem_iff₂] at hx hy hz;
rcases hx with rfl | ⟨Rcx, Rxc⟩ <;>
rcases hy with rfl | ⟨Rcy, Ryc⟩ <;>
rcases hz with rfl | ⟨Rcz, Rzc⟩;
. contradiction;
. exact _root_.trans Rzc Rcz;
. exact _root_.trans Rcy Ryc;
. exact _root_.trans Rzc Rcz;
. exact _root_.trans Rcx Rxc;
. exact _root_.trans Rzc Rcz;
. exact _root_.trans Rcy Ryc;
. exact _root_.trans Rzc Rcz;
lemma refl_rel_of_more_than_one (h : ∃ x y, x ≠ y ∧ x ∈ C ∧ y ∈ C) : C ≼ C := by
obtain ⟨c, rfl⟩ := Quotient.exists_rep C;
apply refl_in_cluster_of_more_than_one h;
tauto;
def degenerate (C : Cluster F) := ¬C ≼ C
lemma not_more_than_two_of_degenerate : C.degenerate → ¬∃ x y, x ≠ y ∧ x ∈ C ∧ y ∈ C := by
apply not_imp_not.mpr $ refl_rel_of_more_than_one;
lemma degenerate_iff_exists_unique_irrefl_point : C.degenerate ↔ (∃! x, x ∈ C ∧ ¬x ≺ x) := by
obtain ⟨c, rfl⟩ := Quotient.exists_rep C;
constructor;
. intro h;
use c;
constructor;
. simpa;
. rintro x ⟨hx₁, hx₂⟩;
by_contra nexc;
have := not_more_than_two_of_degenerate h;
push Not at this;
replace this := this c x (by tauto) (by tauto);
contradiction;
. rintro ⟨x, ⟨hx₁, hx₂⟩, hx₃⟩;
rcases (mem_iff₂.mp hx₁) with rfl | ⟨Rxy, Ryx⟩;
. apply hx₂;
. exfalso;
exact hx₂ $ _root_.trans Ryx Rxy;
def simple (C : Cluster F) := ∃! x, x ∈ C ∧ x ≺ x
lemma not_degenerate_of_simple (h : C.simple) : ¬C.degenerate := by
apply degenerate_iff_exists_unique_irrefl_point.not.mpr;
by_contra hC;
obtain ⟨x, hx⟩ := h;
obtain ⟨y, hy⟩ := hC;
obtain ⟨⟨hx₁, hx₂⟩, hx₃⟩ := hx;
obtain ⟨⟨hy₁, hy₂⟩, hy₃⟩ := hy;
by_cases exy : x = y;
. subst exy;
contradiction;
. exact hy₂ $ refl_in_cluster_of_more_than_one (by use x, y) y hy₁;
lemma refl_in_simple (h : C.simple) (hx : x ∈ C) : x ≺ x := by
obtain ⟨y, ⟨hy, _⟩, _⟩ := h;
rcases mem_same_cluster hx hy with rfl | ⟨Rxy, Ryx⟩;
. assumption;
. exact _root_.trans Ryx Rxy;
def proper (C : Cluster F) := ∃ x y, x ≠ y ∧ x ∈ C ∧ y ∈ C
lemma not_degenerate_of_proper (h : C.proper) : ¬C.degenerate := by
by_contra hC;
exact not_more_than_two_of_degenerate hC h;
lemma refl_in_proper (h : C.proper) (hx : x ∈ C) : x ≺ x := by
obtain ⟨y, z, hxy, hy, hz⟩ := h;
rcases mem_same_cluster hx hy with rfl | ⟨Rxy, Ryx⟩;
. rcases mem_same_cluster hy hz with rfl | ⟨Ryz, Rzy⟩;
. contradiction;
. exact _root_.trans Rzy Ryz;
. exact _root_.trans Ryx Rxy;
lemma either_simple_or_proper_of_non_degenerate (h : ¬C.degenerate) : C.simple ∨ C.proper := by
obtain ⟨x, rfl⟩ := Quotient.exists_rep C;
by_cases ex : ∃ y, x ≠ y ∧ (⟦x⟧ : Cluster F) = ⟦y⟧;
. right;
obtain ⟨y, nexy, h⟩ := ex;
use x, y;
tauto;
. left;
use x;
constructor;
. simpa [degenerate] using h;
. rintro y ⟨hy₁, hy₂⟩;
simp only [ne_eq, Quotient.eq, not_exists, not_and] at ex;
replace hy₁ := iff_eq_cluster.mp hy₁;
rcases hy₁ with rfl | ⟨Rxy, Ryx⟩;
. tauto;
. apply not_imp_comm.mp (ex y) ?_ |>.symm;
push Not;
dsimp [clusterEquiv];
tauto;
lemma refl_of_mem_non_degenerate (h : ¬C.degenerate) (hx : x ∈ C) : x ≺ x := by
rcases (either_simple_or_proper_of_non_degenerate h) with h | h;
. apply refl_in_simple h hx;
. apply refl_in_proper h hx;
theorem degenerate_or_simple_or_proper : C.degenerate ∨ C.simple ∨ C.proper := by
by_cases h : C.degenerate;
. left;
exact h;
. right;
exact either_simple_or_proper_of_non_degenerate h;
end Cluster
def Frame.skeleton (F : Frame) [F.IsTransitive] : Kripke.Frame where
World := Cluster F
world_nonempty := ⟨⟦F.world_nonempty.some⟧⟩
Rel := Cluster.rel
section
variable {F : Frame} [F.IsTransitive]
instance [Finite F] : Finite F.skeleton := by
dsimp only [Frame.skeleton];
infer_instance;
instance : F.skeleton.IsTransitive := by
dsimp only [Frame.skeleton];
infer_instance;
instance : F.skeleton.IsAntisymmetric := by
dsimp only [Frame.skeleton];
infer_instance;
instance [F.IsReflexive] : F.skeleton.IsReflexive := by
dsimp only [Frame.skeleton];
infer_instance;
instance [F.IsReflexive] : F.skeleton.IsPartialOrder where
instance [Std.Total F] : Std.Total F.skeleton := by
dsimp only [Frame.skeleton];
infer_instance;
instance [Std.Total F] : IsLinearOrder _ F.skeleton where
end
def Frame.strictSkelteon (F : Frame) [F.IsTransitive] : Kripke.Frame where
World := Cluster F
world_nonempty := ⟨⟦F.world_nonempty.some⟧⟩
Rel := Cluster.strict_rel
namespace Frame.strictSkelteon
variable {F : Frame} [F.IsTransitive]
instance [Finite F] : Finite F.strictSkelteon := by
dsimp only [Frame.strictSkelteon];
infer_instance;
instance : F.strictSkelteon.IsTransitive := by
dsimp only [Frame.strictSkelteon];
infer_instance;
instance : F.strictSkelteon.IsIrreflexive := by
dsimp only [Frame.strictSkelteon];
infer_instance;
instance [IsTrichotomous _ F] : IsTrichotomous _ F.strictSkelteon := by
dsimp only [Frame.strictSkelteon];
infer_instance;
instance [IsTrichotomous _ F] : IsStrictTotalOrder _ F.strictSkelteon where
end Frame.strictSkelteon
end Kripke
end LO.Modal
end