mathlib documentation

set_theory.surreal

Surreal numbers #

The basic theory of surreal numbers, built on top of the theory of combinatorial (pre-)games.

A pregame is numeric if all the Left options are strictly smaller than all the Right options, and all those options are themselves numeric. In terms of combinatorial games, the numeric games have "frozen"; you can only make your position worse by playing, and Left is some definite "number" of moves ahead (or behind) Right.

A surreal number is an equivalence class of numeric pregames.

In fact, the surreals form a complete ordered field, containing a copy of the reals (and much else besides!) but we do not yet have a complete development.

Order properties #

Surreal numbers inherit the relations and < from games, and these relations satisfy the axioms of a partial order (recall that x < y ↔ x ≤ y ∧ ¬ y ≤ x did not hold for games).

Algebraic operations #

At this point, we have defined addition and negation (from pregames), and shown that surreals form an additive semigroup. It would be very little work to finish showing that the surreals form an ordered commutative group.

We define the operations of multiplication and inverse on surreals, but do not yet establish any of the necessary properties to show the surreals form an ordered field.

Embeddings #

It would be nice projects to define the group homomorphism surrealgame, and also ℤ → surreal, and then the homomorphic inclusion of the dyadic rationals into surreals, and finally via dyadic Dedekind cuts the homomorphic inclusion of the reals into the surreals.

One can also map all the ordinals into the surreals!

References #

Multiplicative operations can be defined at the level of pre-games, but as they are only useful on surreal numbers, we define them here.

def pgame.mul (x : pgame) (y : pgame) :

The product of x = {xL | xR} and y = {yL | yR} is {xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }.

Equations
  • x.mul y = pgame.rec (λ (xl xr : Type u_1) (xL : xl → pgame) (xR : xr → pgame) (IHxl : Π (ᾰ : xl), (λ (x : pgame), pgamepgame) (xL ᾰ)) (IHxr : Π (ᾰ : xr), (λ (x : pgame), pgamepgame) (xR ᾰ)) (y : pgame), pgame.rec (λ (yl yr : Type u_2) (yL : yl → pgame) (yR : yr → pgame) (IHyl : Π (ᾰ : yl), (λ (y : pgame), pgame) (yL ᾰ)) (IHyr : Π (ᾰ : yr), (λ (y : pgame), pgame) (yR ᾰ)), pgame.mk (xl × yl xr × yr) (xl × yr xr × yl) (λ (ᾰ : xl × yl xr × yr), ᾰ.cases_on (λ (ᾰ : xl × yl), ᾰ.cases_on (λ (i : xl) (j : yl), IHxl i (pgame.mk yl yr yL yR) + IHyl j - IHxl i (yL j))) (λ (ᾰ : xr × yr), ᾰ.cases_on (λ (i : xr) (j : yr), IHxr i (pgame.mk yl yr yL yR) + IHyr j - IHxr i (yR j)))) (λ (ᾰ : xl × yr xr × yl), ᾰ.cases_on (λ (ᾰ : xl × yr), ᾰ.cases_on (λ (i : xl) (j : yr), IHxl i (pgame.mk yl yr yL yR) + IHyr j - IHxl i (yR j))) (λ (ᾰ : xr × yl), ᾰ.cases_on (λ (i : xr) (j : yl), IHxr i (pgame.mk yl yr yL yR) + IHyl j - IHxr i (yL j))))) y) x y
@[protected, instance]
Equations

An explicit description of the moves for Left in x * y.

Equations

An explicit description of the moves for Right in x * y.

