Documentation

CombinatorialGames.Surreal.Dyadic

Dyadic games #

A combinatorial game that is both Short and Numeric is called dyadic. We show that the dyadic games are in correspondence with the Dyadic rationals, in the sense that there exists a map Dyadic.toIGame such that:

Future projects #

Since dyadic rationals are easy to do computations with, there are some projects we could pursue in the future:

Upper and lower dyadic fractions #

For a dyadic number m / n, returns (m - 1) / n.

Equations
Instances For

    For a dyadic number m / n, returns (m + 1) / n.

    Equations
    Instances For
      theorem Dyadic.den_lower_lt {x : Dyadic} (h : x.den ≠ 1) :
      theorem Dyadic.den_upper_lt {x : Dyadic} (h : x.den ≠ 1) :

      An auxiliary tactic for inducting on the denominator of a Dyadic.

      Equations
      Instances For
        @[simp]
        theorem Dyadic.lower_neg (x : Dyadic) :
        @[simp]
        theorem Dyadic.upper_neg (x : Dyadic) :
        theorem Dyadic.le_lower_of_lt {x y : Dyadic} (hd : x.den ≤ y.den) (h : x < y) :
        theorem Dyadic.upper_le_of_lt {x y : Dyadic} (hd : y.den ≤ x.den) (h : x < y) :
        theorem Dyadic.lower_eq_of_den_eq_one {x : Dyadic} (h : x.den = 1) :
        x.lower = ↑x.num - 1
        theorem Dyadic.upper_eq_of_den_eq_one {x : Dyadic} (h : x.den = 1) :
        x.upper = ↑x.num + 1
        @[simp]
        theorem Dyadic.lower_lt (x : Dyadic) :
        x.lower < x
        @[simp]
        theorem Dyadic.lt_upper (x : Dyadic) :
        x < x.upper
        theorem Dyadic.coe_lower (x : Dyadic) :
        ↑x.lower = ↑x - (↑x.den)⁻¹
        theorem Dyadic.coe_upper (x : Dyadic) :
        ↑x.upper = ↑x + (↑x.den)⁻¹
        theorem Dyadic.lower_add_le_of_den_le {x y : Dyadic} (h : x.den ≤ y.den) :
        (x + y).lower ≤ x + y.lower
        theorem Dyadic.lower_add_le_of_den_ge {x y : Dyadic} (h : y.den ≤ x.den) :
        (x + y).lower ≤ x.lower + y
        theorem Dyadic.le_upper_add_of_den_le {x y : Dyadic} (h : x.den ≤ y.den) :
        x + y.upper ≤ (x + y).upper
        theorem Dyadic.le_upper_add_of_den_ge {x y : Dyadic} (h : y.den ≤ x.den) :
        x.upper + y ≤ (x + y).upper

        Dyadic numbers to games #

        @[irreducible]
        noncomputable def Dyadic.toIGame (x : Dyadic) :

        Converts a dyadic rational into an IGame. This map is defined so that:

        • If x : ℤ, then toIGame x = ↑x.
        • Otherwise, if x = m / n with n even, then toIGame x = !{(m - 1) / n | (m + 1) / n}. Note that both options will have smaller denominators.
        Equations
        Instances For
          @[instance_reducible]
          noncomputable instance Dyadic.instCoeIGame :
          Equations
          theorem Dyadic.toIGame_of_den_eq_one {x : Dyadic} (hx : x.den = 1) :
          ↑x = ↑x.num
          @[simp]
          theorem Dyadic.toIGame_intCast (n : ℤ) :
          ↑↑n = ↑n
          @[simp]
          theorem Dyadic.toIGame_natCast (n : ℕ) :
          ↑↑n = ↑n
          @[simp]
          theorem Dyadic.toIGame_zero :
          ↑0 = 0
          @[simp]
          theorem Dyadic.toIGame_one :
          ↑1 = 1
          theorem Dyadic.toIGame_of_den_ne_one {x : Dyadic} (hx : x.den ≠ 1) :
          ↑x = !{{↑x.lower} | {↑x.upper}}
          @[simp]
          @[simp]
          theorem Dyadic.toIGame_neg (x : Dyadic) :
          ↑(-x) = -↑x
          theorem Dyadic.toIGame_equiv_lower_upper (x : Dyadic) :
          ↑x ≈ !{{↑x.lower} | {↑x.upper}}

          A dyadic number x is always equivalent to !{lower x | upper x}, though this may not necessarily be the canonical form.

          @[irreducible]
          instance IGame.Short.dyadic (x : Dyadic) :
          (↑x).Short
          @[irreducible]
          instance IGame.Numeric.dyadic (x : Dyadic) :
          (↑x).Numeric
          @[simp]
          theorem Dyadic.toIGame_le_toIGame {x y : Dyadic} :
          ↑x ≤ ↑y ↔ x ≤ y
          @[simp]
          theorem Dyadic.toIGame_lt_toIGame {x y : Dyadic} :
          ↑x < ↑y ↔ x < y
          @[simp]
          theorem Dyadic.toIGame_equiv_toIGame {x y : Dyadic} :
          ↑x ≈ ↑y ↔ x = y
          @[simp]
          theorem Dyadic.toIGame_inj {x y : Dyadic} :
          ↑x = ↑y ↔ x = y
          theorem Dyadic.toIGame_add_equiv (x y : Dyadic) :
          ↑(x + y) ≈ ↑x + ↑y
          theorem Dyadic.toIGame_sub_equiv (x y : Dyadic) :
          ↑(x - y) ≈ ↑x - ↑y
          theorem Dyadic.toIGame_equiv (x : Dyadic) :
          ↑x ≈ ↑↑x
          @[simp]
          theorem Game.mk_dyadic (x : Dyadic) :
          mk ↑x = ↑↑x
          @[simp]
          theorem Surreal.mk_dyadic (x : Dyadic) :
          mk ↑x = ↑↑x
          theorem Dyadic.toIGame_mul_equiv (x y : Dyadic) :
          ↑(x * y) ≈ ↑x * ↑y

          Simp lemmas #

          ℚ #

          @[simp]
          theorem Dyadic.toIGame_lt_ratCast {x : Dyadic} {y : ℚ} :
          ↑x < ↑y ↔ ↑x < y
          @[simp]
          theorem Dyadic.toIGame_le_ratCast {x : Dyadic} {y : ℚ} :
          ↑x ≤ ↑y ↔ ↑x ≤ y
          @[simp]
          theorem Dyadic.ratCast_lt_toIGame {x : ℚ} {y : Dyadic} :
          ↑x < ↑y ↔ x < ↑y
          @[simp]
          theorem Dyadic.ratCast_le_toIGame {x : ℚ} {y : Dyadic} :
          ↑x ≤ ↑y ↔ x ≤ ↑y
          @[simp]
          theorem Dyadic.toIGame_equiv_ratCast {x : Dyadic} {y : ℚ} :
          ↑x ≈ ↑y ↔ ↑x = y
          @[simp]
          theorem Dyadic.ratCast_equiv_toIGame {x : ℚ} {y : Dyadic} :
          ↑x ≈ ↑y ↔ x = ↑y

          ℤ #

          @[simp]
          theorem Dyadic.toIGame_lt_intCast {x : Dyadic} {y : ℤ} :
          ↑x < ↑y ↔ x < ↑y
          @[simp]
          theorem Dyadic.toIGame_le_intCast {x : Dyadic} {y : ℤ} :
          ↑x ≤ ↑y ↔ x ≤ ↑y
          @[simp]
          theorem Dyadic.intCast_lt_toIGame {x : ℤ} {y : Dyadic} :
          ↑x < ↑y ↔ ↑x < y
          @[simp]
          theorem Dyadic.intCast_le_toIGame {x : ℤ} {y : Dyadic} :
          ↑x ≤ ↑y ↔ ↑x ≤ y
          @[simp]
          theorem Dyadic.toIGame_equiv_intCast {x : Dyadic} {y : ℤ} :
          ↑x ≈ ↑y ↔ x = ↑y
          @[simp]
          theorem Dyadic.intCast_equiv_toIGame {x : ℤ} {y : Dyadic} :
          ↑x ≈ ↑y ↔ ↑x = y
          @[simp]
          theorem Dyadic.toIGame_eq_intCast {x : Dyadic} {y : ℤ} :
          ↑x = ↑y ↔ x = ↑y
          @[simp]
          theorem Dyadic.intCast_eq_toIGame {x : ℤ} {y : Dyadic} :
          ↑x = ↑y ↔ ↑x = y

          ℕ #

          @[simp]
          theorem Dyadic.toIGame_lt_natCast {x : Dyadic} {y : ℕ} :
          ↑x < ↑y ↔ x < ↑y
          @[simp]
          theorem Dyadic.toIGame_le_natCast {x : Dyadic} {y : ℕ} :
          ↑x ≤ ↑y ↔ x ≤ ↑y
          @[simp]
          theorem Dyadic.natCast_lt_toIGame {x : ℕ} {y : Dyadic} :
          ↑x < ↑y ↔ ↑x < y
          @[simp]
          theorem Dyadic.natCast_le_toIGame {x : ℕ} {y : Dyadic} :
          ↑x ≤ ↑y ↔ ↑x ≤ y
          @[simp]
          theorem Dyadic.toIGame_equiv_natCast {x : Dyadic} {y : ℕ} :
          ↑x ≈ ↑y ↔ x = ↑y
          @[simp]
          theorem Dyadic.natCast_equiv_toIGame {x : ℕ} {y : Dyadic} :
          ↑x ≈ ↑y ↔ ↑x = y
          @[simp]
          theorem Dyadic.toIGame_eq_natCast {x : Dyadic} {y : ℕ} :
          ↑x = ↑y ↔ x = ↑y
          @[simp]
          theorem Dyadic.natCast_eq_toIGame {x : ℕ} {y : Dyadic} :
          ↑x = ↑y ↔ ↑x = y

          0 #

          @[simp]
          theorem Dyadic.toIGame_lt_zero {x : Dyadic} :
          ↑x < 0 ↔ x < 0
          @[simp]
          theorem Dyadic.toIGame_le_zero {x : Dyadic} :
          ↑x ≤ 0 ↔ x ≤ 0
          @[simp]
          theorem Dyadic.zero_lt_toIGame {x : Dyadic} :
          0 < ↑x ↔ 0 < x
          @[simp]
          theorem Dyadic.zero_le_toIGame {x : Dyadic} :
          0 ≤ ↑x ↔ 0 ≤ x
          @[simp]
          theorem Dyadic.toIGame_equiv_zero {x : Dyadic} :
          ↑x ≈ 0 ↔ x = 0
          @[simp]
          theorem Dyadic.zero_equiv_toIGame {x : Dyadic} :
          0 ≈ ↑x ↔ 0 = x
          @[simp]
          theorem Dyadic.toIGame_eq_zero {x : Dyadic} :
          ↑x = 0 ↔ x = 0
          @[simp]
          theorem Dyadic.zero_eq_toIGame {x : Dyadic} :
          0 = ↑x ↔ 0 = x

          1 #

          @[simp]
          theorem Dyadic.toIGame_lt_one {x : Dyadic} :
          ↑x < 1 ↔ x < 1
          @[simp]
          theorem Dyadic.toIGame_le_one {x : Dyadic} :
          ↑x ≤ 1 ↔ x ≤ 1
          @[simp]
          theorem Dyadic.one_lt_toIGame {x : Dyadic} :
          1 < ↑x ↔ 1 < x
          @[simp]
          theorem Dyadic.one_le_toIGame {x : Dyadic} :
          1 ≤ ↑x ↔ 1 ≤ x
          @[simp]
          theorem Dyadic.toIGame_equiv_one {x : Dyadic} :
          ↑x ≈ 1 ↔ x = 1
          @[simp]
          theorem Dyadic.one_equiv_toIGame {x : Dyadic} :
          1 ≈ ↑x ↔ 1 = x
          @[simp]
          theorem Dyadic.toIGame_eq_one {x : Dyadic} :
          ↑x = 1 ↔ x = 1
          @[simp]
          theorem Dyadic.one_eq_toIGame {x : Dyadic} :
          1 = ↑x ↔ 1 = x

          Dyadic games as numbers #

          noncomputable def IGame.toDyadic (x : IGame) [x.Short] [x.Numeric] :

          Any dyadic game (meaning a game that is Short and Numeric) is equivalent to a Dyadic rational number.

          TODO: it should be possible to compute this value explicitly, given the finsets of Dyadic rationals corresponding to the left and right moves.

          Equations
          Instances For
            @[simp]
            theorem IGame.equiv_toIGame_toDyadic (x : IGame) [x.Short] [x.Numeric] :
            x ≈ ↑x.toDyadic
            @[simp]
            theorem IGame.toIGame_toDyadic_equiv (x : IGame) [x.Short] [x.Numeric] :
            ↑x.toDyadic ≈ x
            @[simp]
            theorem Game.ratCast_toDyadic (x : IGame) [x.Short] [x.Numeric] :
            ↑↑x.toDyadic = mk x
            @[simp]
            theorem Surreal.ratCast_toDyadic (x : IGame) [x.Short] [x.Numeric] :
            ↑↑x.toDyadic = mk x
            theorem IGame.equiv_toIGame_iff_toDyadic_eq {x : IGame} [x.Short] [x.Numeric] {y : Dyadic} :
            x ≈ ↑y ↔ x.toDyadic = y
            theorem IGame.toIGame_equiv_iff_eq_toDyadic {x : IGame} [x.Short] [x.Numeric] {y : Dyadic} :
            ↑y ≈ x ↔ y = x.toDyadic
            @[simp]
            theorem IGame.toDyadic_toIGame (x : Dyadic) :
            (↑x).toDyadic = x
            @[simp]
            @[simp]
            @[simp]
            theorem IGame.toDyadic_natCast (n : ℕ) :
            (↑n).toDyadic = ↑n
            @[simp]
            @[simp]
            theorem IGame.toDyadic_intCast (n : ℤ) :
            (↑n).toDyadic = ↑n
            @[simp]
            @[simp]
            theorem IGame.toDyadic_add (x y : IGame) [x.Short] [x.Numeric] [y.Short] [y.Numeric] :
            @[simp]
            theorem IGame.toDyadic_sub (x y : IGame) [x.Short] [x.Numeric] [y.Short] [y.Numeric] :
            @[simp]
            theorem IGame.toDyadic_mul (x y : IGame) [x.Short] [x.Numeric] [y.Short] [y.Numeric] :