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

Commit ca23d52

Browse files
committed
feat(set_theory/surreal): add dyadic surreals (#7843)
We define `surreal.dyadic` using a map from \int localized away from 2 to surreals. As currently we do not have the ring structure on `surreal` we do this "by hand". Next steps: 1. Prove that `dyadic_map` is injective 2. Prove that `dyadic_map` is a group hom 3. Show that \int localized away from 2 is a subgroup of \rat.
1 parent f0effbd commit ca23d52

File tree

4 files changed

+304
-18
lines changed

4 files changed

+304
-18
lines changed

docs/references.bib

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ @Book{ conway2001
355355
mrnumber = {1803095}
356356
}
357357

358+
@Misc{ schleicher_stoll,
359+
author = {Dierk Schleicher and Michael Stoll},
360+
title = {An introduction to {C}onway's games and numbers},
361+
url = {http://www.cs.cmu.edu/afs/cs/academic/class/15859-s05/www/lecture-notes/comb-games-notes.pdf}
362+
}
363+
358364
@InProceedings{ deligne_formulaire,
359365
author = {Deligne, P.},
360366
title = {Courbes elliptiques: formulaire d'apr\`es {J}. {T}ate},

src/set_theory/pgame.lean

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,13 @@ local infix ` ≈ ` := pgame.equiv
420420
@[trans] theorem equiv_trans {x y z} : x ≈ y → y ≈ z → x ≈ z
421421
| ⟨xy, yx⟩ ⟨yz, zy⟩ := ⟨le_trans xy yz, le_trans zy yx⟩
422422

423+
@[trans]
423424
theorem lt_of_lt_of_equiv {x y z} (h₁ : x < y) (h₂ : y ≈ z) : x < z := lt_of_lt_of_le h₁ h₂.1
425+
@[trans]
424426
theorem le_of_le_of_equiv {x y z} (h₁ : x ≤ y) (h₂ : y ≈ z) : x ≤ z := le_trans h₁ h₂.1
427+
@[trans]
425428
theorem lt_of_equiv_of_lt {x y z} (h₁ : x ≈ y) (h₂ : y < z) : x < z := lt_of_le_of_lt h₁.1 h₂
429+
@[trans]
426430
theorem le_of_equiv_of_le {x y z} (h₁ : x ≈ y) (h₂ : y ≤ z) : x ≤ z := le_trans h₁.1 h₂
427431

428432
theorem le_congr {x₁ y₁ x₂ y₂} : x₁ ≈ x₂ → y₁ ≈ y₂ → (x₁ ≤ y₁ ↔ x₂ ≤ y₂)
@@ -1021,4 +1025,35 @@ or.inl ⟨⟨0, zero_lt_one⟩, (by split; rintros ⟨⟩)⟩
10211025
/-- The pre-game `ω`. (In fact all ordinals have game and surreal representatives.) -/
10221026
def omega : pgame := ⟨ulift ℕ, pempty, λ n, ↑n.1, pempty.elim⟩
10231027

1028+
theorem zero_lt_one : (0 : pgame) < 1 :=
1029+
begin
1030+
rw lt_def,
1031+
left,
1032+
use ⟨punit.star, by split; rintro ⟨ ⟩⟩,
1033+
end
1034+
1035+
/-- The pre-game `half` is defined as `{0 | 1}`. -/
1036+
def half : pgame := ⟨punit, punit, 0, 1
1037+
1038+
@[simp] lemma half_move_left : half.move_left punit.star = 0 := rfl
1039+
1040+
@[simp] lemma half_move_right : half.move_right punit.star = 1 := rfl
1041+
1042+
theorem zero_lt_half : 0 < half :=
1043+
begin
1044+
rw lt_def,
1045+
left,
1046+
use punit.star,
1047+
split; rintro ⟨ ⟩,
1048+
end
1049+
1050+
theorem half_lt_one : half < 1 :=
1051+
begin
1052+
rw lt_def,
1053+
right,
1054+
use punit.star,
1055+
split; rintro ⟨ ⟩,
1056+
exact zero_lt_one,
1057+
end
1058+
10241059
end pgame

src/set_theory/surreal.lean renamed to src/set_theory/surreal/basic.lean

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,19 @@ Surreal numbers inherit the relations `≤` and `<` from games, and these relati
2525
of a partial order (recall that `x < y ↔ x ≤ y ∧ ¬ y ≤ x` did not hold for games).
2626
2727
## Algebraic operations
28-
At this point, we have defined addition and negation (from pregames), and shown that surreals form
29-
an additive semigroup. It would be very little work to finish showing that the surreals form an
30-
ordered commutative group.
31-
32-
## Embeddings
33-
It would be nice projects to define the group homomorphism `surreal → game`, and also `ℤ → surreal`,
34-
and then the homomorphic inclusion of the dyadic rationals into surreals, and finally
35-
via dyadic Dedekind cuts the homomorphic inclusion of the reals into the surreals.
28+
We show that the surreals form a linear ordered commutative group.
3629
3730
One can also map all the ordinals into the surreals!
3831
32+
### Multiplication of surreal numbers
33+
The definition of multiplication for surreal numbers is surprisingly difficult and is currently
34+
missing in the library. A sample proof can be found in Theorem 3.8 in the second reference below.
35+
The difficulty lies in the length of the proof and the number of theorems that need to proven
36+
simultaneously. This will make for a fun and challenging project.
37+
3938
## References
4039
* [Conway, *On numbers and games*][conway2001]
40+
* [Schleicher, Stoll, *An introduction to Conway's games and numbers*][schleicher_stoll]
4141
-/
4242

4343
universes u
@@ -198,6 +198,47 @@ theorem numeric_nat : Π (n : ℕ), numeric n
198198
theorem numeric_omega : numeric omega :=
199199
by rintros ⟨⟩ ⟨⟩, λ i, numeric_nat i.down, by rintros ⟨⟩⟩
200200

201+
/-- The pre-game `half` is numeric. -/
202+
theorem numeric_half : numeric half :=
203+
begin
204+
split,
205+
{ rintros ⟨ ⟩ ⟨ ⟩,
206+
exact zero_lt_one },
207+
split; rintro ⟨ ⟩,
208+
{ exact numeric_zero },
209+
{ exact numeric_one }
210+
end
211+
212+
theorem half_add_half_equiv_one : half + half ≈ 1 :=
213+
begin
214+
split; rw le_def; split,
215+
{ rintro (⟨⟨ ⟩⟩ | ⟨⟨ ⟩⟩),
216+
{ right,
217+
use (sum.inr punit.star),
218+
calc ((half + half).move_left (sum.inl punit.star)).move_right (sum.inr punit.star)
219+
= (half.move_left punit.star + half).move_right (sum.inr punit.star) : by fsplit
220+
... = (0 + half).move_right (sum.inr punit.star) : by fsplit
221+
... ≈ 1 : zero_add_equiv 1
222+
... ≤ 1 : pgame.le_refl 1 },
223+
{ right,
224+
use (sum.inl punit.star),
225+
calc ((half + half).move_left (sum.inr punit.star)).move_right (sum.inl punit.star)
226+
= (half + half.move_left punit.star).move_right (sum.inl punit.star) : by fsplit
227+
... = (half + 0).move_right (sum.inl punit.star) : by fsplit
228+
... ≈ 1 : add_zero_equiv 1
229+
... ≤ 1 : pgame.le_refl 1 } },
230+
{ rintro ⟨ ⟩ },
231+
{ rintro ⟨ ⟩,
232+
left,
233+
use (sum.inl punit.star),
234+
calc 0 ≤ half : le_of_lt numeric_zero numeric_half zero_lt_half
235+
... ≈ 0 + half : (zero_add_equiv half).symm
236+
... = (half + half).move_left (sum.inl punit.star) : by fsplit },
237+
{ rintro (⟨⟨ ⟩⟩ | ⟨⟨ ⟩⟩); left,
238+
{ exact ⟨sum.inr punit.star, le_of_le_of_equiv (pgame.le_refl _) (add_zero_equiv _).symm⟩ },
239+
{ exact ⟨sum.inl punit.star, le_of_le_of_equiv (pgame.le_refl _) (zero_add_equiv _).symm⟩ } }
240+
end
241+
201242
end pgame
202243

203244
/-- The equivalence on numeric pre-games. -/
@@ -295,16 +336,6 @@ noncomputable instance : linear_ordered_add_comm_group surreal :=
295336
-- We conclude with some ideas for further work on surreals; these would make fun projects.
296337

297338
-- TODO define the inclusion of groups `surreal → game`
298-
299-
-- TODO define the dyadic rationals, and show they map into the surreals via the formula
300-
-- m / 2^n ↦ { (m-1) / 2^n | (m+1) / 2^n }
301-
-- TODO show this is a group homomorphism, and injective
302-
303-
-- TODO map the reals into the surreals, using dyadic Dedekind cuts
304-
-- TODO show this is a group homomorphism, and injective
305-
306339
-- TODO define the field structure on the surreals
307-
-- TODO show the maps from the dyadic rationals and from the reals
308-
-- into the surreals are multiplicative
309340

310341
end surreal

src/set_theory/surreal/dyadic.lean

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
/-
2+
Copyright (c) 2021 Apurva Nakade. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Apurva Nakade
5+
-/
6+
import set_theory.surreal.basic
7+
import ring_theory.localization
8+
9+
/-!
10+
# Dyadic numbers
11+
Dyadic numbers are obtained by localizing ℤ away from 2. They are the initial object in the category
12+
of rings with no 2-torsion.
13+
14+
## Dyadic surreal numbers
15+
We construct dyadic surreal numbers using the canonical map from ℤ[2 ^ {-1}] to surreals.
16+
As we currently do not have a ring structure on `surreal` we construct this map explicitly. Once we
17+
have the ring structure, this map can be constructed directly by sending `2 ^ {-1}` to `half`.
18+
19+
## Embeddings
20+
The above construction gives us an abelian group embedding of ℤ into `surreal`. The goal is to
21+
extend this to an embedding of dyadic rationals into `surreal` and use Cauchy sequences of dyadic
22+
rational numbers to construct an ordered field embedding of ℝ into `surreal`.
23+
-/
24+
25+
universes u
26+
27+
local infix ` ≈ ` := pgame.equiv
28+
29+
namespace pgame
30+
31+
/-- For a natural number `n`, the pre-game `pow_half (n + 1)` is recursively defined as
32+
`{ 0 | pow_half n }`. These are the explicit expressions of powers of `half`. By definition, we have
33+
`pow_half 0 = 0` and `pow_half 1 = half` and we prove later on that
34+
`pow_half (n + 1) + pow_half (n + 1) ≈ pow_half n`.-/
35+
def pow_half : ℕ → pgame
36+
| 0 := mk punit pempty 0 pempty.elim
37+
| (n + 1) := mk punit punit 0 (λ _, pow_half n)
38+
39+
@[simp] lemma pow_half_left_moves {n} : (pow_half n).left_moves = punit :=
40+
by cases n; refl
41+
42+
@[simp] lemma pow_half_right_moves {n} : (pow_half (n + 1)).right_moves = punit :=
43+
by cases n; refl
44+
45+
@[simp] lemma pow_half_move_left {n i} : (pow_half n).move_left i = 0 :=
46+
by cases n; cases i; refl
47+
48+
@[simp] lemma pow_half_move_right {n i} : (pow_half (n + 1)).move_right i = pow_half n :=
49+
by cases n; cases i; refl
50+
51+
lemma pow_half_move_left' (n) :
52+
(pow_half n).move_left (equiv.cast (pow_half_left_moves.symm) punit.star) = 0 :=
53+
by simp only [eq_self_iff_true, pow_half_move_left]
54+
55+
lemma pow_half_move_right' (n) :
56+
(pow_half (n + 1)).move_right (equiv.cast (pow_half_right_moves.symm) punit.star) = pow_half n :=
57+
by simp only [pow_half_move_right, eq_self_iff_true]
58+
59+
/-- For all natural numbers `n`, the pre-games `pow_half n` are numeric. -/
60+
theorem numeric_pow_half {n} : (pow_half n).numeric :=
61+
begin
62+
induction n with n hn,
63+
{ exact numeric_one },
64+
{ split,
65+
{ rintro ⟨ ⟩ ⟨ ⟩,
66+
dsimp only [pi.zero_apply],
67+
rw ← pow_half_move_left' n,
68+
apply hn.move_left_lt },
69+
{ exact ⟨λ _, numeric_zero, λ _, hn⟩ } }
70+
end
71+
72+
theorem pow_half_succ_lt_pow_half {n : ℕ} : pow_half (n + 1) < pow_half n :=
73+
(@numeric_pow_half (n + 1)).lt_move_right punit.star
74+
75+
theorem pow_half_succ_le_pow_half {n : ℕ} : pow_half (n + 1) ≤ pow_half n :=
76+
le_of_lt numeric_pow_half numeric_pow_half pow_half_succ_lt_pow_half
77+
78+
theorem zero_lt_pow_half {n : ℕ} : 0 < pow_half n :=
79+
by cases n; rw lt_def_le; use ⟨punit.star, pgame.le_refl 0
80+
81+
theorem zero_le_pow_half {n : ℕ} : 0 ≤ pow_half n :=
82+
le_of_lt numeric_zero numeric_pow_half zero_lt_pow_half
83+
84+
theorem add_pow_half_succ_self_eq_pow_half {n} : pow_half (n + 1) + pow_half (n + 1) ≈ pow_half n :=
85+
begin
86+
induction n with n hn,
87+
{ exact half_add_half_equiv_one },
88+
{ split; rw le_def_lt; split,
89+
{ rintro (⟨⟨ ⟩⟩ | ⟨⟨ ⟩⟩),
90+
{ calc 0 + pow_half (n.succ + 1) ≈ pow_half (n.succ + 1) : zero_add_equiv _
91+
... < pow_half n.succ : pow_half_succ_lt_pow_half },
92+
{ calc pow_half (n.succ + 1) + 0 ≈ pow_half (n.succ + 1) : add_zero_equiv _
93+
... < pow_half n.succ : pow_half_succ_lt_pow_half } },
94+
{ rintro ⟨ ⟩,
95+
rw lt_def_le,
96+
right,
97+
use sum.inl punit.star,
98+
calc pow_half (n.succ) + pow_half (n.succ + 1)
99+
≤ pow_half (n.succ) + pow_half (n.succ) : add_le_add_left pow_half_succ_le_pow_half
100+
... ≈ pow_half n : hn },
101+
{ rintro ⟨ ⟩,
102+
calc 00 + 0 : (add_zero_equiv _).symm
103+
... ≤ pow_half (n.succ + 1) + 0 : add_le_add_right zero_le_pow_half
104+
... < pow_half (n.succ + 1) + pow_half (n.succ + 1) : add_lt_add_left zero_lt_pow_half },
105+
{ rintro (⟨⟨ ⟩⟩ | ⟨⟨ ⟩⟩),
106+
{ calc pow_half n.succ
107+
≈ pow_half n.succ + 0 : (add_zero_equiv _).symm
108+
... < pow_half (n.succ) + pow_half (n.succ + 1) : add_lt_add_left zero_lt_pow_half },
109+
{ calc pow_half n.succ
110+
0 + pow_half n.succ : (zero_add_equiv _).symm
111+
... < pow_half (n.succ + 1) + pow_half (n.succ) : add_lt_add_right zero_lt_pow_half }}}
112+
end
113+
114+
end pgame
115+
116+
namespace surreal
117+
open pgame
118+
119+
/-- The surreal number `half`. -/
120+
def half : surreal := ⟦⟨pgame.half, pgame.numeric_half⟩⟧
121+
122+
/-- Powers of the surreal number `half`. -/
123+
def pow_half (n : ℕ) : surreal := ⟦⟨pgame.pow_half n, pgame.numeric_pow_half⟩⟧
124+
125+
@[simp] lemma pow_half_zero : pow_half 0 = 1 := rfl
126+
127+
@[simp] lemma pow_half_one : pow_half 1 = half := rfl
128+
129+
@[simp] theorem add_half_self_eq_one : half + half = 1 :=
130+
quotient.sound pgame.half_add_half_equiv_one
131+
132+
lemma double_pow_half_succ_eq_pow_half (n : ℕ) : 2 • pow_half n.succ = pow_half n :=
133+
begin
134+
rw two_nsmul,
135+
apply quotient.sound,
136+
exact pgame.add_pow_half_succ_self_eq_pow_half,
137+
end
138+
139+
lemma nsmul_pow_two_pow_half (n : ℕ) : 2 ^ n • pow_half n = 1 :=
140+
begin
141+
induction n with n hn,
142+
{ simp only [nsmul_one, pow_half_zero, nat.cast_one, pow_zero] },
143+
{ rw [← hn, ← double_pow_half_succ_eq_pow_half n, smul_smul (2^n) 2 (pow_half n.succ),
144+
mul_comm, pow_succ] }
145+
end
146+
147+
lemma nsmul_pow_two_pow_half' (n k : ℕ) : 2 ^ n • pow_half (n + k) = pow_half k :=
148+
begin
149+
induction k with k hk,
150+
{ simp only [add_zero, surreal.nsmul_pow_two_pow_half, nat.nat_zero_eq_zero, eq_self_iff_true,
151+
surreal.pow_half_zero] },
152+
{ rw [← double_pow_half_succ_eq_pow_half (n + k), ← double_pow_half_succ_eq_pow_half k,
153+
smul_algebra_smul_comm] at hk,
154+
rwa ← (gsmul_eq_gsmul_iff' two_ne_zero) }
155+
end
156+
157+
lemma nsmul_int_pow_two_pow_half (m : ℤ) (n k : ℕ) :
158+
(m * 2 ^ n) • pow_half (n + k) = m • pow_half k :=
159+
begin
160+
rw mul_gsmul,
161+
congr,
162+
norm_cast,
163+
exact nsmul_pow_two_pow_half' n k,
164+
end
165+
166+
lemma dyadic_aux {m₁ m₂ : ℤ} {y₁ y₂ : ℕ} (h₂ : m₁ * (2 ^ y₁) = m₂ * (2 ^ y₂)) :
167+
m₁ • pow_half y₂ = m₂ • pow_half y₁ :=
168+
begin
169+
revert m₁ m₂,
170+
wlog h : y₁ ≤ y₂,
171+
intros m₁ m₂ h₂,
172+
obtain ⟨c, rfl⟩ := le_iff_exists_add.mp h,
173+
rw [add_comm, pow_add, ← mul_assoc, mul_eq_mul_right_iff] at h₂,
174+
cases h₂,
175+
{ rw [h₂, add_comm, nsmul_int_pow_two_pow_half m₂ c y₁] },
176+
{ have := nat.one_le_pow y₁ 2 nat.succ_pos',
177+
linarith },
178+
end
179+
180+
/-- The map `dyadic_map` sends ⟦⟨m, 2^n⟩⟧ to m • half ^ n. -/
181+
def dyadic_map (x : localization (submonoid.powers (2 : ℤ))) : surreal :=
182+
quotient.lift_on' x (λ x : _ × _, x.1 • pow_half (submonoid.log x.2)) $
183+
begin
184+
rintros ⟨m₁, n₁⟩ ⟨m₂, n₂⟩ h₁,
185+
obtain ⟨⟨n₃, y₃, hn₃⟩, h₂⟩ := localization.r_iff_exists.mp h₁,
186+
simp only [subtype.coe_mk, mul_eq_mul_right_iff] at h₂,
187+
cases h₂,
188+
{ simp only,
189+
obtain ⟨a₁, ha₁⟩ := n₁.prop,
190+
obtain ⟨a₂, ha₂⟩ := n₂.prop,
191+
have hn₁ : n₁ = submonoid.pow 2 a₁ := subtype.ext ha₁.symm,
192+
have hn₂ : n₂ = submonoid.pow 2 a₂ := subtype.ext ha₂.symm,
193+
have h₂ : 1 < (2 : ℤ).nat_abs, from dec_trivial,
194+
rw [hn₁, hn₂, submonoid.log_pow_int_eq_self h₂, submonoid.log_pow_int_eq_self h₂],
195+
apply dyadic_aux,
196+
rwa [ha₁, ha₂] },
197+
{ have := nat.one_le_pow y₃ 2 nat.succ_pos',
198+
linarith }
199+
end
200+
201+
/-- We define dyadic surreals as the range of the map `dyadic_map`. -/
202+
def dyadic : set surreal := set.range dyadic_map
203+
204+
-- We conclude with some ideas for further work on surreals; these would make fun projects.
205+
206+
-- TODO show that the map from dyadic rationals to surreals is a group homomorphism, and injective
207+
208+
-- TODO map the reals into the surreals, using dyadic Dedekind cuts
209+
-- TODO show this is a group homomorphism, and injective
210+
211+
-- TODO show the maps from the dyadic rationals and from the reals
212+
-- into the surreals are multiplicative
213+
214+
end surreal

0 commit comments

Comments
 (0)