Equations
@[simp]
theorem pgame.mk_mul_move_left_inl {xl xr yl yr : Type u_1} {xL : xl → pgame} {xR : xr → pgame} {yL : yl → pgame} {yR : yr → pgame} {i : xl} {j : yl} :
((pgame.mk xl xr xL xR) * pgame.mk yl yr yL yR).move_left (sum.inl (i, j)) = (xL i) * pgame.mk yl yr yL yR + (pgame.mk xl xr xL xR) * yL j - (xL i) * yL j
@[simp]
theorem pgame.mul_move_left_inl {x y : pgame} {i : x.left_moves} {j : y.left_moves} :
(x * y).move_left (((x.left_moves_mul y).symm) (sum.inl (i, j))) = (x.move_left i) * y + x * y.move_left j - (x.move_left i) * y.move_left j
@[simp]
theorem pgame.mk_mul_move_left_inr {xl xr yl yr : Type u_1} {xL : xl → pgame} {xR : xr → pgame} {yL : yl → pgame} {yR : yr → pgame} {i : xr} {j : yr} :
((pgame.mk xl xr xL xR) * pgame.mk yl yr yL yR).move_left (sum.inr (i, j)) = (xR i) * pgame.mk yl yr yL yR + (pgame.mk xl xr xL xR) * yR j - (xR i) * yR j
@[simp]
theorem pgame.mul_move_left_inr {x y : pgame} {i : x.right_moves} {j : y.right_moves} :
(x * y).move_left (((x.left_moves_mul y).symm) (sum.inr (i, j))) = (x.move_right i) * y + x * y.move_right j - (x.move_right i) * y.move_right j
@[simp]
theorem pgame.mk_mul_move_right_inl {xl xr yl yr : Type u_1} {xL : xl → pgame} {xR : xr → pgame} {yL : yl → pgame} {yR : yr → pgame} {i : xl} {j : yr} :
((pgame.mk xl xr xL xR) * pgame.mk yl yr yL yR).move_right (sum.inl (i, j)) = (xL i) * pgame.mk yl yr yL yR + (pgame.mk xl xr xL xR) * yR j - (xL i) * yR j
@[simp]
theorem pgame.mul_move_right_inl {x y : pgame} {i : x.left_moves} {j : y.right_moves} :
(x * y).move_right (((x.right_moves_mul y).symm) (sum.inl (i, j))) = (x.move_left i) * y + x * y.move_right j - (x.move_left i) * y.move_right j
@[simp]
theorem pgame.mk_mul_move_right_inr {xl xr yl yr : Type u_1} {xL : xl → pgame} {xR : xr → pgame} {yL : yl → pgame} {yR : yr → pgame} {i : xr} {j : yl} :
((pgame.mk xl xr xL xR) * pgame.mk yl yr yL yR).move_right (sum.inr (i, j)) = (xR i) * pgame.mk yl yr yL yR + (pgame.mk xl xr xL xR) * yL j - (xR i) * yL j
@[simp]
theorem pgame.mul_move_right_inr {x y : pgame} {i : x.right_moves} {j : y.left_moves} :
(x * y).move_right (((x.right_moves_mul y).symm) (sum.inr (i, j))) = (x.move_right i) * y + x * y.move_left j - (x.move_right i) * y.move_left j
def pgame.add_sub_relabelling {a b c x y z : pgame} (h₁ : a.relabelling x) (h₂ : b.relabelling y) (h₃ : c.relabelling z) :
(a + b - c).relabelling (x + y - z)

If a has the same moves as x, b has the same moves as y, and c has the same moves as z, then a + b - c has the same moves as x + y - z. This lemma is repeatedly used for simplifying multiplication of surreal numbers.

Equations
def pgame.add_comm_sub_relabelling {a b c x y z : pgame} (h₁ : a.relabelling x) (h₂ : b.relabelling y) (h₃ : c.relabelling z) :
(a + b - c).relabelling (y + x - z)

If a has the same moves as x, b has the same moves as y, and c has the same moves as z, then a + b - c has the same moves as y + x - z. This lemma is repeatedly used for simplifying multiplication of surreal numbers.

Equations
def pgame.mul_comm_relabelling (x y : pgame) :
(x * y).relabelling (y * x)

x * y has exactly the same moves as y * x.

Equations
theorem pgame.mul_comm_equiv (x y : pgame) :
(x * y).equiv (y * x)

x * y is equivalent to y * x.

x * 0 has exactly the same moves as 0.

Equations
theorem pgame.mul_zero_equiv (x : pgame) :
(x * 0).equiv 0

x * 0 is equivalent to 0.

0 * x has exactly the same moves as 0.

Equations
theorem pgame.zero_mul_equiv (x : pgame) :
(0 * x).equiv 0

0 * x is equivalent to 0.

inductive pgame.inv_ty (l r : Type u) :
boolType u

Because the two halves of the definition of inv produce more elements of each side, we have to define the two families inductively. This is the indexing set for the function, and inv_val is the function part.

def pgame.inv_val {l r : Type u_1} (L : l → pgame) (R : r → pgame) (IHl : l → pgame) (IHr : r → pgame) {b : bool} :

Because the two halves of the definition of inv produce more elements of each side, we have to define the two families inductively. This is the function part, defined by recursion on inv_ty.

Equations
def pgame.inv'  :

The inverse of a positive surreal number x = {L | R} is given by x⁻¹ = {0, (1 + (R - x) * x⁻¹L) * R, (1 + (L - x) * x⁻¹R) * L | (1 + (L - x) * x⁻¹L) * L, (1 + (R - x) * x⁻¹R) * R}. Because the two halves x⁻¹L, x⁻¹R of x⁻¹ are used in their own definition, the sets and elements are inductively generated.

