-
Notifications
You must be signed in to change notification settings - Fork 337
/
Ultraproducts.lean
167 lines (138 loc) · 6.22 KB
/
Ultraproducts.lean
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
/-
Copyright (c) 2022 Aaron Anderson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Aaron Anderson
-/
import Mathlib.ModelTheory.Quotients
import Mathlib.Order.Filter.Germ.Basic
import Mathlib.Order.Filter.Ultrafilter
/-!
# Ultraproducts and Łoś's Theorem
## Main Definitions
- `FirstOrder.Language.Ultraproduct.Structure` is the ultraproduct structure on `Filter.Product`.
## Main Results
- Łoś's Theorem: `FirstOrder.Language.Ultraproduct.sentence_realize`. An ultraproduct models a
sentence `φ` if and only if the set of structures in the product that model `φ` is in the
ultrafilter.
## Tags
ultraproduct, Los's theorem
-/
universe u v
variable {α : Type*} (M : α → Type*) (u : Ultrafilter α)
open FirstOrder Filter
open Filter
namespace FirstOrder
namespace Language
open Structure
variable {L : Language.{u, v}} [∀ a, L.Structure (M a)]
namespace Ultraproduct
instance setoidPrestructure : L.Prestructure ((u : Filter α).productSetoid M) :=
{ (u : Filter α).productSetoid M with
toStructure :=
{ funMap := fun {n} f x a => funMap f fun i => x i a
RelMap := fun {n} r x => ∀ᶠ a : α in u, RelMap r fun i => x i a }
fun_equiv := fun {n} f x y xy => by
refine mem_of_superset (iInter_mem.2 xy) fun a ha => ?_
simp only [Set.mem_iInter, Set.mem_setOf_eq] at ha
simp only [Set.mem_setOf_eq, ha]
rel_equiv := fun {n} r x y xy => by
rw [← iff_eq_eq]
refine ⟨fun hx => ?_, fun hy => ?_⟩
· refine mem_of_superset (inter_mem hx (iInter_mem.2 xy)) ?_
rintro a ⟨ha1, ha2⟩
simp only [Set.mem_iInter, Set.mem_setOf_eq] at *
rw [← funext ha2]
exact ha1
· refine mem_of_superset (inter_mem hy (iInter_mem.2 xy)) ?_
rintro a ⟨ha1, ha2⟩
simp only [Set.mem_iInter, Set.mem_setOf_eq] at *
rw [funext ha2]
exact ha1 }
variable {M} {u}
instance «structure» : L.Structure ((u : Filter α).Product M) :=
Language.quotientStructure
theorem funMap_cast {n : ℕ} (f : L.Functions n) (x : Fin n → ∀ a, M a) :
(funMap f fun i => (x i : (u : Filter α).Product M)) =
(fun a => funMap f fun i => x i a : (u : Filter α).Product M) := by
apply funMap_quotient_mk'
theorem term_realize_cast {β : Type*} (x : β → ∀ a, M a) (t : L.Term β) :
(t.realize fun i => (x i : (u : Filter α).Product M)) =
(fun a => t.realize fun i => x i a : (u : Filter α).Product M) := by
convert @Term.realize_quotient_mk' L _ ((u : Filter α).productSetoid M)
(Ultraproduct.setoidPrestructure M u) _ t x using 2
ext a
induction t with
| var => rfl
| func _ _ t_ih => simp only [Term.realize, t_ih]; rfl
variable [∀ a : α, Nonempty (M a)]
theorem boundedFormula_realize_cast {β : Type*} {n : ℕ} (φ : L.BoundedFormula β n)
(x : β → ∀ a, M a) (v : Fin n → ∀ a, M a) :
(φ.Realize (fun i : β => (x i : (u : Filter α).Product M))
(fun i => (v i : (u : Filter α).Product M))) ↔
∀ᶠ a : α in u, φ.Realize (fun i : β => x i a) fun i => v i a := by
letI := (u : Filter α).productSetoid M
induction φ with
| falsum => simp only [BoundedFormula.Realize, eventually_const]
| equal =>
have h2 : ∀ a : α, (Sum.elim (fun i : β => x i a) fun i => v i a) = fun i => Sum.elim x v i a :=
fun a => funext fun i => Sum.casesOn i (fun i => rfl) fun i => rfl
simp only [BoundedFormula.Realize, h2, term_realize_cast]
erw [(Sum.comp_elim ((↑) : (∀ a, M a) → (u : Filter α).Product M) x v).symm,
term_realize_cast, term_realize_cast]
exact Quotient.eq''
| rel =>
have h2 : ∀ a : α, (Sum.elim (fun i : β => x i a) fun i => v i a) = fun i => Sum.elim x v i a :=
fun a => funext fun i => Sum.casesOn i (fun i => rfl) fun i => rfl
simp only [BoundedFormula.Realize, h2]
erw [(Sum.comp_elim ((↑) : (∀ a, M a) → (u : Filter α).Product M) x v).symm]
conv_lhs => enter [2, i]; erw [term_realize_cast]
apply relMap_quotient_mk'
| imp _ _ ih ih' =>
simp only [BoundedFormula.Realize, ih v, ih' v]
rw [Ultrafilter.eventually_imp]
| @all k φ ih =>
simp only [BoundedFormula.Realize]
apply Iff.trans (b := ∀ m : ∀ a : α, M a,
φ.Realize (fun i : β => (x i : (u : Filter α).Product M))
(Fin.snoc (((↑) : (∀ a, M a) → (u : Filter α).Product M) ∘ v)
(m : (u : Filter α).Product M)))
· exact Quotient.forall
have h' :
∀ (m : ∀ a, M a) (a : α),
(fun i : Fin (k + 1) => (Fin.snoc v m : _ → ∀ a, M a) i a) =
Fin.snoc (fun i : Fin k => v i a) (m a) := by
refine fun m a => funext (Fin.reverseInduction ?_ fun i _ => ?_)
· simp only [Fin.snoc_last]
· simp only [Fin.snoc_castSucc]
simp only [← Fin.comp_snoc]
simp only [Function.comp_def, ih, h']
refine ⟨fun h => ?_, fun h m => ?_⟩
· contrapose! h
simp_rw [← Ultrafilter.eventually_not, not_forall] at h
refine
⟨fun a : α =>
Classical.epsilon fun m : M a =>
¬φ.Realize (fun i => x i a) (Fin.snoc (fun i => v i a) m),
?_⟩
rw [← Ultrafilter.eventually_not]
exact Filter.mem_of_superset h fun a ha => Classical.epsilon_spec ha
· rw [Filter.eventually_iff] at *
exact Filter.mem_of_superset h fun a ha => ha (m a)
theorem realize_formula_cast {β : Type*} (φ : L.Formula β) (x : β → ∀ a, M a) :
(φ.Realize fun i => (x i : (u : Filter α).Product M)) ↔
∀ᶠ a : α in u, φ.Realize fun i => x i a := by
simp_rw [Formula.Realize, ← boundedFormula_realize_cast φ x, iff_eq_eq]
exact congr rfl (Subsingleton.elim _ _)
/-- **Łoś's Theorem**: A sentence is true in an ultraproduct if and only if the set of structures
it is true in is in the ultrafilter. -/
theorem sentence_realize (φ : L.Sentence) :
(u : Filter α).Product M ⊨ φ ↔ ∀ᶠ a : α in u, M a ⊨ φ := by
simp_rw [Sentence.Realize]
erw [← realize_formula_cast φ, iff_eq_eq]
exact congr rfl (Subsingleton.elim _ _)
nonrec instance Product.instNonempty : Nonempty ((u : Filter α).Product M) :=
letI : ∀ a, Inhabited (M a) := fun _ => Classical.inhabited_of_nonempty'
inferInstance
end Ultraproduct
end Language
end FirstOrder