Skip to content

feat: sign expansion of surreal#394

Open
plp127 wants to merge 23 commits intovihdzp:masterfrom
plp127:aliu/sur-sign
Open

feat: sign expansion of surreal#394
plp127 wants to merge 23 commits intovihdzp:masterfrom
plp127:aliu/sur-sign

Conversation

@plp127
Copy link
Copy Markdown
Contributor

@plp127 plp127 commented Mar 23, 2026

We define the truncation of a surreal and prove a uniquely characterizing property. We define the sign expansion of a surreal as the sequence of inequalities with its truncations. We prove the birthday of a surreal is the length of its sign sequence, and that the sign sequence of the truncation of a surreal is the truncation of its sign sequence. We show that taking the sign sequence of a surreal defines an order isomorphism with the subset of sign sequences of ordinal length.

Comment thread CombinatorialGames/SignExpansion/Surreal.lean

/-- The truncation of a surreal to an ordinal `o` is the unique surreal `truncate o x`
with `birthday (truncate o x) ≤ o` which compares the same to every `y` with `birthday y < o`. -/
def truncate (o : NatOrdinal.{u}) : Surreal.{u} →o Surreal.{u} where
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The analogous function on sign expansions is called restrict, so maybe this should too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This operation doesn't really feel like "restricting" the surreal, so I wouldn't like this rename.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conversely, should restrict be renamed to truncate? Or maybe trunc to match HahnSeries.trunc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are certainly possibilities

/-- The truncation of a surreal to an ordinal `o` is the unique surreal `truncate o x`
with `birthday (truncate o x) ≤ o` which compares the same to every `y` with `birthday y < o`. -/
def truncate (o : NatOrdinal.{u}) : Surreal.{u} →o Surreal.{u} where
toFun x := @mk !{fun p => {s : IGame.{u} | s.birthday < o} ∩
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it any easier to define truncate o x = !{{y < x| y.birthday < o} | {y > x| y.birthday < o}}? That is, without going through IGame. If not, can we at least have this as a lemma?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's not enough API for inequalities of ofSets in Surreal for this to work easily.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it doesn't work easily, then we should make it work easily! After #402, this works:

def truncate (o : NatOrdinal) : Surreal →o Surreal where
  toFun x := !{Set.Iio x ∩ {y | y.birthday < o} | Set.Ioi x ∩ {y | y.birthday < o}}'(by
    aesop (add apply unsafe [lt_trans])
  )
  monotone' x y hxy := by
    rw [Surreal.ofSets_le_ofSets_iff]
    aesop (add apply unsafe [lt_of_le_of_lt, lt_of_lt_of_le])

Comment thread CombinatorialGames/SignExpansion/Surreal.lean Outdated
Comment thread CombinatorialGames/SignExpansion/Surreal.lean Outdated
Comment thread CombinatorialGames/SignExpansion/Surreal.lean Outdated
apply_eq_zero.2 ((length_ofSurreal _).trans_le (WithTop.coe_le_coe.2
((birthday_truncate_le o₁ x).trans h)))

theorem range_ofSurreal : Set.range ofSurreal.{u} = { f | f.length ≠ ⊤ } := by
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth making a subtype SmallSignExpansion? That way ofSurreal could be an order isomorphism.

Copy link
Copy Markdown
Contributor Author

@plp127 plp127 Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are approximately three things we care about that can be represented as sign expansions:

  • surreals correspond to sign expansions which are eventually 0
  • numeric cuts (something in the range of leftSurreal or rightSurreal) correspond to sign expansions which end in a + followed by all -s or a - followed by all +s
  • short cuts (those with an ordinal birthday) correspond to sign expansions which are either eventually constant + or eventually constant constant -
  • arbitrary cuts correspond to sign expansions without 0s

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think #395 is a good idea? If so, what about defining SignExpansion.toSurreal (x : SignExpansion) (hx : Short x) : Surreal by using this theorem?

plp127 and others added 3 commits March 23, 2026 20:38
Co-authored-by: Violeta Hernández Palacios <vi.hdz.p@gmail.com>
Co-authored-by: Violeta Hernández Palacios <vi.hdz.p@gmail.com>
Comment thread CombinatorialGames/SignExpansion/Surreal.lean
Comment thread CombinatorialGames/SignExpansion/Surreal.lean Outdated
Comment thread CombinatorialGames/SignExpansion/Surreal.lean
Comment thread CombinatorialGames/SignExpansion/Surreal.lean
Comment thread CombinatorialGames/SignExpansion/Surreal.lean Outdated
Comment thread CombinatorialGames/SignExpansion/Surreal.lean Outdated
Comment thread CombinatorialGames/SignExpansion/Surreal.lean
apply_eq_zero.2 ((length_ofSurreal _).trans_le (WithTop.coe_le_coe.2
((birthday_truncate_le o₁ x).trans h)))

theorem range_ofSurreal : Set.range ofSurreal.{u} = { f | f.length ≠ ⊤ } := by
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think #395 is a good idea? If so, what about defining SignExpansion.toSurreal (x : SignExpansion) (hx : Short x) : Surreal by using this theorem?

@vihdzp vihdzp added awaiting-author A reviewer has asked the author a question or requested changes t-surreal This is mainly about surreal numbers labels Mar 26, 2026
plp127 and others added 6 commits March 28, 2026 12:33
@plp127
Copy link
Copy Markdown
Contributor Author

plp127 commented Mar 28, 2026

-awaiting-author

