Documentation

CombinatorialGames.Game.Impartial

Basic definitions about impartial games #

We will define an impartial game, one in which left and right can make exactly the same moves. Our definition differs slightly by saying that the game is always equivalent to its negative, no matter what moves are played. This allows for games such as poker-nim to be classified as impartial.

An impartial game is one that's equivalent to its negative, such that each left and right move is also impartial.

Note that this is a slightly more general definition than the one that's usually in the literature, as we don't require x = -x. Despite this, the Sprague-Grundy theorem still holds: see IGame.equiv_nim_grundyValue.

In such a game, both players have the same payoffs at any subposition.

Instances
    theorem IGame.impartial_def {x : IGame} :
    x.Impartial -xx (∀ ix.leftMoves, i.Impartial) jx.rightMoves, j.Impartial
    @[simp]
    theorem IGame.Impartial.neg_equiv (x : IGame) [hx : x.Impartial] :
    -xx
    @[simp]
    theorem IGame.Impartial.equiv_neg (x : IGame) [hx : x.Impartial] :
    x-x
    @[simp]
    @[simp]
    @[irreducible]
    @[irreducible]
    instance IGame.Impartial.add (x y : IGame) [x.Impartial] [y.Impartial] :
    (x + y).Impartial
    @[simp]
    theorem IGame.Impartial.not_lt (x y : IGame) [hx : x.Impartial] [hy : y.Impartial] :
    ¬x < y
    theorem IGame.Impartial.equiv_or_fuzzy (x y : IGame) [hx : x.Impartial] [hy : y.Impartial] :
    xy xy

    By setting y = 0, we find that in an impartial game, either the first player always wins, or the second player always wins.

    theorem IGame.Impartial.equiv_iff_add_equiv_zero (y : IGame) [hy : y.Impartial] (x : IGame) :
    xy x + y0

    This lemma doesn't require x to be impartial.

    theorem IGame.Impartial.equiv_iff_add_equiv_zero' (x : IGame) [hx : x.Impartial] (y : IGame) :
    xy x + y0

    This lemma doesn't require y to be impartial.

    @[simp]
    theorem IGame.Impartial.not_equiv_iff {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    ¬xy xy
    @[simp]
    theorem IGame.Impartial.not_fuzzy_iff {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    ¬xy xy
    @[simp]
    theorem IGame.Impartial.le_iff_equiv {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    x y xy
    theorem IGame.Impartial.ge_iff_equiv {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    y x xy
    theorem IGame.Impartial.lf_iff_fuzzy {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    ¬y x xy
    theorem IGame.Impartial.gf_iff_fuzzy {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    ¬x y xy
    theorem IGame.Impartial.fuzzy_leftMove {x : IGame} [hx : x.Impartial] {y : IGame} (hy : y x.leftMoves) :
    xy
    theorem IGame.Impartial.leftMove_fuzzy {x : IGame} [hx : x.Impartial] {y : IGame} (hy : y x.leftMoves) :
    yx
    theorem IGame.Impartial.rightMove_fuzzy {x : IGame} [hx : x.Impartial] {y : IGame} (hy : y x.rightMoves) :
    yx
    theorem IGame.Impartial.fuzzy_rightMove {x : IGame} [hx : x.Impartial] {y : IGame} (hy : y x.rightMoves) :
    xy
    theorem IGame.Impartial.equiv_iff_forall_fuzzy {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    xy (∀ zx.leftMoves, zy) zy.rightMoves, xz

    This version is stated in terms of left moves of x and right moves of y.

    theorem IGame.Impartial.equiv_iff_forall_fuzzy' {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    xy (∀ zx.rightMoves, zy) zy.leftMoves, xz

    This version is stated in terms of right moves of x and left moves of y.

    theorem IGame.Impartial.fuzzy_iff_exists_equiv' {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    xy (∃ zy.leftMoves, xz) zx.rightMoves, zy

    This version is stated in terms of left moves of y and right moves of x.

    theorem IGame.Impartial.fuzzy_iff_exists_equiv {x y : IGame} [hx : x.Impartial] [hy : y.Impartial] :
    xy (∃ zy.rightMoves, xz) zx.leftMoves, zy

    This version is stated in terms of right moves of y and left moves of x.

    theorem IGame.Impartial.equiv_zero {x : IGame} [hx : x.Impartial] :
    x0 yx.leftMoves, y0

    This version is stated in terms of left moves of x.

    theorem IGame.Impartial.equiv_zero' {x : IGame} [hx : x.Impartial] :
    x0 yx.rightMoves, y0

    This version is stated in terms of right moves of x.

    theorem IGame.Impartial.fuzzy_zero {x : IGame} [hx : x.Impartial] :
    x0 yx.leftMoves, y0

    This version is stated in terms of left moves of x.

    theorem IGame.Impartial.fuzzy_zero' {x : IGame} [hx : x.Impartial] :
    x0 yx.rightMoves, y0

    This version is stated in terms of right moves of x.

    theorem IGame.Impartial.fuzzy_zero_of_forall_exists_moveLeft {x : IGame} [hx : x.Impartial] {y : IGame} (hy : y x.leftMoves) (H : zy.leftMoves, wx.leftMoves, zw) :
    x0

    A strategy stealing argument. If there's a move in x, such that any immediate move could have also been reached in the first turn, then x is won by the first player.

    This version of the theorem is stated exclusively in terms of left moves; see fuzzy_zero_of_forall_exists_moveRight for a version stated with right moves.

    theorem IGame.Impartial.fuzzy_zero_of_forall_exists_moveRight {x : IGame} [hx : x.Impartial] {y : IGame} (hy : y x.rightMoves) (H : zy.rightMoves, wx.rightMoves, zw) :
    x0

    A strategy stealing argument. If there's a move in x, such that any immediate move could have also been reached in the first turn, then x is won by the first player.

    This version of the theorem is stated exclusively in terms of right moves; see fuzzy_zero_of_forall_exists_moveLeft for a version stated with left moves.