Equations
def pgame.inv (x : pgame) :

The inverse of a surreal number in terms of the inverse on positive surreals.

Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
def pgame.numeric  :
pgame → Prop

A pre-game is numeric if everything in the L set is less than everything in the R set, and all the elements of L and R are also numeric.

Equations
theorem pgame.numeric.move_left {x : pgame} (o : x.numeric) (i : x.left_moves) :
theorem pgame.numeric.move_right {x : pgame} (o : x.numeric) (j : x.right_moves) :
theorem pgame.numeric_rec {C : pgame → Prop} (H : ∀ (l r : Type u_1) (L : l → pgame) (R : r → pgame), (∀ (i : l) (j : r), L i < R j)(∀ (i : l), (L i).numeric)(∀ (i : r), (R i).numeric)(∀ (i : l), C (L i))(∀ (i : r), C (R i))C (pgame.mk l r L R)) (x : pgame) :
x.numericC x
theorem pgame.lt_asymm {x y : pgame} (ox : x.numeric) (oy : y.numeric) :
x < y¬y < x
theorem pgame.le_of_lt {x y : pgame} (ox : x.numeric) (oy : y.numeric) (h : x < y) :
x y
theorem pgame.lt_iff_le_not_le {x y : pgame} (ox : x.numeric) (oy : y.numeric) :
x < y x y ¬y x

On numeric pre-games, < and satisfy the axioms of a partial order (even though they don't on all pre-games).

theorem pgame.numeric_neg {x : pgame} (o : x.numeric) :
theorem pgame.numeric.move_left_lt {x : pgame} (o : x.numeric) (i : x.left_moves) :
x.move_left i < x
theorem pgame.numeric.move_left_le {x : pgame} (o : x.numeric) (i : x.left_moves) :
theorem pgame.numeric.lt_move_right {x : pgame} (o : x.numeric) (j : x.right_moves) :
theorem pgame.numeric.le_move_right {x : pgame} (o : x.numeric) (j : x.right_moves) :
theorem pgame.add_lt_add {w x y z : pgame} (ow : w.numeric) (ox : x.numeric) (oy : y.numeric) (oz : z.numeric) (hwx : w < x) (hyz : y < z) :
w + y < x + z
theorem pgame.numeric_add {x y : pgame} (ox : x.numeric) (oy : y.numeric) :
(x + y).numeric
theorem pgame.numeric_nat (n : ) :

Pre-games defined by natural numbers are numeric.

The pre-game omega is numeric.

def surreal.equiv (x y : {x // x.numeric}) :
Prop

The equivalence on numeric pre-games.

Equations
@[protected, instance]
def surreal.setoid  :
setoid {x // x.numeric}
Equations
def surreal  :
Type (u_1+1)

The type of surreal numbers. These are the numeric pre-games quotiented by the equivalence relation x ≈ y ↔ x ≤ y ∧ y ≤ x. In the quotient, the order becomes a total order.

Equations
def surreal.mk (x : pgame) (h : x.numeric) :

Construct a surreal number from a numeric pre-game.

Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
def surreal.lift {α : Sort u_1} (f : Π (x : pgame), x.numeric → α) (H : ∀ {x y : pgame} (hx : x.numeric) (hy : y.numeric), x.equiv yf x hx = f y hy) :
surreal → α

Lift an equivalence-respecting function on pre-games to surreals.

Equations
def surreal.lift₂ {α : Sort u_1} (f : Π (x : pgame) (y : pgame), x.numericy.numeric → α) (H : ∀ {x₁ : pgame} {y₁ : pgame} {x₂ : pgame} {y₂ : pgame} (ox₁ : x₁.numeric) (oy₁ : y₁.numeric) (ox₂ : x₂.numeric) (oy₂ : y₂.numeric), x₁.equiv x₂y₁.equiv y₂f x₁ y₁ ox₁ oy₁ = f x₂ y₂ ox₂ oy₂) :
surrealsurreal → α

Lift a binary equivalence-respecting function on pre-games to surreals.

Equations
def surreal.le  :
surrealsurreal → Prop

The relation x ≤ y on surreals.

Equations
def surreal.lt  :
surrealsurreal → Prop

The relation x < y on surreals.

Equations
theorem surreal.not_le {x y : surreal} :
¬x.le y y.lt x

Addition on surreals is inherited from pre-game addition: the sum of x = {xL | xR} and y = {yL | yR} is {xL + y, x + yL | xR + y, x + yR}.

Equations

Negation for surreal numbers is inherited from pre-game negation: the negation of {L | R} is {-R | -L}.

Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations
@[protected, instance]
Equations