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

Commit 7ec5e87

Browse files
committed
feat(set_theory/lists): finite ZFA
1 parent 8731789 commit 7ec5e87

File tree

2 files changed

+342
-1
lines changed

2 files changed

+342
-1
lines changed

set_theory/lists.lean

Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
/-
2+
Copyright (c) 2018 Mario Carneiro. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Author: Mario Carneiro
5+
6+
A computable model of hereditarily finite sets with atoms
7+
(ZFA without infinity). This is useful for calculations in naive
8+
set theory.
9+
-/
10+
import tactic.interactive data.list.basic
11+
12+
variables {α : Type*}
13+
14+
@[derive decidable_eq]
15+
inductive {u} lists' (α : Type u) : bool → Type u
16+
| atom : α → lists' ff
17+
| nil {} : lists' tt
18+
| cons' {b} : lists' b → lists' tt → lists' tt
19+
20+
def lists (α : Type*) := Σ b, lists' α b
21+
22+
namespace lists'
23+
24+
def cons : lists α → lists' α tt → lists' α tt
25+
| ⟨b, a⟩ l := cons' a l
26+
27+
@[simp] def to_list : ∀ {b}, lists' α b → list (lists α)
28+
| _ (atom a) := []
29+
| _ nil := []
30+
| _ (cons' a l) := ⟨_, a⟩ :: l.to_list
31+
32+
@[simp] theorem to_list_cons (a : lists α) (l) :
33+
to_list (cons a l) = a :: l.to_list :=
34+
by cases a; simp [cons]
35+
36+
@[simp] def of_list : list (lists α) → lists' α tt
37+
| [] := nil
38+
| (a :: l) := cons a (of_list l)
39+
40+
@[simp] theorem to_of_list (l : list (lists α)) : to_list (of_list l) = l :=
41+
by induction l; simp *
42+
43+
@[simp] theorem of_to_list : ∀ (l : lists' α tt), of_list (to_list l) = l :=
44+
suffices ∀ b (h : tt = b) (l : lists' α b),
45+
let l' : lists' α tt := by rw h; exact l in
46+
of_list (to_list l') = l', from this _ rfl,
47+
λ b h l, begin
48+
induction l, {cases h}, {exact rfl},
49+
case lists'.cons' : b a l IH₁ IH₂ {
50+
intro, change l' with cons' a l,
51+
simpa [cons] using IH₂ rfl }
52+
end
53+
54+
end lists'
55+
56+
mutual inductive lists.equiv, lists'.subset
57+
with lists.equiv : lists α → lists α → Prop
58+
| refl (l) : lists.equiv l l
59+
| antisymm {l₁ l₂ : lists' α tt} :
60+
lists'.subset l₁ l₂ → lists'.subset l₂ l₁ → lists.equiv ⟨_, l₁⟩ ⟨_, l₂⟩
61+
with lists'.subset : lists' α tt → lists' α tt → Prop
62+
| nil {l} : lists'.subset lists'.nil l
63+
| cons {a a' l l'} : lists.equiv a a' → a' ∈ lists'.to_list l' →
64+
lists'.subset l l' → lists'.subset (lists'.cons a l) l'
65+
local infix ~ := equiv
66+
67+
namespace lists'
68+
69+
instance : has_subset (lists' α tt) := ⟨lists'.subset⟩
70+
71+
instance {b} : has_mem (lists α) (lists' α b) :=
72+
⟨λ a l, ∃ a' ∈ l.to_list, a ~ a'⟩
73+
74+
theorem mem_def {b a} {l : lists' α b} :
75+
a ∈ l ↔ ∃ a' ∈ l.to_list, a ~ a' := iff.rfl
76+
77+
@[simp] theorem mem_cons {a y l} : a ∈ @cons α y l ↔ a ~ y ∨ a ∈ l :=
78+
by simp [mem_def, or_and_distrib_right, exists_or_distrib]
79+
80+
theorem cons_subset {a} {l₁ l₂ : lists' α tt} :
81+
lists'.cons a l₁ ⊆ l₂ ↔ a ∈ l₂ ∧ l₁ ⊆ l₂ :=
82+
begin
83+
refine ⟨λ h, _, λ ⟨⟨a', m, e⟩, s⟩, subset.cons e m s⟩,
84+
generalize_hyp h' : lists'.cons a l₁ = l₁' at h,
85+
cases h with l a' a'' l l' e m s, {cases a, cases h'},
86+
cases a, cases a', cases h', exact ⟨⟨_, m, e⟩, s⟩
87+
end
88+
89+
theorem of_list_subset {l₁ l₂ : list (lists α)} (h : l₁ ⊆ l₂) :
90+
lists'.of_list l₁ ⊆ lists'.of_list l₂ :=
91+
begin
92+
induction l₁, {exact subset.nil},
93+
refine subset.cons (equiv.refl _) _ (l₁_ih (list.subset_of_cons_subset h)),
94+
simp at h, simp [h]
95+
end
96+
97+
@[refl] theorem subset.refl {l : lists' α tt} : l ⊆ l :=
98+
by rw ← lists'.of_to_list l; exact
99+
of_list_subset (list.subset.refl _)
100+
101+
theorem subset_nil {l : lists' α tt} :
102+
l ⊆ lists'.nil → l = lists'.nil :=
103+
begin
104+
rw ← of_to_list l,
105+
induction to_list l; intro h, {refl},
106+
rcases cons_subset.1 h with ⟨⟨_, ⟨⟩, _⟩, _⟩
107+
end
108+
109+
theorem mem_of_subset' {a} {l₁ l₂ : lists' α tt}
110+
(s : l₁ ⊆ l₂) (h : a ∈ l₁.to_list) : a ∈ l₂ :=
111+
begin
112+
induction s with _ a a' l l' e m s IH, {cases h},
113+
simp at h, rcases h with rfl|h,
114+
exacts [⟨_, m, e⟩, IH h]
115+
end
116+
117+
theorem subset_def {l₁ l₂ : lists' α tt} :
118+
l₁ ⊆ l₂ ↔ ∀ a ∈ l₁.to_list, a ∈ l₂ :=
119+
⟨λ H a, mem_of_subset' H, λ H, begin
120+
rw ← of_to_list l₁,
121+
revert H, induction to_list l₁; intro,
122+
{ exact subset.nil },
123+
{ simp at H, exact cons_subset.2 ⟨H.1, ih H.2⟩ }
124+
end
125+
126+
end lists'
127+
128+
namespace lists
129+
130+
@[pattern] def atom (a : α) : lists α := ⟨_, lists'.atom a⟩
131+
132+
@[pattern] def of' (l : lists' α tt) : lists α := ⟨_, l⟩
133+
134+
@[simp] def to_list : lists α → list (lists α)
135+
| ⟨b, l⟩ := l.to_list
136+
137+
def is_list (l : lists α) : Prop := l.1
138+
139+
def of_list (l : list (lists α)) : lists α := of' (lists'.of_list l)
140+
141+
theorem is_list_to_list (l : list (lists α)) : is_list (of_list l) :=
142+
eq.refl _
143+
144+
theorem to_of_list (l : list (lists α)) : to_list (of_list l) = l :=
145+
by simp [of_list, of']
146+
147+
theorem of_to_list : ∀ {l : lists α}, is_list l → of_list (to_list l) = l
148+
| ⟨tt, l⟩ _ := by simp [of_list, of']
149+
150+
instance [decidable_eq α] : decidable_eq (lists α) :=
151+
by unfold lists; apply_instance
152+
153+
instance [has_sizeof α] : has_sizeof (lists α) :=
154+
by unfold lists; apply_instance
155+
156+
def induction_mut (C : lists α → Sort*) (D : lists' α tt → Sort*)
157+
(C0 : ∀ a, C (atom a)) (C1 : ∀ l, D l → C (of' l))
158+
(D0 : D lists'.nil) (D1 : ∀ a l, C a → D l → D (lists'.cons a l)) :
159+
pprod (∀ l, C l) (∀ l, D l) :=
160+
begin
161+
suffices : ∀ {b} (l : lists' α b),
162+
pprod (C ⟨_, l⟩) (match b, l with
163+
| tt, l := D l
164+
| ff, l := punit
165+
end),
166+
{ exact ⟨λ ⟨b, l⟩, (this _).1, λ l, (this l).2⟩ },
167+
intros, induction l with a b a l IH₁ IH₂,
168+
{ exact ⟨C0 _, ⟨⟩⟩ },
169+
{ exact ⟨C1 _ D0, D0⟩ },
170+
{ suffices, {exact ⟨C1 _ this, this⟩},
171+
exact D1 ⟨_, _⟩ _ IH₁.1 IH₂.2 }
172+
end
173+
174+
def mem (a : lists α) : lists α → Prop
175+
| ⟨ff, l⟩ := false
176+
| ⟨tt, l⟩ := a ∈ l
177+
178+
instance : has_mem (lists α) (lists α) := ⟨mem⟩
179+
180+
theorem is_list_of_mem {a : lists α} : ∀ {l : lists α}, a ∈ l → is_list l
181+
| ⟨_, lists'.nil⟩ _ := rfl
182+
| ⟨_, lists'.cons' _ _⟩ _ := rfl
183+
184+
theorem equiv.antisymm_iff {l₁ l₂ : lists' α tt} :
185+
of' l₁ ~ of' l₂ ↔ l₁ ⊆ l₂ ∧ l₂ ⊆ l₁ :=
186+
begin
187+
refine ⟨λ h, _, λ ⟨h₁, h₂⟩, equiv.antisymm h₁ h₂⟩,
188+
cases h with _ _ _ h₁ h₂,
189+
{ simp [lists'.subset.refl] }, { exact ⟨h₁, h₂⟩ }
190+
end
191+
192+
attribute [refl] equiv.refl
193+
194+
theorem equiv_atom {a} {l : lists α} : atom a ~ l ↔ atom a = l :=
195+
⟨λ h, by cases h; refl, λ h, h ▸ equiv.refl _⟩
196+
197+
theorem equiv.symm {l₁ l₂ : lists α} (h : l₁ ~ l₂) : l₂ ~ l₁ :=
198+
by cases h with _ _ _ h₁ h₂; [refl, exact equiv.antisymm h₂ h₁]
199+
200+
theorem equiv.trans : ∀ {l₁ l₂ l₃ : lists α}, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃ :=
201+
begin
202+
let trans := λ (l₁ : lists α), ∀ ⦃l₂ l₃⦄, l₁ ~ l₂ → l₂ ~ l₃ → l₁ ~ l₃,
203+
suffices : pprod (∀ l₁, trans l₁)
204+
(∀ (l : lists' α tt) (l' ∈ l.to_list), trans l'), {exact this.1},
205+
apply induction_mut,
206+
{ intros a l₂ l₃ h₁ h₂,
207+
rwa ← equiv_atom.1 h₁ at h₂ },
208+
{ intros l₁ IH l₂ l₃ h₁ h₂,
209+
cases h₁ with _ _ l₂, {exact h₂},
210+
cases h₂ with _ _ l₃, {exact h₁},
211+
cases equiv.antisymm_iff.1 h₁ with hl₁ hr₁,
212+
cases equiv.antisymm_iff.1 h₂ with hl₂ hr₂,
213+
apply equiv.antisymm_iff.2; split; apply lists'.subset_def.2,
214+
{ intros a₁ m₁,
215+
rcases lists'.mem_of_subset' hl₁ m₁ with ⟨a₂, m₂, e₁₂⟩,
216+
rcases lists'.mem_of_subset' hl₂ m₂ with ⟨a₃, m₃, e₂₃⟩,
217+
exact ⟨a₃, m₃, IH _ m₁ e₁₂ e₂₃⟩ },
218+
{ intros a₃ m₃,
219+
rcases lists'.mem_of_subset' hr₂ m₃ with ⟨a₂, m₂, e₃₂⟩,
220+
rcases lists'.mem_of_subset' hr₁ m₂ with ⟨a₁, m₁, e₂₁⟩,
221+
exact ⟨a₁, m₁, (IH _ m₁ e₂₁.symm e₃₂.symm).symm⟩ } },
222+
{ rintro _ ⟨⟩ },
223+
{ intros a l IH₁ IH₂, simpa [IH₁] using IH₂ }
224+
end
225+
226+
instance : setoid (lists α) :=
227+
⟨(~), equiv.refl, @equiv.symm _, @equiv.trans _⟩
228+
229+
section decidable
230+
231+
@[simp] def equiv.decidable_meas :
232+
(psum (Σ' (l₁ : lists α), lists α) $
233+
psum (Σ' (l₁ : lists' α tt), lists' α tt)
234+
Σ' (a : lists α), lists' α tt) → ℕ
235+
| (psum.inl ⟨l₁, l₂⟩) := sizeof l₁ + sizeof l₂
236+
| (psum.inr $ psum.inl ⟨l₁, l₂⟩) := sizeof l₁ + sizeof l₂
237+
| (psum.inr $ psum.inr ⟨l₁, l₂⟩) := sizeof l₁ + sizeof l₂
238+
239+
local attribute [-simp] add_comm add_assoc
240+
open well_founded_tactics
241+
242+
theorem sizeof_pos {b} (l : lists' α b) : 0 < sizeof l :=
243+
by cases l; {unfold_sizeof, trivial_nat_lt}
244+
245+
theorem lt_sizeof_cons' {b} (a : lists' α b) (l) :
246+
sizeof (⟨b, a⟩ : lists α) < sizeof (lists'.cons' a l) :=
247+
by {unfold_sizeof, exact lt_add_of_pos_right _ (sizeof_pos _)}
248+
249+
@[instance] mutual def equiv.decidable, subset.decidable, mem.decidable [decidable_eq α]
250+
with equiv.decidable : ∀ l₁ l₂ : lists α, decidable (l₁ ~ l₂)
251+
| ⟨ff, l₁⟩ ⟨ff, l₂⟩ := decidable_of_iff' (l₁ = l₂) $
252+
by cases l₁; refine equiv_atom.trans (by simp [atom])
253+
| ⟨ff, l₁⟩ ⟨tt, l₂⟩ := is_false $ by rintro ⟨⟩
254+
| ⟨tt, l₁⟩ ⟨ff, l₂⟩ := is_false $ by rintro ⟨⟩
255+
| ⟨tt, l₁⟩ ⟨tt, l₂⟩ := begin
256+
haveI :=
257+
have sizeof l₁ + sizeof l₂ <
258+
sizeof (⟨tt, l₁⟩ : lists α) + sizeof (⟨tt, l₂⟩ : lists α),
259+
by default_dec_tac,
260+
subset.decidable l₁ l₂,
261+
haveI :=
262+
have sizeof l₂ + sizeof l₁ <
263+
sizeof (⟨tt, l₁⟩ : lists α) + sizeof (⟨tt, l₂⟩ : lists α),
264+
by default_dec_tac,
265+
subset.decidable l₂ l₁,
266+
exact decidable_of_iff' _ equiv.antisymm_iff,
267+
end
268+
with subset.decidable : ∀ l₁ l₂ : lists' α tt, decidable (l₁ ⊆ l₂)
269+
| lists'.nil l₂ := is_true subset.nil
270+
| (@lists'.cons' _ b a l₁) l₂ := begin
271+
haveI :=
272+
have sizeof (⟨b, a⟩ : lists α) + sizeof l₂ <
273+
sizeof (lists'.cons' a l₁) + sizeof l₂,
274+
from add_lt_add_right (lt_sizeof_cons' _ _) _,
275+
mem.decidable ⟨b, a⟩ l₂,
276+
haveI :=
277+
have sizeof l₁ + sizeof l₂ <
278+
sizeof (lists'.cons' a l₁) + sizeof l₂,
279+
by default_dec_tac,
280+
subset.decidable l₁ l₂,
281+
exact decidable_of_iff' _ (@lists'.cons_subset _ ⟨_, _⟩ _ _)
282+
end
283+
with mem.decidable : ∀ (a : lists α) (l : lists' α tt), decidable (a ∈ l)
284+
| a lists'.nil := is_false $ by rintro ⟨_, ⟨⟩, _⟩
285+
| a (lists'.cons' b l₂) := begin
286+
haveI :=
287+
have sizeof a + sizeof (⟨_, b⟩ : lists α) <
288+
sizeof a + sizeof (lists'.cons' b l₂),
289+
from add_lt_add_left (lt_sizeof_cons' _ _) _,
290+
equiv.decidable a ⟨_, b⟩,
291+
haveI :=
292+
have sizeof a + sizeof l₂ <
293+
sizeof a + sizeof (lists'.cons' b l₂),
294+
by default_dec_tac,
295+
mem.decidable a l₂,
296+
refine decidable_of_iff' (a ~ ⟨_, b⟩ ∨ a ∈ l₂) _,
297+
rw ← lists'.mem_cons, refl
298+
end
299+
using_well_founded {
300+
rel_tac := λ _ _, `[exact ⟨_, measure_wf equiv.decidable_meas⟩],
301+
dec_tac := `[assumption] }
302+
303+
end decidable
304+
305+
end lists
306+
307+
namespace lists'
308+
309+
theorem mem_equiv_left {l : lists' α tt} :
310+
∀ {a a'}, a ~ a' → (a ∈ l ↔ a' ∈ l) :=
311+
suffices ∀ {a a'}, a ~ a' → a ∈ l → a' ∈ l,
312+
from λ a a' e, ⟨this e, this e.symm⟩,
313+
λ a₁ a₂ e₁ ⟨a₃, m₃, e₂⟩, ⟨_, m₃, e₁.symm.trans e₂⟩
314+
315+
theorem mem_of_subset {a} {l₁ l₂ : lists' α tt}
316+
(s : l₁ ⊆ l₂) : a ∈ l₁ → a ∈ l₂ | ⟨a', m, e⟩ :=
317+
(mem_equiv_left e).2 (mem_of_subset' s m)
318+
319+
theorem subset.trans {l₁ l₂ l₃ : lists' α tt}
320+
(h₁ : l₁ ⊆ l₂) (h₂ : l₂ ⊆ l₃) : l₁ ⊆ l₃ :=
321+
subset_def.2 $ λ a₁ m₁, mem_of_subset h₂ $ mem_of_subset' h₁ m₁
322+
323+
end lists'
324+
325+
def finsets (α : Type*) := quotient (@lists.setoid α)
326+
327+
namespace finsets
328+
329+
instance : has_emptyc (finsets α) := ⟨⟦lists.of' lists'.nil⟧⟩
330+
331+
instance [decidable_eq α] : decidable_eq (finsets α) :=
332+
by unfold finsets; apply_instance
333+
334+
end finsets

set_theory/zfc.lean

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
/-
2+
Copyright (c) 2018 Mario Carneiro. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Author: Mario Carneiro
5+
6+
A model of ZFC in Lean.
7+
-/
18
import data.set.basic
29

310
universes u v
@@ -37,7 +44,7 @@ theorem equiv.refl (x) : equiv x x :=
3744
pSet.rec_on x $ λα A IH, ⟨λa, ⟨a, IH a⟩, λa, ⟨a, IH a⟩⟩
3845

3946
theorem equiv.euc {x} : Π {y z}, equiv x y → equiv z y → equiv x z :=
40-
pSet.rec_on x $ λα A IH y, pSet.rec_on y $ λβ B _ ⟨γ, Γ⟩ ⟨αβ, βα⟩ ⟨γβ, βγ⟩,
47+
pSet.rec_on x $ λα A IH y, pSet.cases_on y $ λβ B ⟨γ, Γ⟩ ⟨αβ, βα⟩ ⟨γβ, βγ⟩,
4148
⟨λa, let ⟨b, ab⟩ := αβ a, ⟨c, bc⟩ := βγ b in ⟨c, IH a ab bc⟩,
4249
λc, let ⟨b, cb⟩ := γβ c, ⟨a, ba⟩ := βα b in ⟨a, IH a ba cb⟩⟩
4350

0 commit comments

Comments
 (0)