|
| 1 | +/- |
| 2 | +Copyright (c) 2019 Abhimanyu Pallavi Sudhir. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Abhimanyu Pallavi Sudhir, Yury Kudryashov |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module order.filter.filter_product |
| 7 | +! leanprover-community/mathlib commit 2738d2ca56cbc63be80c3bd48e9ed90ad94e947d |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Order.Filter.Ultrafilter |
| 12 | +import Mathlib.Order.Filter.Germ |
| 13 | + |
| 14 | +/-! |
| 15 | +# Ultraproducts |
| 16 | +
|
| 17 | +If `φ` is an ultrafilter, then the space of germs of functions `f : α → β` at `φ` is called |
| 18 | +the *ultraproduct*. In this file we prove properties of ultraproducts that rely on `φ` being an |
| 19 | +ultrafilter. Definitions and properties that work for any filter should go to `Order.Filter.Germ`. |
| 20 | +
|
| 21 | +## Tags |
| 22 | +
|
| 23 | +ultrafilter, ultraproduct |
| 24 | +-/ |
| 25 | + |
| 26 | + |
| 27 | +universe u v |
| 28 | + |
| 29 | +variable {α : Type u} {β : Type v} {φ : Ultrafilter α} |
| 30 | + |
| 31 | +open Classical |
| 32 | + |
| 33 | +namespace Filter |
| 34 | + |
| 35 | +local notation3"∀* "(...)", "r:(scoped p => Filter.Eventually p φ) => r |
| 36 | + |
| 37 | +namespace Germ |
| 38 | + |
| 39 | +open Ultrafilter |
| 40 | + |
| 41 | +local notation "β*" => Germ (φ : Filter α) β |
| 42 | + |
| 43 | +instance divisionSemiring [DivisionSemiring β] : DivisionSemiring β* := |
| 44 | + { Germ.semiring, Germ.divInvMonoid, |
| 45 | + Germ.nontrivial with |
| 46 | + mul_inv_cancel := fun f => |
| 47 | + inductionOn f fun f hf => |
| 48 | + coe_eq.2 <| |
| 49 | + (φ.em fun y => f y = 0).elim (fun H => (hf <| coe_eq.2 H).elim) fun H => |
| 50 | + H.mono fun x => mul_inv_cancel |
| 51 | + inv_zero := coe_eq.2 <| by |
| 52 | + simp only [Function.comp, inv_zero] |
| 53 | + exact EventuallyEq.refl _ fun _ => 0} |
| 54 | + |
| 55 | +instance divisionRing [DivisionRing β] : DivisionRing β* := |
| 56 | + { Germ.ring, Germ.divisionSemiring with } |
| 57 | + |
| 58 | +instance semifield [Semifield β] : Semifield β* := |
| 59 | + { Germ.commSemiring, Germ.divisionSemiring with } |
| 60 | + |
| 61 | +instance field [Field β] : Field β* := |
| 62 | + { Germ.commRing, Germ.divisionRing with } |
| 63 | + |
| 64 | +theorem coe_lt [Preorder β] {f g : α → β} : (f : β*) < g ↔ ∀* x, f x < g x := by |
| 65 | + simp only [lt_iff_le_not_le, eventually_and, coe_le, eventually_not, EventuallyLe] |
| 66 | +#align filter.germ.coe_lt Filter.Germ.coe_lt |
| 67 | + |
| 68 | +theorem coe_pos [Preorder β] [Zero β] {f : α → β} : 0 < (f : β*) ↔ ∀* x, 0 < f x := |
| 69 | + coe_lt |
| 70 | +#align filter.germ.coe_pos Filter.Germ.coe_pos |
| 71 | + |
| 72 | +theorem const_lt [Preorder β] {x y : β} : x < y → (↑x : β*) < ↑y := |
| 73 | + coe_lt.mpr ∘ liftRel_const |
| 74 | +#align filter.germ.const_lt Filter.Germ.const_lt |
| 75 | + |
| 76 | +@[simp, norm_cast] |
| 77 | +theorem const_lt_iff [Preorder β] {x y : β} : (↑x : β*) < ↑y ↔ x < y := |
| 78 | + coe_lt.trans liftRel_const_iff |
| 79 | +#align filter.germ.const_lt_iff Filter.Germ.const_lt_iff |
| 80 | + |
| 81 | +theorem lt_def [Preorder β] : ((· < ·) : β* → β* → Prop) = LiftRel (· < ·) := by |
| 82 | + ext (⟨f⟩⟨g⟩) |
| 83 | + exact coe_lt |
| 84 | +#align filter.germ.lt_def Filter.Germ.lt_def |
| 85 | + |
| 86 | +instance hasSup [HasSup β] : HasSup β* := |
| 87 | + ⟨map₂ (· ⊔ ·)⟩ |
| 88 | + |
| 89 | +instance hasInf [HasInf β] : HasInf β* := |
| 90 | + ⟨map₂ (· ⊓ ·)⟩ |
| 91 | + |
| 92 | +@[simp, norm_cast] |
| 93 | +theorem const_sup [HasSup β] (a b : β) : ↑(a ⊔ b) = (↑a ⊔ ↑b : β*) := |
| 94 | + rfl |
| 95 | +#align filter.germ.const_sup Filter.Germ.const_sup |
| 96 | + |
| 97 | +@[simp, norm_cast] |
| 98 | +theorem const_inf [HasInf β] (a b : β) : ↑(a ⊓ b) = (↑a ⊓ ↑b : β*) := |
| 99 | + rfl |
| 100 | +#align filter.germ.const_inf Filter.Germ.const_inf |
| 101 | + |
| 102 | +instance semilatticeSup [SemilatticeSup β] : SemilatticeSup β* := |
| 103 | + { Germ.partialOrder with |
| 104 | + sup := (· ⊔ ·) |
| 105 | + le_sup_left := fun f g => |
| 106 | + inductionOn₂ f g fun _f _g => eventually_of_forall fun _x => le_sup_left |
| 107 | + le_sup_right := fun f g => |
| 108 | + inductionOn₂ f g fun _f _g => eventually_of_forall fun _x => le_sup_right |
| 109 | + sup_le := fun f₁ f₂ g => |
| 110 | + inductionOn₃ f₁ f₂ g fun _f₁ _f₂ _g h₁ h₂ => h₂.mp <| h₁.mono fun _x => sup_le } |
| 111 | + |
| 112 | +instance semilatticeInf [SemilatticeInf β] : SemilatticeInf β* := |
| 113 | + { Germ.partialOrder with |
| 114 | + inf := (· ⊓ ·) |
| 115 | + inf_le_left := fun f g => |
| 116 | + inductionOn₂ f g fun _f _g => eventually_of_forall fun _x => inf_le_left |
| 117 | + inf_le_right := fun f g => |
| 118 | + inductionOn₂ f g fun _f _g => eventually_of_forall fun _x => inf_le_right |
| 119 | + le_inf := fun f₁ f₂ g => |
| 120 | + inductionOn₃ f₁ f₂ g fun _f₁ _f₂ _g h₁ h₂ => h₂.mp <| h₁.mono fun _x => le_inf } |
| 121 | + |
| 122 | +instance lattice [Lattice β] : Lattice β* := |
| 123 | + { Germ.semilatticeSup, Germ.semilatticeInf with } |
| 124 | + |
| 125 | +instance distribLattice [DistribLattice β] : DistribLattice β* := |
| 126 | + { Germ.semilatticeSup, Germ.semilatticeInf with |
| 127 | + le_sup_inf := fun f g h => |
| 128 | + inductionOn₃ f g h fun _f _g _h => eventually_of_forall fun _ => le_sup_inf } |
| 129 | + |
| 130 | +instance isTotal [LE β] [IsTotal β (· ≤ ·)] : IsTotal β* (· ≤ ·) := |
| 131 | + ⟨fun f g => |
| 132 | + inductionOn₂ f g fun _f _g => eventually_or.1 <| eventually_of_forall fun _x => total_of _ _ _⟩ |
| 133 | + |
| 134 | +/-- If `φ` is an ultrafilter then the ultraproduct is a linear order. -/ |
| 135 | +noncomputable instance linearOrder [LinearOrder β] : LinearOrder β* := |
| 136 | + Lattice.toLinearOrder _ |
| 137 | + |
| 138 | +@[to_additive] |
| 139 | +instance orderedCommMonoid [OrderedCommMonoid β] : OrderedCommMonoid β* := |
| 140 | + { Germ.partialOrder, Germ.commMonoid with |
| 141 | + mul_le_mul_left := fun f g => |
| 142 | + inductionOn₂ f g fun _f _g H h => |
| 143 | + inductionOn h fun _h => H.mono fun _x H => mul_le_mul_left' H _ } |
| 144 | + |
| 145 | +@[to_additive] |
| 146 | +instance orderedCancelCommMonoid [OrderedCancelCommMonoid β] : |
| 147 | + OrderedCancelCommMonoid β* := |
| 148 | + { Germ.orderedCommMonoid with |
| 149 | + le_of_mul_le_mul_left := fun f g h => |
| 150 | + inductionOn₃ f g h fun _f _g _h H => H.mono fun _x => le_of_mul_le_mul_left' } |
| 151 | + |
| 152 | +@[to_additive] |
| 153 | +instance orderedCommGroup [OrderedCommGroup β] : OrderedCommGroup β* := |
| 154 | + { Germ.orderedCancelCommMonoid, Germ.commGroup with } |
| 155 | + |
| 156 | +@[to_additive] |
| 157 | +noncomputable instance linearOrderedCommGroup [LinearOrderedCommGroup β] : |
| 158 | + LinearOrderedCommGroup β* := |
| 159 | + { Germ.orderedCommGroup, Germ.linearOrder with } |
| 160 | + |
| 161 | +instance orderedSemiring [OrderedSemiring β] : OrderedSemiring β* := |
| 162 | + { Germ.semiring, |
| 163 | + Germ.orderedAddCommMonoid with |
| 164 | + zero_le_one := const_le zero_le_one |
| 165 | + mul_le_mul_of_nonneg_left := fun x y z => |
| 166 | + inductionOn₃ x y z fun _f _g _h hfg hh => |
| 167 | + hh.mp <| hfg.mono fun _a => mul_le_mul_of_nonneg_left |
| 168 | + mul_le_mul_of_nonneg_right := fun x y z => |
| 169 | + inductionOn₃ x y z fun _f _g _h hfg hh => |
| 170 | + hh.mp <| hfg.mono fun _a => mul_le_mul_of_nonneg_right } |
| 171 | + |
| 172 | +instance orderedCommSemiring [OrderedCommSemiring β] : OrderedCommSemiring β* := |
| 173 | + { Germ.orderedSemiring, Germ.commSemiring with } |
| 174 | + |
| 175 | +instance orderedRing [OrderedRing β] : OrderedRing β* := |
| 176 | + { Germ.ring, |
| 177 | + Germ.orderedAddCommGroup with |
| 178 | + zero_le_one := const_le zero_le_one |
| 179 | + mul_nonneg := fun x y => |
| 180 | + inductionOn₂ x y fun _f _g hf hg => hg.mp <| hf.mono fun _a => mul_nonneg } |
| 181 | + |
| 182 | +instance orderedCommRing [OrderedCommRing β] : OrderedCommRing β* := |
| 183 | + { Germ.orderedRing, Germ.orderedCommSemiring with } |
| 184 | + |
| 185 | +instance strictOrderedSemiring [StrictOrderedSemiring β] : StrictOrderedSemiring β* := |
| 186 | + { Germ.orderedSemiring, Germ.orderedAddCancelCommMonoid, |
| 187 | + Germ.nontrivial with |
| 188 | + mul_lt_mul_of_pos_left := fun x y z => |
| 189 | + inductionOn₃ x y z fun _f _g _h hfg hh => |
| 190 | + coe_lt.2 <| (coe_lt.1 hh).mp <| (coe_lt.1 hfg).mono fun _a => mul_lt_mul_of_pos_left |
| 191 | + mul_lt_mul_of_pos_right := fun x y z => |
| 192 | + inductionOn₃ x y z fun _f _g _h hfg hh => |
| 193 | + coe_lt.2 <| (coe_lt.1 hh).mp <| (coe_lt.1 hfg).mono fun _a => mul_lt_mul_of_pos_right } |
| 194 | + |
| 195 | +instance strictOrderedCommSemiring [StrictOrderedCommSemiring β] : StrictOrderedCommSemiring β* := |
| 196 | + { Germ.strictOrderedSemiring, Germ.orderedCommSemiring with } |
| 197 | + |
| 198 | +instance strictOrderedRing [StrictOrderedRing β] : StrictOrderedRing β* := |
| 199 | + { Germ.ring, |
| 200 | + Germ.strictOrderedSemiring with |
| 201 | + zero_le_one := const_le zero_le_one |
| 202 | + mul_pos := fun x y => |
| 203 | + inductionOn₂ x y fun _f _g hf hg => |
| 204 | + coe_pos.2 <| (coe_pos.1 hg).mp <| (coe_pos.1 hf).mono fun _x => mul_pos } |
| 205 | + |
| 206 | +instance strictOrderedCommRing [StrictOrderedCommRing β] : StrictOrderedCommRing β* := |
| 207 | + { Germ.strictOrderedRing, Germ.orderedCommRing with } |
| 208 | + |
| 209 | +noncomputable instance linearOrderedRing [LinearOrderedRing β] : LinearOrderedRing β* := |
| 210 | + { Germ.strictOrderedRing, Germ.linearOrder with } |
| 211 | + |
| 212 | +noncomputable instance linearOrderedField [LinearOrderedField β] : LinearOrderedField β* := |
| 213 | + { Germ.linearOrderedRing, Germ.field with } |
| 214 | + |
| 215 | +noncomputable instance linearOrderedCommRing [LinearOrderedCommRing β] : LinearOrderedCommRing β* := |
| 216 | + { Germ.linearOrderedRing, Germ.commMonoid with } |
| 217 | + |
| 218 | +theorem max_def [LinearOrder β] (x y : β*) : max x y = map₂ max x y := |
| 219 | + inductionOn₂ x y fun a b => by |
| 220 | + cases' le_total (a : β*) b with h h |
| 221 | + · rw [max_eq_right h, map₂_coe, coe_eq] |
| 222 | + exact h.mono fun i hi => (max_eq_right hi).symm |
| 223 | + · rw [max_eq_left h, map₂_coe, coe_eq] |
| 224 | + exact h.mono fun i hi => (max_eq_left hi).symm |
| 225 | +#align filter.germ.max_def Filter.Germ.max_def |
| 226 | + |
| 227 | +theorem min_def [K : LinearOrder β] (x y : β*) : min x y = map₂ min x y := |
| 228 | + inductionOn₂ x y fun a b => by |
| 229 | + cases' le_total (a : β*) b with h h |
| 230 | + · rw [min_eq_left h, map₂_coe, coe_eq] |
| 231 | + exact h.mono fun i hi => (min_eq_left hi).symm |
| 232 | + · rw [min_eq_right h, map₂_coe, coe_eq] |
| 233 | + exact h.mono fun i hi => (min_eq_right hi).symm |
| 234 | +#align filter.germ.min_def Filter.Germ.min_def |
| 235 | + |
| 236 | +theorem abs_def [LinearOrderedAddCommGroup β] (x : β*) : |x| = map abs x := |
| 237 | + inductionOn x fun _a => rfl |
| 238 | +#align filter.germ.abs_def Filter.Germ.abs_def |
| 239 | + |
| 240 | +@[simp] |
| 241 | +theorem const_max [LinearOrder β] (x y : β) : (↑(max x y : β) : β*) = max ↑x ↑y := by |
| 242 | + rw [max_def, map₂_const] |
| 243 | +#align filter.germ.const_max Filter.Germ.const_max |
| 244 | + |
| 245 | +@[simp] |
| 246 | +theorem const_min [LinearOrder β] (x y : β) : (↑(min x y : β) : β*) = min ↑x ↑y := by |
| 247 | + rw [min_def, map₂_const] |
| 248 | +#align filter.germ.const_min Filter.Germ.const_min |
| 249 | + |
| 250 | +@[simp] |
| 251 | +theorem const_abs [LinearOrderedAddCommGroup β] (x : β) : (↑(|x|) : β*) = |↑x| := by |
| 252 | + rw [abs_def, map_const] |
| 253 | +#align filter.germ.const_abs Filter.Germ.const_abs |
| 254 | + |
| 255 | +end Germ |
| 256 | + |
| 257 | +end Filter |
0 commit comments