Documentation

CombinatorialGames.Game.Impartial.Grundy

Grundy value #

The Grundy value of an impartial game is recursively defined as the least nimber not among the Grundy values of either its left or right options. This map respects addition and multiplication.

We provide three definitions for the Grundy value. leftGrundy and rightGrundy are computed using the left/right options of the game respectively, and are defined for all games. To make the API symmetric, we also provide Impartial.grundy, which enforces that the game is impartial, and is thus equal to either of leftGrundy or rightGrundy.

The Sprague-Grundy theorem nim_grundy_equiv shows that any impartial game is equivalent to a game of Nim, namely that corresponding to its Grundy value.

Grundy value #

@[irreducible]

The left Grundy value of a game is recursively defined as the minimum excluded value (the infimum of the complement) of the left Grundy values of its left options.

This is an auxiliary definition for reasoning about games not yet known to be impartial. Use Impartial.grundy for an impartial game.

Equations
Instances For
    @[simp, irreducible]
    @[irreducible]

    The right Grundy value of a game is recursively defined as the minimum excluded value (the infimum of the complement) of the right Grundy values of its right options.

    This is an auxiliary definition for reasoning about games not yet known to be impartial. Use Impartial.grundy for an impartial game.

    Equations
    Instances For
      @[simp, irreducible]

      The Grundy value of an impartial game is recursively defined as the minimum excluded value (the infimum of the complement) of the Grundy values of its options.

      This definition enforces that x is impartial. If you want to talk about the left or right Grundy values of a game (e.g. if you don't yet know it to be impartial), use leftGrundy or rightGrundy. The lemmas leftGrundy_eq_grundy and rightGrundy_eq_grundy show that both definitions match in the case of an impartial game.

      Equations
      Instances For
        @[irreducible]

        The Sprague-Grundy theorem states that every impartial game is equivalent to a game of nim, namely the game of nim for the game's Grundy value.

        theorem IGame.Impartial.grundy_eq {x : IGame} [x.Impartial] {o : Nimber} :
        xnim ogrundy x = o

        Alias of the reverse direction of IGame.Impartial.grundy_eq_iff_equiv_nim.

        @[simp]
        @[simp]
        theorem IGame.nim_add_equiv (a b : Nimber) :
        nim a + nim bnim (a + b)
        theorem IGame.Impartial.grundy_leftMove_ne {x y : IGame} [x.Impartial] (hy : y x.leftMoves) :
        have this := ; grundy y grundy x
        theorem IGame.Impartial.grundy_rightMove_ne {x y : IGame} [x.Impartial] (hy : y x.rightMoves) :
        have this := ; grundy y grundy x
        theorem IGame.Impartial.lt_of_numeric_of_pos (x : IGame) [x.Impartial] {y : IGame} [y.Numeric] (hy : 0 < y) :
        x < y

        One half of the lawnmower theorem for impartial games.

        theorem IGame.Impartial.lt_of_numeric_of_neg (x : IGame) [x.Impartial] {y : IGame} [y.Numeric] (hy : y < 0) :
        y < x

        One half of the lawnmower theorem for impartial games.

        theorem IGame.Impartial.of_leftGrundy_eq_rightGrundy {x : IGame} (hl : yx.leftMoves, y.Impartial) (hr : yx.rightMoves, y.Impartial) (H : x.leftGrundy = x.rightGrundy) :

        If a game x has only impartial options, and its left Grundy value equals its right Grundy value, then it's impartial.

        Multiplication #

        @[simp]
        theorem IGame.nim_mul_equiv (a b : Nimber) :
        nim a * nim bnim (a * b)
        theorem IGame.Impartial.mul_equiv_zero {x y : IGame} [x.Impartial] [y.Impartial] :
        x * y0 x0 y0
        theorem IGame.Impartial.mul_congr_left {x₁ x₂ y : IGame} [x₁.Impartial] [x₂.Impartial] [y.Impartial] (he : x₁x₂) :
        x₁ * yx₂ * y
        theorem IGame.Impartial.mul_congr_right {x y₁ y₂ : IGame} [x.Impartial] [y₁.Impartial] [y₂.Impartial] (he : y₁y₂) :
        x * y₁x * y₂
        theorem IGame.Impartial.mul_congr {x₁ x₂ y₁ y₂ : IGame} [x₁.Impartial] [x₂.Impartial] [y₁.Impartial] [y₂.Impartial] (hx : x₁x₂) (hy : y₁y₂) :
        x₁ * y₁x₂ * y₂