@vihdzp vihdzp removed the awaiting-author A reviewer has asked the author a question or requested changes label Mar 29, 2026
Comment on lines +21 to +32
public theorem ite_lt_iff {α : Type*} [LT α] {P : Prop} [Decidable P] {a b c : α} :
(if P then a else b) < c ↔ P ∧ a < c ∨ ¬P ∧ b < c := by split <;> simp_all

public theorem lt_ite_iff {α : Type*} [LT α] {P : Prop} [Decidable P] {a b c : α} :
a < (if P then b else c) ↔ P ∧ a < b ∨ ¬P ∧ a < c := by split <;> simp_all

public theorem ite_le_iff {α : Type*} [LE α] {P : Prop} [Decidable P] {a b c : α} :
(if P then a else b) ≤ c ↔ P ∧ a ≤ c ∨ ¬P ∧ b ≤ c := by split <;> simp_all

public theorem le_ite_iff {α : Type*} [LE α] {P : Prop} [Decidable P] {a b c : α} :
a ≤ (if P then b else c) ↔ P ∧ a ≤ b ∨ ¬P ∧ a ≤ c := by split <;> simp_all

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are unused now.

Suggested change
public theorem ite_lt_iff {α : Type*} [LT α] {P : Prop} [Decidable P] {a b c : α} :
(if P then a else b) < c ↔ P ∧ a < c ∨ ¬P ∧ b < c := by split <;> simp_all
public theorem lt_ite_iff {α : Type*} [LT α] {P : Prop} [Decidable P] {a b c : α} :
a < (if P then b else c) ↔ P ∧ a < b ∨ ¬P ∧ a < c := by split <;> simp_all
public theorem ite_le_iff {α : Type*} [LE α] {P : Prop} [Decidable P] {a b c : α} :
(if P then a else b) ≤ c ↔ P ∧ a ≤ c ∨ ¬P ∧ b ≤ c := by split <;> simp_all
public theorem le_ite_iff {α : Type*} [LE α] {P : Prop} [Decidable P] {a b c : α} :
a ≤ (if P then b else c) ↔ P ∧ a ≤ b ∨ ¬P ∧ a ≤ c := by split <;> simp_all

import Mathlib.Tactic.Order

/-!
# Sign Expansions
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency

Suggested change
# Sign Expansions
# Sign expansions

/-!
# Sign Expansions

Every surreal number has a sign expansion, a function from its birthday to the set `{-1, 1}`.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The file SignExpansion/Basic already defines what a sign expansion is. This docstring should rather explain how the correspondence works. Maybe something like:

In this file we define the correspondence between surreals and sign expansions. This map can be
uniquely characterized as the order-preserving map such that every surreal gets mapped to a sign
sequence whose length equals its birthday.

Comment on lines +257 to +264
rw [lt_iff_toLex]
have hdcc (d : Surreal) (hd : d.birthday < c.birthday) : d ∉ Set.Icc x y := by
contrapose! hd
apply Cut.birthday_simplestBtwn_le_of_fits
exact hd
have hcxy (j : NatOrdinal) (hj : j ≤ c.birthday)
(z : Surreal) (hz : z ∈ Set.Icc x y) : z.truncate j = c.truncate j := by
apply truncate_eq_of_birthday_le_of_forall_lt_gt_iff (birthday_truncate_le j c) <;> grind
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I meant, makes more sense to me to have all the haves together.

Suggested change
rw [lt_iff_toLex]
have hdcc (d : Surreal) (hd : d.birthday < c.birthday) : d ∉ Set.Icc x y := by
contrapose! hd
apply Cut.birthday_simplestBtwn_le_of_fits
exact hd
have hcxy (j : NatOrdinal) (hj : j ≤ c.birthday)
(z : Surreal) (hz : z ∈ Set.Icc x y) : z.truncate j = c.truncate j := by
apply truncate_eq_of_birthday_le_of_forall_lt_gt_iff (birthday_truncate_le j c) <;> grind
have hdcc (d : Surreal) (hd : d.birthday < c.birthday) : d ∉ Set.Icc x y := by
contrapose! hd
apply Cut.birthday_simplestBtwn_le_of_fits
exact hd
have hcxy (j : NatOrdinal) (hj : j ≤ c.birthday)
(z : Surreal) (hz : z ∈ Set.Icc x y) : z.truncate j = c.truncate j := by
apply truncate_eq_of_birthday_le_of_forall_lt_gt_iff (birthday_truncate_le j c) <;> grind
rw [lt_iff_toLex]

/-- The truncation of a surreal to an ordinal `o` is the unique surreal `truncate o x`
with `birthday (truncate o x) ≤ o` which compares the same to every `y` with `birthday y < o`. -/
def truncate (o : NatOrdinal.{u}) : Surreal.{u} →o Surreal.{u} where
toFun x := @mk !{fun p => {s : IGame.{u} | s.birthday < o} ∩
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it doesn't work easily, then we should make it work easily! After #402, this works:

def truncate (o : NatOrdinal) : Surreal →o Surreal where
  toFun x := !{Set.Iio x ∩ {y | y.birthday < o} | Set.Ioi x ∩ {y | y.birthday < o}}'(by
    aesop (add apply unsafe [lt_trans])
  )
  monotone' x y hxy := by
    rw [Surreal.ofSets_le_ofSets_iff]
    aesop (add apply unsafe [lt_of_le_of_lt, lt_of_lt_of_le])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-surreal This is mainly about surreal numbers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants