Documentation

Mathlib.SetTheory.Game.PGame

Combinatorial (pre-)games. #

The basic theory of combinatorial games, following Conway's book On Numbers and Games. We construct "pregames", define an ordering and arithmetic operations on them, then show that the operations descend to "games", defined via the equivalence relation p ≈ q ↔ p ≤ q ∧ q ≤ p.

The surreal numbers will be built as a quotient of a subtype of pregames.

A pregame (SetTheory.PGame below) is axiomatised via an inductive type, whose sole constructor takes two types (thought of as indexing the possible moves for the players Left and Right), and a pair of functions out of these types to SetTheory.PGame (thought of as describing the resulting game after making a move).

We may denote a game as $\{L | R\}$, where $L$ and $R$ stand for the collections of left and right moves. This notation is not currently used in Mathlib.

Combinatorial games themselves, as a quotient of pregames, are constructed in Mathlib.SetTheory.Game.Basic.

Conway induction #

By construction, the induction principle for pregames is exactly "Conway induction". That is, to prove some predicate SetTheory.PGame → Prop holds for all pregames, it suffices to prove that for every pregame g, if the predicate holds for every game resulting from making a move, then it also holds for g.

While it is often convenient to work "by induction" on pregames, in some situations this becomes awkward, so we also define accessor functions SetTheory.PGame.LeftMoves, SetTheory.PGame.RightMoves, SetTheory.PGame.moveLeft and SetTheory.PGame.moveRight. There is a relation PGame.Subsequent p q, saying that p can be reached by playing some non-empty sequence of moves starting from q, an instance WellFounded Subsequent, and a local tactic pgame_wf_tac which is helpful for discharging proof obligations in inductive proofs relying on this relation.

Order properties #

Pregames have both a and a < relation, satisfying the usual properties of a Preorder. The relation 0 < x means that x can always be won by Left, while 0 ≤ x means that x can be won by Left as the second player.

It turns out to be quite convenient to define various relations on top of these. We define the "less or fuzzy" relation x ⧏ y as ¬ y ≤ x, the equivalence relation x ≈ y as x ≤ y ∧ y ≤ x, and the fuzzy relation x ‖ y as x ⧏ y ∧ y ⧏ x. If 0 ⧏ x, then x can be won by Left as the first player. If x ≈ 0, then x can be won by the second player. If x ‖ 0, then x can be won by the first player.

Statements like zero_le_lf, zero_lf_le, etc. unfold these definitions. The theorems le_def and lf_def give a recursive characterisation of each relation in terms of themselves two moves later. The theorems zero_le, zero_lf, etc. also take into account that 0 has no moves.

Later, games will be defined as the quotient by the relation; that is to say, the Antisymmetrization of SetTheory.PGame.

Algebraic structures #

We next turn to defining the operations necessary to make games into a commutative additive group. Addition is defined for $x = \{xL | xR\}$ and $y = \{yL | yR\}$ by $x + y = \{xL + y, x + yL | xR + y, x + yR\}$. Negation is defined by $\{xL | xR\} = \{-xR | -xL\}$.

The order structures interact in the expected way with addition, so we have

theorem le_iff_sub_nonneg {x y : PGame} : x ≤ y ↔ 0 ≤ y - x := sorry
theorem lt_iff_sub_pos {x y : PGame} : x < y ↔ 0 < y - x := sorry

We show that these operations respect the equivalence relation, and hence descend to games. At the level of games, these operations satisfy all the laws of a commutative group. To prove the necessary equivalence relations at the level of pregames, we introduce the notion of a Relabelling of a game, and show, for example, that there is a relabelling between x + (y + z) and (x + y) + z.

Future work #

References #

The material here is all drawn from

An interested reader may like to formalise some of the material from

Pre-game moves #

inductive SetTheory.PGame :
Type (u + 1)

The type of pre-games, before we have quotiented by equivalence (PGame.Setoid). In ZFC, a combinatorial game is constructed from two sets of combinatorial games that have been constructed at an earlier stage. To do this in type theory, we say that a pre-game is built inductively from two families of pre-games indexed over any type in Type u. The resulting type PGame.{u} lives in Type (u+1), reflecting that it is a proper class in ZFC.

Instances For

    The indexing type for allowable moves by Left.

    Equations
    Instances For

      The indexing type for allowable moves by Right.

      Equations
      Instances For

        The new game after Left makes an allowed move.

        Equations
        Instances For

          The new game after Right makes an allowed move.

          Equations
          Instances For
            @[simp]
            theorem SetTheory.PGame.leftMoves_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} :
            (mk xl xr xL xR).LeftMoves = xl
            @[simp]
            theorem SetTheory.PGame.moveLeft_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} :
            (mk xl xr xL xR).moveLeft = xL
            @[simp]
            theorem SetTheory.PGame.rightMoves_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} :
            (mk xl xr xL xR).RightMoves = xr
            @[simp]
            theorem SetTheory.PGame.moveRight_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} :
            (mk xl xr xL xR).moveRight = xR
            theorem SetTheory.PGame.ext {x y : PGame} (hl : x.LeftMoves = y.LeftMoves) (hr : x.RightMoves = y.RightMoves) (hL : ∀ (i : x.LeftMoves) (j : y.LeftMoves), HEq i jx.moveLeft i = y.moveLeft j) (hR : ∀ (i : x.RightMoves) (j : y.RightMoves), HEq i jx.moveRight i = y.moveRight j) :
            x = y

            Construct a pre-game from list of pre-games describing the available moves for Left and Right.

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              @[reducible, inline]

              Converts a number into a left move for ofLists.

              This is just an abbreviation for Equiv.ulift.symm

              Equations
              Instances For
                @[reducible, inline]

                Converts a number into a right move for ofLists.

                This is just an abbreviation for Equiv.ulift.symm

                Equations
                Instances For
                  @[simp]
                  theorem SetTheory.PGame.ofLists_moveLeft {L R : List PGame} (i : Fin L.length) :
                  (ofLists L R).moveLeft { down := i } = L[i]
                  theorem SetTheory.PGame.ofLists_moveRight {L R : List PGame} (i : Fin R.length) :
                  (ofLists L R).moveRight { down := i } = R[i]
                  def SetTheory.PGame.moveRecOn {C : PGameSort u_1} (x : PGame) (IH : (y : PGame) → ((i : y.LeftMoves) → C (y.moveLeft i))((j : y.RightMoves) → C (y.moveRight j))C y) :
                  C x

                  A variant of PGame.recOn expressed in terms of PGame.moveLeft and PGame.moveRight.

                  Both this and PGame.recOn describe Conway induction on games.

                  Equations
                  Instances For

                    IsOption x y means that x is either a left or right option for y.

                    Instances For
                      theorem SetTheory.PGame.isOption_iff (a✝ a✝¹ : PGame) :
                      a✝.IsOption a✝¹ (∃ (i : a✝¹.LeftMoves), a✝ = a✝¹.moveLeft i) ∃ (i : a✝¹.RightMoves), a✝ = a✝¹.moveRight i
                      theorem SetTheory.PGame.IsOption.mk_left {xl xr : Type u} (xL : xlPGame) (xR : xrPGame) (i : xl) :
                      (xL i).IsOption (mk xl xr xL xR)
                      theorem SetTheory.PGame.IsOption.mk_right {xl xr : Type u} (xL : xlPGame) (xR : xrPGame) (i : xr) :
                      (xR i).IsOption (mk xl xr xL xR)

                      Subsequent x y says that x can be obtained by playing some nonempty sequence of moves from y. It is the transitive closure of IsOption.

                      Equations
                      Instances For
                        @[simp]
                        theorem SetTheory.PGame.Subsequent.mk_left {xl xr : Type u_1} (xL : xlPGame) (xR : xrPGame) (i : xl) :
                        (xL i).Subsequent (mk xl xr xL xR)
                        @[simp]
                        theorem SetTheory.PGame.Subsequent.mk_right {xl xr : Type u_1} (xL : xlPGame) (xR : xrPGame) (j : xr) :
                        (xR j).Subsequent (mk xl xr xL xR)

                        Discharges proof obligations of the form Subsequent .. arising in termination proofs of definitions using well-founded recursion on PGame.

                        Equations
                        Instances For
                          @[simp]
                          theorem SetTheory.PGame.Subsequent.mk_right' {xl xr : Type u} (xL : xlPGame) (xR : xrPGame) (j : (mk xl xr xL xR).RightMoves) :
                          (xR j).Subsequent (mk xl xr xL xR)
                          @[simp]
                          theorem SetTheory.PGame.Subsequent.moveRight_mk_left {xl xr : Type u} {xR : xrPGame} {i : xl} (xL : xlPGame) (j : (xL i).RightMoves) :
                          ((xL i).moveRight j).Subsequent (mk xl xr xL xR)
                          @[simp]
                          theorem SetTheory.PGame.Subsequent.moveRight_mk_right {xl xr : Type u} {xL : xlPGame} {i : xr} (xR : xrPGame) (j : (xR i).RightMoves) :
                          ((xR i).moveRight j).Subsequent (mk xl xr xL xR)
                          @[simp]
                          theorem SetTheory.PGame.Subsequent.moveLeft_mk_left {xl xr : Type u} {xR : xrPGame} {i : xl} (xL : xlPGame) (j : (xL i).LeftMoves) :
                          ((xL i).moveLeft j).Subsequent (mk xl xr xL xR)
                          @[simp]
                          theorem SetTheory.PGame.Subsequent.moveLeft_mk_right {xl xr : Type u} {xL : xlPGame} {i : xr} (xR : xrPGame) (j : (xR i).LeftMoves) :
                          ((xR i).moveLeft j).Subsequent (mk xl xr xL xR)

                          Basic pre-games #

                          Identity #

                          Two pre-games are identical if their left and right sets are identical. That is, Identical x y if every left move of x is identical to some left move of y, every right move of x is identical to some right move of y, and vice versa.

                          Equations
                          • One or more equations did not get rendered due to their size.
                          Instances For

                            Two pre-games are identical if their left and right sets are identical. That is, Identical x y if every left move of x is identical to some left move of y, every right move of x is identical to some right move of y, and vice versa.

                            Equations
                            Instances For
                              theorem SetTheory.PGame.identical_iff {x y : PGame} :
                              x.Identical y (Relator.BiTotal fun (x1 : x.LeftMoves) (x2 : y.LeftMoves) => (x.moveLeft x1).Identical (y.moveLeft x2)) Relator.BiTotal fun (x1 : x.RightMoves) (x2 : y.RightMoves) => (x.moveRight x1).Identical (y.moveRight x2)

                              x ∈ₗ y if x is identical to some left move of y.

                              Equations
                              Instances For

                                x ∈ᵣ y if x is identical to some right move of y.

                                Equations
                                Instances For

                                  x ∈ₗ y if x is identical to some left move of y.

                                  Equations
                                  Instances For

                                    x ∈ᵣ y if x is identical to some right move of y.

                                    Equations
                                    Instances For

                                      x ∈ₗ y if x is identical to some left move of y.

                                      Equations
                                      Instances For

                                        x ∈ᵣ y if x is identical to some right move of y.

                                        Equations
                                        Instances For
                                          theorem SetTheory.PGame.memₗ_def {x y : PGame} :
                                          x.memₗ y ∃ (b : y.LeftMoves), x.Identical (y.moveLeft b)
                                          theorem SetTheory.PGame.Identical.moveLeft {x y : PGame} :
                                          x.Identical y∀ (i : x.LeftMoves), ∃ (j : y.LeftMoves), (x.moveLeft i).Identical (y.moveLeft j)

                                          If x and y are identical, then a left move of x is identical to some left move of y.

                                          theorem SetTheory.PGame.Identical.moveRight {x y : PGame} :
                                          x.Identical y∀ (i : x.RightMoves), ∃ (j : y.RightMoves), (x.moveRight i).Identical (y.moveRight j)

                                          If x and y are identical, then a right move of x is identical to some right move of y.

                                          theorem SetTheory.PGame.identical_iff' {x y : PGame} :
                                          x.Identical y ((∀ (i : x.LeftMoves), (x.moveLeft i).memₗ y) ∀ (j : y.LeftMoves), (y.moveLeft j).memₗ x) (∀ (i : x.RightMoves), (x.moveRight i).memᵣ y) ∀ (j : y.RightMoves), (y.moveRight j).memᵣ x

                                          Uses ∈ₗ and ∈ᵣ instead of .

                                          theorem SetTheory.PGame.memₗ.congr_right {x y : PGame} :
                                          x.Identical y∀ {w : PGame}, w.memₗ x w.memₗ y
                                          theorem SetTheory.PGame.memᵣ.congr_right {x y : PGame} :
                                          x.Identical y∀ {w : PGame}, w.memᵣ x w.memᵣ y
                                          theorem SetTheory.PGame.memₗ.congr_left {x y : PGame} :
                                          x.Identical y∀ {w : PGame}, x.memₗ w y.memₗ w
                                          theorem SetTheory.PGame.memᵣ.congr_left {x y : PGame} :
                                          x.Identical y∀ {w : PGame}, x.memᵣ w y.memᵣ w
                                          theorem SetTheory.PGame.Identical.ext {x y : PGame} :
                                          (∀ (z : PGame), z.memₗ x z.memₗ y)(∀ (z : PGame), z.memᵣ x z.memᵣ y)x.Identical y
                                          theorem SetTheory.PGame.Identical.ext_iff {x y : PGame} :
                                          x.Identical y (∀ (z : PGame), z.memₗ x z.memₗ y) ∀ (z : PGame), z.memᵣ x z.memᵣ y
                                          theorem SetTheory.PGame.Identical.of_fn {x y : PGame} (l : x.LeftMovesy.LeftMoves) (il : y.LeftMovesx.LeftMoves) (r : x.RightMovesy.RightMoves) (ir : y.RightMovesx.RightMoves) (hl : ∀ (i : x.LeftMoves), (x.moveLeft i).Identical (y.moveLeft (l i))) (hil : ∀ (i : y.LeftMoves), (x.moveLeft (il i)).Identical (y.moveLeft i)) (hr : ∀ (i : x.RightMoves), (x.moveRight i).Identical (y.moveRight (r i))) (hir : ∀ (i : y.RightMoves), (x.moveRight (ir i)).Identical (y.moveRight i)) :

                                          Show x ≡ y by giving an explicit correspondence between the moves of x and y.

                                          theorem SetTheory.PGame.Identical.of_equiv {x y : PGame} (l : x.LeftMoves y.LeftMoves) (r : x.RightMoves y.RightMoves) (hl : ∀ (i : x.LeftMoves), (x.moveLeft i).Identical (y.moveLeft (l i))) (hr : ∀ (i : x.RightMoves), (x.moveRight i).Identical (y.moveRight (r i))) :

                                          Pre-game order relations #

                                          The less or equal relation on pre-games.

                                          If 0 ≤ x, then Left can win x as the second player. x ≤ y means that 0 ≤ y - x. See PGame.le_iff_sub_nonneg.

                                          Equations
                                          • One or more equations did not get rendered due to their size.

                                          The less or fuzzy relation on pre-games. x ⧏ y is defined as ¬ y ≤ x.

                                          If 0 ⧏ x, then Left can win x as the first player. x ⧏ y means that 0 ⧏ y - x. See PGame.lf_iff_sub_zero_lf.

                                          Equations
                                          Instances For

                                            The less or fuzzy relation on pre-games. x ⧏ y is defined as ¬ y ≤ x.

                                            If 0 ⧏ x, then Left can win x as the first player. x ⧏ y means that 0 ⧏ y - x. See PGame.lf_iff_sub_zero_lf.

                                            Equations
                                            Instances For
                                              @[simp]
                                              theorem SetTheory.PGame.not_le {x y : PGame} :
                                              ¬x y y.LF x
                                              @[simp]
                                              theorem SetTheory.PGame.not_lf {x y : PGame} :
                                              ¬x.LF y y x
                                              theorem LE.le.not_gf {x y : SetTheory.PGame} :
                                              x y¬y.LF x
                                              theorem SetTheory.PGame.LF.not_ge {x y : PGame} :
                                              x.LF y¬y x
                                              theorem SetTheory.PGame.le_iff_forall_lf {x y : PGame} :
                                              x y (∀ (i : x.LeftMoves), (x.moveLeft i).LF y) ∀ (j : y.RightMoves), x.LF (y.moveRight j)

                                              Definition of x ≤ y on pre-games, in terms of .

                                              The ordering here is chosen so that And.left refer to moves by Left, and And.right refer to moves by Right.

                                              @[simp]
                                              theorem SetTheory.PGame.mk_le_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yl yr : Type u_1} {yL : ylPGame} {yR : yrPGame} :
                                              mk xl xr xL xR mk yl yr yL yR (∀ (i : xl), (xL i).LF (mk yl yr yL yR)) ∀ (j : yr), (mk xl xr xL xR).LF (yR j)

                                              Definition of x ≤ y on pre-games built using the constructor.

                                              theorem SetTheory.PGame.le_of_forall_lf {x y : PGame} (h₁ : ∀ (i : x.LeftMoves), (x.moveLeft i).LF y) (h₂ : ∀ (j : y.RightMoves), x.LF (y.moveRight j)) :
                                              x y
                                              theorem SetTheory.PGame.lf_iff_exists_le {x y : PGame} :
                                              x.LF y (∃ (i : y.LeftMoves), x y.moveLeft i) ∃ (j : x.RightMoves), x.moveRight j y

                                              Definition of x ⧏ y on pre-games, in terms of .

                                              The ordering here is chosen so that or.inl refer to moves by Left, and or.inr refer to moves by Right.

                                              @[simp]
                                              theorem SetTheory.PGame.mk_lf_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yl yr : Type u_1} {yL : ylPGame} {yR : yrPGame} :
                                              (mk xl xr xL xR).LF (mk yl yr yL yR) (∃ (i : yl), mk xl xr xL xR yL i) ∃ (j : xr), xR j mk yl yr yL yR

                                              Definition of x ⧏ y on pre-games built using the constructor.

                                              theorem SetTheory.PGame.le_or_gf (x y : PGame) :
                                              x y y.LF x
                                              theorem SetTheory.PGame.moveLeft_lf_of_le {x y : PGame} (h : x y) (i : x.LeftMoves) :
                                              (x.moveLeft i).LF y
                                              theorem SetTheory.PGame.lf_moveRight_of_le {x y : PGame} (h : x y) (j : y.RightMoves) :
                                              x.LF (y.moveRight j)
                                              theorem SetTheory.PGame.lf_of_moveRight_le {x y : PGame} {j : x.RightMoves} (h : x.moveRight j y) :
                                              x.LF y
                                              theorem SetTheory.PGame.lf_of_le_moveLeft {x y : PGame} {i : y.LeftMoves} (h : x y.moveLeft i) :
                                              x.LF y
                                              theorem SetTheory.PGame.lf_of_le_mk {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} {y : PGame} :
                                              mk xl xr xL xR y∀ (i : xl), (xL i).LF y
                                              theorem SetTheory.PGame.lf_of_mk_le {x : PGame} {yl yr : Type u_1} {yL : ylPGame} {yR : yrPGame} :
                                              x mk yl yr yL yR∀ (j : yr), x.LF (yR j)
                                              theorem SetTheory.PGame.mk_lf_of_le {xl xr : Type u_1} {y : PGame} {j : xr} (xL : xlPGame) {xR : xrPGame} :
                                              xR j y(mk xl xr xL xR).LF y
                                              theorem SetTheory.PGame.lf_mk_of_le {x : PGame} {yl yr : Type u_1} {yL : ylPGame} (yR : yrPGame) {i : yl} :
                                              x yL ix.LF (mk yl yr yL yR)
                                              theorem SetTheory.PGame.Identical.ge {x y : PGame} (h : x.Identical y) :
                                              y x
                                              theorem SetTheory.PGame.lt_of_le_of_lf {x y : PGame} (h₁ : x y) (h₂ : x.LF y) :
                                              x < y
                                              theorem SetTheory.PGame.lf_of_lt {x y : PGame} (h : x < y) :
                                              x.LF y
                                              theorem LT.lt.lf {x y : SetTheory.PGame} (h : x < y) :
                                              x.LF y

                                              Alias of SetTheory.PGame.lf_of_lt.

                                              theorem SetTheory.PGame.not_lt {x y : PGame} :
                                              ¬x < y y.LF x y x
                                              theorem SetTheory.PGame.lf_of_le_of_lf {x y z : PGame} (h₁ : x y) (h₂ : y.LF z) :
                                              x.LF z
                                              instance SetTheory.PGame.instTransLeLF :
                                              Trans (fun (x1 x2 : PGame) => x1 x2) (fun (x1 x2 : PGame) => x1.LF x2) fun (x1 x2 : PGame) => x1.LF x2
                                              Equations
                                              theorem SetTheory.PGame.lf_of_lf_of_le {x y z : PGame} (h₁ : x.LF y) (h₂ : y z) :
                                              x.LF z
                                              instance SetTheory.PGame.instTransLFLe :
                                              Trans (fun (x1 x2 : PGame) => x1.LF x2) (fun (x1 x2 : PGame) => x1 x2) fun (x1 x2 : PGame) => x1.LF x2
                                              Equations
                                              theorem LE.le.trans_lf {x y z : SetTheory.PGame} (h₁ : x y) (h₂ : y.LF z) :
                                              x.LF z

                                              Alias of SetTheory.PGame.lf_of_le_of_lf.

                                              theorem SetTheory.PGame.LF.trans_le {x y z : PGame} (h₁ : x.LF y) (h₂ : y z) :
                                              x.LF z

                                              Alias of SetTheory.PGame.lf_of_lf_of_le.

                                              theorem SetTheory.PGame.lf_of_lt_of_lf {x y z : PGame} (h₁ : x < y) (h₂ : y.LF z) :
                                              x.LF z
                                              theorem SetTheory.PGame.lf_of_lf_of_lt {x y z : PGame} (h₁ : x.LF y) (h₂ : y < z) :
                                              x.LF z
                                              theorem LT.lt.trans_lf {x y z : SetTheory.PGame} (h₁ : x < y) (h₂ : y.LF z) :
                                              x.LF z

                                              Alias of SetTheory.PGame.lf_of_lt_of_lf.

                                              theorem SetTheory.PGame.LF.trans_lt {x y z : PGame} (h₁ : x.LF y) (h₂ : y < z) :
                                              x.LF z

                                              Alias of SetTheory.PGame.lf_of_lf_of_lt.

                                              theorem SetTheory.PGame.lf_mk {xl xr : Type u_1} (xL : xlPGame) (xR : xrPGame) (i : xl) :
                                              (xL i).LF (mk xl xr xL xR)
                                              theorem SetTheory.PGame.mk_lf {xl xr : Type u_1} (xL : xlPGame) (xR : xrPGame) (j : xr) :
                                              (mk xl xr xL xR).LF (xR j)
                                              theorem SetTheory.PGame.le_of_forall_lt {x y : PGame} (h₁ : ∀ (i : x.LeftMoves), x.moveLeft i < y) (h₂ : ∀ (j : y.RightMoves), x < y.moveRight j) :
                                              x y

                                              This special case of PGame.le_of_forall_lf is useful when dealing with surreals, where < is preferred over .

                                              theorem SetTheory.PGame.le_def {x y : PGame} :
                                              x y (∀ (i : x.LeftMoves), (∃ (i' : y.LeftMoves), x.moveLeft i y.moveLeft i') ∃ (j : (x.moveLeft i).RightMoves), (x.moveLeft i).moveRight j y) ∀ (j : y.RightMoves), (∃ (i : (y.moveRight j).LeftMoves), x (y.moveRight j).moveLeft i) ∃ (j' : x.RightMoves), x.moveRight j' y.moveRight j

                                              The definition of x ≤ y on pre-games, in terms of two moves later.

                                              Note that it's often more convenient to use le_iff_forall_lf, which only unfolds the definition by one step.

                                              theorem SetTheory.PGame.lf_def {x y : PGame} :
                                              x.LF y (∃ (i : y.LeftMoves), (∀ (i' : x.LeftMoves), (x.moveLeft i').LF (y.moveLeft i)) ∀ (j : (y.moveLeft i).RightMoves), x.LF ((y.moveLeft i).moveRight j)) ∃ (j : x.RightMoves), (∀ (i : (x.moveRight j).LeftMoves), ((x.moveRight j).moveLeft i).LF y) ∀ (j' : y.RightMoves), (x.moveRight j).LF (y.moveRight j')

                                              The definition of x ⧏ y on pre-games, in terms of two moves later.

                                              Note that it's often more convenient to use lf_iff_exists_le, which only unfolds the definition by one step.

                                              theorem SetTheory.PGame.zero_le_lf {x : PGame} :
                                              0 x ∀ (j : x.RightMoves), LF 0 (x.moveRight j)

                                              The definition of 0 ≤ x on pre-games, in terms of 0 ⧏.

                                              theorem SetTheory.PGame.le_zero_lf {x : PGame} :
                                              x 0 ∀ (i : x.LeftMoves), (x.moveLeft i).LF 0

                                              The definition of x ≤ 0 on pre-games, in terms of ⧏ 0.

                                              theorem SetTheory.PGame.zero_lf_le {x : PGame} :
                                              LF 0 x ∃ (i : x.LeftMoves), 0 x.moveLeft i

                                              The definition of 0 ⧏ x on pre-games, in terms of 0 ≤.

                                              theorem SetTheory.PGame.lf_zero_le {x : PGame} :
                                              x.LF 0 ∃ (j : x.RightMoves), x.moveRight j 0

                                              The definition of x ⧏ 0 on pre-games, in terms of ≤ 0.

                                              theorem SetTheory.PGame.zero_le {x : PGame} :
                                              0 x ∀ (j : x.RightMoves), ∃ (i : (x.moveRight j).LeftMoves), 0 (x.moveRight j).moveLeft i

                                              The definition of 0 ≤ x on pre-games, in terms of 0 ≤ two moves later.

                                              theorem SetTheory.PGame.le_zero {x : PGame} :
                                              x 0 ∀ (i : x.LeftMoves), ∃ (j : (x.moveLeft i).RightMoves), (x.moveLeft i).moveRight j 0

                                              The definition of x ≤ 0 on pre-games, in terms of ≤ 0 two moves later.

                                              theorem SetTheory.PGame.zero_lf {x : PGame} :
                                              LF 0 x ∃ (i : x.LeftMoves), ∀ (j : (x.moveLeft i).RightMoves), LF 0 ((x.moveLeft i).moveRight j)

                                              The definition of 0 ⧏ x on pre-games, in terms of 0 ⧏ two moves later.

                                              theorem SetTheory.PGame.lf_zero {x : PGame} :
                                              x.LF 0 ∃ (j : x.RightMoves), ∀ (i : (x.moveRight j).LeftMoves), ((x.moveRight j).moveLeft i).LF 0

                                              The definition of x ⧏ 0 on pre-games, in terms of ⧏ 0 two moves later.

                                              noncomputable def SetTheory.PGame.rightResponse {x : PGame} (h : x 0) (i : x.LeftMoves) :

                                              Given a game won by the right player when they play second, provide a response to any move by left.

                                              Equations
                                              Instances For

                                                Show that the response for right provided by rightResponse preserves the right-player-wins condition.

                                                noncomputable def SetTheory.PGame.leftResponse {x : PGame} (h : 0 x) (j : x.RightMoves) :

                                                Given a game won by the left player when they play second, provide a response to any move by right.

                                                Equations
                                                Instances For

                                                  Show that the response for left provided by leftResponse preserves the left-player-wins condition.

                                                  A small family of pre-games is bounded above.

                                                  A small set of pre-games is bounded above.

                                                  A small family of pre-games is bounded below.

                                                  A small set of pre-games is bounded below.

                                                  The equivalence relation on pre-games. Two pre-games x, y are equivalent if x ≤ y and y ≤ x.

                                                  If x ≈ 0, then the second player can always win x.

                                                  Equations
                                                  Instances For
                                                    theorem SetTheory.PGame.equiv_def {x y : PGame} :
                                                    x y x y y x
                                                    theorem SetTheory.PGame.Equiv.le {x y : PGame} (h : x y) :
                                                    x y
                                                    theorem SetTheory.PGame.Equiv.ge {x y : PGame} (h : x y) :
                                                    y x
                                                    theorem SetTheory.PGame.Equiv.symm {x y : PGame} :
                                                    x yy x
                                                    theorem SetTheory.PGame.Equiv.trans {x y z : PGame} :
                                                    x yy zx z
                                                    theorem SetTheory.PGame.equiv_of_eq {x y : PGame} (h : x = y) :
                                                    x y
                                                    theorem SetTheory.PGame.le_of_le_of_equiv {x y z : PGame} (h₁ : x y) (h₂ : y z) :
                                                    x z
                                                    instance SetTheory.PGame.instTransLeEquiv :
                                                    Trans (fun (x1 x2 : PGame) => x1 x2) (fun (x1 x2 : PGame) => x1 x2) fun (x1 x2 : PGame) => x1 x2
                                                    Equations
                                                    theorem SetTheory.PGame.le_of_equiv_of_le {x y z : PGame} (h₁ : x y) :
                                                    y zx z
                                                    instance SetTheory.PGame.instTransEquivLe :
                                                    Trans (fun (x1 x2 : PGame) => x1 x2) (fun (x1 x2 : PGame) => x1 x2) fun (x1 x2 : PGame) => x1 x2
                                                    Equations
                                                    theorem SetTheory.PGame.LF.not_equiv {x y : PGame} (h : x.LF y) :
                                                    ¬x y
                                                    theorem SetTheory.PGame.LF.not_equiv' {x y : PGame} (h : x.LF y) :
                                                    ¬y x
                                                    theorem SetTheory.PGame.LF.not_gt {x y : PGame} (h : x.LF y) :
                                                    ¬y < x
                                                    theorem SetTheory.PGame.le_congr_imp {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) (h : x₁ y₁) :
                                                    x₂ y₂
                                                    theorem SetTheory.PGame.le_congr {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) :
                                                    x₁ y₁ x₂ y₂
                                                    theorem SetTheory.PGame.le_congr_left {x₁ x₂ y : PGame} (hx : x₁ x₂) :
                                                    x₁ y x₂ y
                                                    theorem SetTheory.PGame.le_congr_right {x y₁ y₂ : PGame} (hy : y₁ y₂) :
                                                    x y₁ x y₂
                                                    theorem SetTheory.PGame.lf_congr {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) :
                                                    x₁.LF y₁ x₂.LF y₂
                                                    theorem SetTheory.PGame.lf_congr_imp {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) :
                                                    x₁.LF y₁x₂.LF y₂
                                                    theorem SetTheory.PGame.lf_congr_left {x₁ x₂ y : PGame} (hx : x₁ x₂) :
                                                    x₁.LF y x₂.LF y
                                                    theorem SetTheory.PGame.lf_congr_right {x y₁ y₂ : PGame} (hy : y₁ y₂) :
                                                    x.LF y₁ x.LF y₂
                                                    theorem SetTheory.PGame.lf_of_lf_of_equiv {x y z : PGame} (h₁ : x.LF y) (h₂ : y z) :
                                                    x.LF z
                                                    instance SetTheory.PGame.instTransLFEquiv :
                                                    Trans (fun (x1 x2 : PGame) => x1.LF x2) (fun (x1 x2 : PGame) => x1 x2) fun (x1 x2 : PGame) => x1.LF x2
                                                    Equations
                                                    theorem SetTheory.PGame.lf_of_equiv_of_lf {x y z : PGame} (h₁ : x y) :
                                                    y.LF zx.LF z
                                                    instance SetTheory.PGame.instTransEquivLF :
                                                    Trans (fun (x1 x2 : PGame) => x1 x2) (fun (x1 x2 : PGame) => x1.LF x2) fun (x1 x2 : PGame) => x1.LF x2
                                                    Equations
                                                    theorem SetTheory.PGame.lt_of_lt_of_equiv {x y z : PGame} (h₁ : x < y) (h₂ : y z) :
                                                    x < z
                                                    instance SetTheory.PGame.instTransLtEquiv :
                                                    Trans (fun (x1 x2 : PGame) => x1 < x2) (fun (x1 x2 : PGame) => x1 x2) fun (x1 x2 : PGame) => x1 < x2
                                                    Equations
                                                    theorem SetTheory.PGame.lt_of_equiv_of_lt {x y z : PGame} (h₁ : x y) :
                                                    y < zx < z
                                                    instance SetTheory.PGame.instTransEquivLt :
                                                    Trans (fun (x1 x2 : PGame) => x1 x2) (fun (x1 x2 : PGame) => x1 < x2) fun (x1 x2 : PGame) => x1 < x2
                                                    Equations
                                                    theorem SetTheory.PGame.lt_congr_imp {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) (h : x₁ < y₁) :
                                                    x₂ < y₂
                                                    theorem SetTheory.PGame.lt_congr {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) :
                                                    x₁ < y₁ x₂ < y₂
                                                    theorem SetTheory.PGame.lt_congr_left {x₁ x₂ y : PGame} (hx : x₁ x₂) :
                                                    x₁ < y x₂ < y
                                                    theorem SetTheory.PGame.lt_congr_right {x y₁ y₂ : PGame} (hy : y₁ y₂) :
                                                    x < y₁ x < y₂
                                                    theorem SetTheory.PGame.lt_or_equiv_of_le {x y : PGame} (h : x y) :
                                                    x < y x y
                                                    theorem SetTheory.PGame.equiv_congr_left {y₁ y₂ : PGame} :
                                                    y₁ y₂ ∀ (x₁ : PGame), x₁ y₁ x₁ y₂
                                                    theorem SetTheory.PGame.equiv_congr_right {x₁ x₂ : PGame} :
                                                    x₁ x₂ ∀ (y₁ : PGame), x₁ y₁ x₂ y₁
                                                    theorem SetTheory.PGame.Equiv.of_exists {x y : PGame} (hl₁ : ∀ (i : x.LeftMoves), ∃ (j : y.LeftMoves), x.moveLeft i y.moveLeft j) (hr₁ : ∀ (i : x.RightMoves), ∃ (j : y.RightMoves), x.moveRight i y.moveRight j) (hl₂ : ∀ (j : y.LeftMoves), ∃ (i : x.LeftMoves), x.moveLeft i y.moveLeft j) (hr₂ : ∀ (j : y.RightMoves), ∃ (i : x.RightMoves), x.moveRight i y.moveRight j) :
                                                    x y
                                                    theorem SetTheory.PGame.Equiv.of_equiv {x y : PGame} (L : x.LeftMoves y.LeftMoves) (R : x.RightMoves y.RightMoves) (hl : ∀ (i : x.LeftMoves), x.moveLeft i y.moveLeft (L i)) (hr : ∀ (j : x.RightMoves), x.moveRight j y.moveRight (R j)) :
                                                    x y
                                                    @[deprecated SetTheory.PGame.Equiv.of_equiv (since := "2024-09-26")]
                                                    theorem SetTheory.PGame.equiv_of_mk_equiv {x y : PGame} (L : x.LeftMoves y.LeftMoves) (R : x.RightMoves y.RightMoves) (hl : ∀ (i : x.LeftMoves), x.moveLeft i y.moveLeft (L i)) (hr : ∀ (j : x.RightMoves), x.moveRight j y.moveRight (R j)) :
                                                    x y

                                                    Alias of SetTheory.PGame.Equiv.of_equiv.

                                                    The fuzzy, confused, or incomparable relation on pre-games.

                                                    If x ‖ 0, then the first player can always win x.

                                                    Equations
                                                    Instances For

                                                      The fuzzy, confused, or incomparable relation on pre-games.

                                                      If x ‖ 0, then the first player can always win x.

                                                      Equations
                                                      Instances For
                                                        theorem SetTheory.PGame.Fuzzy.swap {x y : PGame} :
                                                        x.Fuzzy yy.Fuzzy x
                                                        theorem SetTheory.PGame.lf_of_fuzzy {x y : PGame} (h : x.Fuzzy y) :
                                                        x.LF y
                                                        theorem SetTheory.PGame.lt_or_fuzzy_of_lf {x y : PGame} :
                                                        x.LF yx < y x.Fuzzy y
                                                        theorem SetTheory.PGame.fuzzy_congr {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) :
                                                        x₁.Fuzzy y₁ x₂.Fuzzy y₂
                                                        theorem SetTheory.PGame.fuzzy_congr_imp {x₁ y₁ x₂ y₂ : PGame} (hx : x₁ x₂) (hy : y₁ y₂) :
                                                        x₁.Fuzzy y₁x₂.Fuzzy y₂
                                                        theorem SetTheory.PGame.fuzzy_congr_left {x₁ x₂ y : PGame} (hx : x₁ x₂) :
                                                        x₁.Fuzzy y x₂.Fuzzy y
                                                        theorem SetTheory.PGame.fuzzy_congr_right {x y₁ y₂ : PGame} (hy : y₁ y₂) :
                                                        x.Fuzzy y₁ x.Fuzzy y₂
                                                        theorem SetTheory.PGame.fuzzy_of_fuzzy_of_equiv {x y z : PGame} (h₁ : x.Fuzzy y) (h₂ : y z) :
                                                        x.Fuzzy z
                                                        theorem SetTheory.PGame.fuzzy_of_equiv_of_fuzzy {x y z : PGame} (h₁ : x y) (h₂ : y.Fuzzy z) :
                                                        x.Fuzzy z

                                                        Exactly one of the following is true (although we don't prove this here).

                                                        Relabellings #

                                                        inductive SetTheory.PGame.Relabelling :
                                                        PGamePGameType (u + 1)

                                                        Relabelling x y says that x and y are really the same game, just dressed up differently. Specifically, there is a bijection between the moves for Left in x and in y, and similarly for Right, and under these bijections we inductively have Relabellings for the consequent games.

                                                        Instances For

                                                          Relabelling x y says that x and y are really the same game, just dressed up differently. Specifically, there is a bijection between the moves for Left in x and in y, and similarly for Right, and under these bijections we inductively have Relabellings for the consequent games.

                                                          Equations
                                                          Instances For
                                                            def SetTheory.PGame.Relabelling.mk' {x y : PGame} (L : y.LeftMoves x.LeftMoves) (R : y.RightMoves x.RightMoves) (hL : (i : y.LeftMoves) → (x.moveLeft (L i)).Relabelling (y.moveLeft i)) (hR : (j : y.RightMoves) → (x.moveRight (R j)).Relabelling (y.moveRight j)) :

                                                            A constructor for relabellings swapping the equivalences.

                                                            Equations
                                                            Instances For

                                                              The equivalence between left moves of x and y given by the relabelling.

                                                              Equations
                                                              Instances For
                                                                @[simp]
                                                                theorem SetTheory.PGame.Relabelling.mk_leftMovesEquiv {x y : PGame} {L : x.LeftMoves y.LeftMoves} {R : x.RightMoves y.RightMoves} {hL : (i : x.LeftMoves) → (x.moveLeft i).Relabelling (y.moveLeft (L i))} {hR : (j : x.RightMoves) → (x.moveRight j).Relabelling (y.moveRight (R j))} :
                                                                (mk L R hL hR).leftMovesEquiv = L
                                                                @[simp]
                                                                theorem SetTheory.PGame.Relabelling.mk'_leftMovesEquiv {x y : PGame} {L : y.LeftMoves x.LeftMoves} {R : y.RightMoves x.RightMoves} {hL : (i : y.LeftMoves) → (x.moveLeft (L i)).Relabelling (y.moveLeft i)} {hR : (j : y.RightMoves) → (x.moveRight (R j)).Relabelling (y.moveRight j)} :
                                                                (mk' L R hL hR).leftMovesEquiv = L.symm

                                                                The equivalence between right moves of x and y given by the relabelling.

                                                                Equations
                                                                Instances For
                                                                  @[simp]
                                                                  theorem SetTheory.PGame.Relabelling.mk_rightMovesEquiv {x y : PGame} {L : x.LeftMoves y.LeftMoves} {R : x.RightMoves y.RightMoves} {hL : (i : x.LeftMoves) → (x.moveLeft i).Relabelling (y.moveLeft (L i))} {hR : (j : x.RightMoves) → (x.moveRight j).Relabelling (y.moveRight (R j))} :
                                                                  (mk L R hL hR).rightMovesEquiv = R
                                                                  @[simp]
                                                                  theorem SetTheory.PGame.Relabelling.mk'_rightMovesEquiv {x y : PGame} {L : y.LeftMoves x.LeftMoves} {R : y.RightMoves x.RightMoves} {hL : (i : y.LeftMoves) → (x.moveLeft (L i)).Relabelling (y.moveLeft i)} {hR : (j : y.RightMoves) → (x.moveRight (R j)).Relabelling (y.moveRight j)} :
                                                                  (mk' L R hL hR).rightMovesEquiv = R.symm

                                                                  A left move of x is a relabelling of a left move of y.

                                                                  Equations
                                                                  Instances For

                                                                    A left move of y is a relabelling of a left move of x.

                                                                    Equations
                                                                    Instances For

                                                                      A right move of x is a relabelling of a right move of y.

                                                                      Equations
                                                                      Instances For

                                                                        A right move of y is a relabelling of a right move of x.

                                                                        Equations
                                                                        Instances For
                                                                          @[irreducible]

                                                                          The identity relabelling.

                                                                          Equations
                                                                          • One or more equations did not get rendered due to their size.
                                                                          Instances For

                                                                            Flip a relabelling.

                                                                            Equations
                                                                            Instances For
                                                                              @[irreducible]
                                                                              theorem SetTheory.PGame.Relabelling.le {x y : PGame} (r : x.Relabelling y) :
                                                                              x y

                                                                              A relabelling lets us prove equivalence of games.

                                                                              Transitivity of relabelling.

                                                                              Equations
                                                                              • One or more equations did not get rendered due to their size.
                                                                              Instances For

                                                                                Any game without left or right moves is a relabelling of 0.

                                                                                Equations
                                                                                • One or more equations did not get rendered due to their size.
                                                                                Instances For
                                                                                  def SetTheory.PGame.relabel {x : PGame} {xl' xr' : Type u_1} (el : xl' x.LeftMoves) (er : xr' x.RightMoves) :

                                                                                  Replace the types indexing the next moves for Left and Right by equivalent types.

                                                                                  Equations
                                                                                  Instances For
                                                                                    @[simp]
                                                                                    theorem SetTheory.PGame.relabel_moveLeft' {x : PGame} {xl' xr' : Type u_1} (el : xl' x.LeftMoves) (er : xr' x.RightMoves) (i : xl') :
                                                                                    (relabel el er).moveLeft i = x.moveLeft (el i)
                                                                                    theorem SetTheory.PGame.relabel_moveLeft {x : PGame} {xl' xr' : Type u_1} (el : xl' x.LeftMoves) (er : xr' x.RightMoves) (i : x.LeftMoves) :
                                                                                    (relabel el er).moveLeft (el.symm i) = x.moveLeft i
                                                                                    @[simp]
                                                                                    theorem SetTheory.PGame.relabel_moveRight' {x : PGame} {xl' xr' : Type u_1} (el : xl' x.LeftMoves) (er : xr' x.RightMoves) (j : xr') :
                                                                                    (relabel el er).moveRight j = x.moveRight (er j)
                                                                                    theorem SetTheory.PGame.relabel_moveRight {x : PGame} {xl' xr' : Type u_1} (el : xl' x.LeftMoves) (er : xr' x.RightMoves) (j : x.RightMoves) :
                                                                                    (relabel el er).moveRight (er.symm j) = x.moveRight j
                                                                                    def SetTheory.PGame.relabelRelabelling {x : PGame} {xl' xr' : Type u_1} (el : xl' x.LeftMoves) (er : xr' x.RightMoves) :

                                                                                    The game obtained by relabelling the next moves is a relabelling of the original game.

                                                                                    Equations
                                                                                    • One or more equations did not get rendered due to their size.
                                                                                    Instances For

                                                                                      Negation #

                                                                                      The negation of {L | R} is {-R | -L}.

                                                                                      Equations
                                                                                      Instances For
                                                                                        @[simp]
                                                                                        theorem SetTheory.PGame.neg_def {xl xr : Type u_1} {xL : xlPGame} {xR : xrPGame} :
                                                                                        -mk xl xr xL xR = mk xr xl (fun (x : xr) => -xR x) fun (x : xl) => -xL x
                                                                                        @[simp]
                                                                                        theorem SetTheory.PGame.neg_ofLists (L R : List PGame) :
                                                                                        -ofLists L R = ofLists (List.map (fun (x : PGame) => -x) R) (List.map (fun (x : PGame) => -x) L)

                                                                                        Use toLeftMovesNeg to cast between these two types.

                                                                                        Use toRightMovesNeg to cast between these two types.

                                                                                        Turns a right move for x into a left move for -x and vice versa.

                                                                                        Even though these types are the same (not definitionally so), this is the preferred way to convert between them.

                                                                                        Equations
                                                                                        Instances For

                                                                                          Turns a left move for x into a right move for -x and vice versa.

                                                                                          Even though these types are the same (not definitionally so), this is the preferred way to convert between them.

                                                                                          Equations
                                                                                          Instances For
                                                                                            @[deprecated SetTheory.PGame.moveLeft_neg (since := "2024-10-30")]

                                                                                            Alias of SetTheory.PGame.moveLeft_neg.

                                                                                            @[deprecated SetTheory.PGame.moveRight_neg (since := "2024-10-30")]

                                                                                            Alias of SetTheory.PGame.moveRight_neg.

                                                                                            @[deprecated SetTheory.PGame.moveRight_neg (since := "2024-10-30")]
                                                                                            @[deprecated SetTheory.PGame.moveRight_neg (since := "2024-10-30")]
                                                                                            @[deprecated SetTheory.PGame.moveLeft_neg (since := "2024-10-30")]
                                                                                            @[deprecated SetTheory.PGame.moveLeft_neg (since := "2024-10-30")]
                                                                                            @[simp]
                                                                                            theorem SetTheory.PGame.forall_leftMoves_neg {x : PGame} {p : (-x).LeftMovesProp} :
                                                                                            (∀ (i : (-x).LeftMoves), p i) ∀ (i : x.RightMoves), p (toLeftMovesNeg i)
                                                                                            @[simp]
                                                                                            theorem SetTheory.PGame.exists_leftMoves_neg {x : PGame} {p : (-x).LeftMovesProp} :
                                                                                            (∃ (i : (-x).LeftMoves), p i) ∃ (i : x.RightMoves), p (toLeftMovesNeg i)
                                                                                            @[simp]
                                                                                            theorem SetTheory.PGame.forall_rightMoves_neg {x : PGame} {p : (-x).RightMovesProp} :
                                                                                            (∀ (i : (-x).RightMoves), p i) ∀ (i : x.LeftMoves), p (toRightMovesNeg i)
                                                                                            @[simp]
                                                                                            theorem SetTheory.PGame.exists_rightMoves_neg {x : PGame} {p : (-x).RightMovesProp} :
                                                                                            (∃ (i : (-x).RightMoves), p i) ∃ (i : x.LeftMoves), p (toRightMovesNeg i)
                                                                                            theorem SetTheory.PGame.leftMoves_neg_cases {x : PGame} (k : (-x).LeftMoves) {P : (-x).LeftMovesProp} (h : ∀ (i : x.RightMoves), P (toLeftMovesNeg i)) :
                                                                                            P k
                                                                                            theorem SetTheory.PGame.rightMoves_neg_cases {x : PGame} (k : (-x).RightMoves) {P : (-x).RightMovesProp} (h : ∀ (i : x.LeftMoves), P (toRightMovesNeg i)) :
                                                                                            P k
                                                                                            theorem SetTheory.PGame.Identical.neg {x₁ x₂ : PGame} :
                                                                                            x₁.Identical x₂(-x₁).Identical (-x₂)

                                                                                            If x has the same moves as y, then -x has the sames moves as -y.

                                                                                            theorem SetTheory.PGame.Identical.of_neg {x₁ x₂ : PGame} :
                                                                                            (-x₁).Identical (-x₂)x₁.Identical x₂

                                                                                            If -x has the same moves as -y, then x has the sames moves as y.

                                                                                            theorem SetTheory.PGame.memₗ_neg_iff {x y : PGame} :
                                                                                            x.memₗ (-y) ∃ (z : PGame), z.memᵣ y x.Identical (-z)
                                                                                            theorem SetTheory.PGame.memᵣ_neg_iff {x y : PGame} :
                                                                                            x.memᵣ (-y) ∃ (z : PGame), z.memₗ y x.Identical (-z)

                                                                                            If x has the same moves as y, then -x has the same moves as -y.

                                                                                            Equations
                                                                                            • One or more equations did not get rendered due to their size.
                                                                                            Instances For
                                                                                              @[simp]
                                                                                              @[simp]
                                                                                              theorem SetTheory.PGame.neg_lf_neg_iff {x y : PGame} :
                                                                                              (-y).LF (-x) x.LF y
                                                                                              @[simp]
                                                                                              theorem SetTheory.PGame.neg_lt_neg_iff {x y : PGame} :
                                                                                              -y < -x x < y
                                                                                              @[simp]
                                                                                              @[simp]
                                                                                              theorem SetTheory.PGame.neg_lf_iff {x y : PGame} :
                                                                                              (-y).LF x (-x).LF y
                                                                                              theorem SetTheory.PGame.lf_neg_iff {x y : PGame} :
                                                                                              y.LF (-x) x.LF (-y)
                                                                                              @[simp]
                                                                                              @[simp]
                                                                                              @[simp]
                                                                                              @[simp]
                                                                                              @[simp]
                                                                                              @[simp]

                                                                                              Addition and subtraction #

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

                                                                                              Equations
                                                                                              • One or more equations did not get rendered due to their size.
                                                                                              theorem SetTheory.PGame.mk_add_moveLeft {xl xr yl yr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yL : ylPGame} {yR : yrPGame} {i : (mk xl xr xL xR + mk yl yr yL yR).LeftMoves} :
                                                                                              (mk xl xr xL xR + mk yl yr yL yR).moveLeft i = Sum.rec (fun (x : xl) => xL x + mk yl yr yL yR) (fun (x : yl) => mk xl xr xL xR + yL x) i
                                                                                              theorem SetTheory.PGame.mk_add_moveRight {xl xr yl yr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yL : ylPGame} {yR : yrPGame} {i : (mk xl xr xL xR + mk yl yr yL yR).RightMoves} :
                                                                                              (mk xl xr xL xR + mk yl yr yL yR).moveRight i = Sum.rec (fun (x : xr) => xR x + mk yl yr yL yR) (fun (x : yr) => mk xl xr xL xR + yR x) i

                                                                                              The pre-game ((0 + 1) + ⋯) + 1.

                                                                                              Note that this is not the usual recursive definition n = {0, 1, … | }. For instance, 2 = 0 + 1 + 1 = {0 + 0 + 1, 0 + 1 + 0 | } does not contain any left option equivalent to 0. For an implementation of said definition, see Ordinal.toPGame. For the proof that these games are equivalent, see Ordinal.toPGame_natCast.

                                                                                              Equations
                                                                                              @[simp]
                                                                                              theorem SetTheory.PGame.nat_succ (n : ) :
                                                                                              ↑(n + 1) = n + 1
                                                                                              @[irreducible]

                                                                                              x + 0 has exactly the same moves as x.

                                                                                              Equations
                                                                                              • One or more equations did not get rendered due to their size.
                                                                                              Instances For

                                                                                                x + 0 is equivalent to x.

                                                                                                0 + x has exactly the same moves as x.

                                                                                                Equations
                                                                                                • One or more equations did not get rendered due to their size.
                                                                                                Instances For

                                                                                                  0 + x is equivalent to x.

                                                                                                  Use toLeftMovesAdd to cast between these two types.

                                                                                                  Use toRightMovesAdd to cast between these two types.

                                                                                                  Converts a left move for x or y into a left move for x + y and vice versa.

                                                                                                  Even though these types are the same (not definitionally so), this is the preferred way to convert between them.

                                                                                                  Equations
                                                                                                  Instances For

                                                                                                    Converts a right move for x or y into a right move for x + y and vice versa.

                                                                                                    Even though these types are the same (not definitionally so), this is the preferred way to convert between them.

                                                                                                    Equations
                                                                                                    Instances For
                                                                                                      @[simp]
                                                                                                      theorem SetTheory.PGame.mk_add_moveLeft_inl {xl xr yl yr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yL : ylPGame} {yR : yrPGame} {i : xl} :
                                                                                                      (mk xl xr xL xR + mk yl yr yL yR).moveLeft (Sum.inl i) = (mk xl xr xL xR).moveLeft i + mk yl yr yL yR
                                                                                                      @[simp]
                                                                                                      @[simp]
                                                                                                      theorem SetTheory.PGame.mk_add_moveRight_inl {xl xr yl yr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yL : ylPGame} {yR : yrPGame} {i : xr} :
                                                                                                      (mk xl xr xL xR + mk yl yr yL yR).moveRight (Sum.inl i) = (mk xl xr xL xR).moveRight i + mk yl yr yL yR
                                                                                                      @[simp]
                                                                                                      theorem SetTheory.PGame.mk_add_moveLeft_inr {xl xr yl yr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yL : ylPGame} {yR : yrPGame} {i : yl} :
                                                                                                      (mk xl xr xL xR + mk yl yr yL yR).moveLeft (Sum.inr i) = mk xl xr xL xR + (mk yl yr yL yR).moveLeft i
                                                                                                      @[simp]
                                                                                                      @[simp]
                                                                                                      theorem SetTheory.PGame.mk_add_moveRight_inr {xl xr yl yr : Type u_1} {xL : xlPGame} {xR : xrPGame} {yL : ylPGame} {yR : yrPGame} {i : yr} :
                                                                                                      (mk xl xr xL xR + mk yl yr yL yR).moveRight (Sum.inr i) = mk xl xr xL xR + (mk yl yr yL yR).moveRight i
                                                                                                      theorem SetTheory.PGame.leftMoves_add_cases {x y : PGame} (k : (x + y).LeftMoves) {P : (x + y).LeftMovesProp} (hl : ∀ (i : x.LeftMoves), P (toLeftMovesAdd (Sum.inl i))) (hr : ∀ (i : y.LeftMoves), P (toLeftMovesAdd (Sum.inr i))) :
                                                                                                      P k

                                                                                                      Case on possible left moves of x + y.

                                                                                                      theorem SetTheory.PGame.rightMoves_add_cases {x y : PGame} (k : (x + y).RightMoves) {P : (x + y).RightMovesProp} (hl : ∀ (j : x.RightMoves), P (toRightMovesAdd (Sum.inl j))) (hr : ∀ (j : y.RightMoves), P (toRightMovesAdd (Sum.inr j))) :
                                                                                                      P k

                                                                                                      Case on possible right moves of x + y.

                                                                                                      @[irreducible]
                                                                                                      theorem SetTheory.PGame.add_comm (x y : PGame) :
                                                                                                      (x + y).Identical (y + x)

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

                                                                                                      @[irreducible]
                                                                                                      theorem SetTheory.PGame.add_assoc (x y z : PGame) :
                                                                                                      (x + y + z).Identical (x + (y + z))

                                                                                                      (x + y) + z has exactly the same moves as x + (y + z).

                                                                                                      theorem SetTheory.PGame.add_zero (x : PGame) :
                                                                                                      (x + 0).Identical x

                                                                                                      x + 0 has exactly the same moves as x.

                                                                                                      theorem SetTheory.PGame.zero_add (x : PGame) :
                                                                                                      (0 + x).Identical x

                                                                                                      0 + x has exactly the same moves as x.

                                                                                                      @[irreducible]
                                                                                                      theorem SetTheory.PGame.neg_add (x y : PGame) :
                                                                                                      -(x + y) = -x + -y

                                                                                                      -(x + y) has exactly the same moves as -x + -y.

                                                                                                      theorem SetTheory.PGame.neg_add_rev (x y : PGame) :
                                                                                                      (-(x + y)).Identical (-y + -x)

                                                                                                      -(x + y) has exactly the same moves as -y + -x.

                                                                                                      Any game without left or right moves is identical to 0.

                                                                                                      @[irreducible]
                                                                                                      theorem SetTheory.PGame.Identical.add_right {x₁ x₂ y : PGame} :
                                                                                                      x₁.Identical x₂(x₁ + y).Identical (x₂ + y)
                                                                                                      theorem SetTheory.PGame.Identical.add_left {x y₁ y₂ : PGame} (hy : y₁.Identical y₂) :
                                                                                                      (x + y₁).Identical (x + y₂)
                                                                                                      theorem SetTheory.PGame.Identical.add {x₁ x₂ y₁ y₂ : PGame} (hx : x₁.Identical x₂) (hy : y₁.Identical y₂) :
                                                                                                      (x₁ + y₁).Identical (x₂ + y₂)

                                                                                                      If w has the same moves as x and y has the same moves as z, then w + y has the same moves as x + z.

                                                                                                      theorem SetTheory.PGame.memₗ_add_iff {x y₁ y₂ : PGame} :
                                                                                                      x.memₗ (y₁ + y₂) (∃ (z : PGame), z.memₗ y₁ x.Identical (z + y₂)) ∃ (z : PGame), z.memₗ y₂ x.Identical (y₁ + z)
                                                                                                      theorem SetTheory.PGame.memᵣ_add_iff {x y₁ y₂ : PGame} :
                                                                                                      x.memᵣ (y₁ + y₂) (∃ (z : PGame), z.memᵣ y₁ x.Identical (z + y₂)) ∃ (z : PGame), z.memᵣ y₂ x.Identical (y₁ + z)
                                                                                                      @[irreducible]
                                                                                                      def SetTheory.PGame.Relabelling.addCongr {w x y z : PGame} :
                                                                                                      w.Relabelling xy.Relabelling z(w + y).Relabelling (x + z)

                                                                                                      If w has the same moves as x and y has the same moves as z, then w + y has the same moves as x + z.

                                                                                                      Equations
                                                                                                      • One or more equations did not get rendered due to their size.
                                                                                                      Instances For
                                                                                                        Equations
                                                                                                        @[simp]
                                                                                                        theorem SetTheory.PGame.neg_sub' (x y : PGame) :
                                                                                                        -(x - y) = -x - -y

                                                                                                        This lemma is named to match neg_sub'.

                                                                                                        theorem SetTheory.PGame.Identical.sub {x₁ x₂ y₁ y₂ : PGame} (hx : x₁.Identical x₂) (hy : y₁.Identical y₂) :
                                                                                                        (x₁ - y₁).Identical (x₂ - y₂)

                                                                                                        If w has the same moves as x and y has the same moves as z, then w - y has the same moves as x - z.

                                                                                                        def SetTheory.PGame.Relabelling.subCongr {w x y z : PGame} (h₁ : w.Relabelling x) (h₂ : y.Relabelling z) :
                                                                                                        (w - y).Relabelling (x - z)

                                                                                                        If w has the same moves as x and y has the same moves as z, then w - y has the same moves as x - z.

                                                                                                        Equations
                                                                                                        Instances For
                                                                                                          @[irreducible]

                                                                                                          -(x + y) has exactly the same moves as -x + -y.

                                                                                                          Equations
                                                                                                          • One or more equations did not get rendered due to their size.
                                                                                                          Instances For
                                                                                                            theorem SetTheory.PGame.neg_add_le {x y : PGame} :
                                                                                                            -(x + y) -x + -y
                                                                                                            @[irreducible]

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

                                                                                                            Equations
                                                                                                            • One or more equations did not get rendered due to their size.
                                                                                                            Instances For
                                                                                                              theorem SetTheory.PGame.add_comm_le {x y : PGame} :
                                                                                                              x + y y + x
                                                                                                              @[irreducible]
                                                                                                              def SetTheory.PGame.addAssocRelabelling (x y z : PGame) :
                                                                                                              (x + y + z).Relabelling (x + (y + z))

                                                                                                              (x + y) + z has exactly the same moves as x + (y + z).

                                                                                                              Equations
                                                                                                              • One or more equations did not get rendered due to their size.
                                                                                                              Instances For
                                                                                                                theorem SetTheory.PGame.add_assoc_equiv {x y z : PGame} :
                                                                                                                x + y + z x + (y + z)
                                                                                                                theorem SetTheory.PGame.add_lf_add_right {y z : PGame} (h : y.LF z) (x : PGame) :
                                                                                                                (y + x).LF (z + x)
                                                                                                                theorem SetTheory.PGame.add_lf_add_left {y z : PGame} (h : y.LF z) (x : PGame) :
                                                                                                                (x + y).LF (x + z)
                                                                                                                theorem SetTheory.PGame.add_lf_add_of_lf_of_le {w x y z : PGame} (hwx : w.LF x) (hyz : y z) :
                                                                                                                (w + y).LF (x + z)
                                                                                                                theorem SetTheory.PGame.add_lf_add_of_le_of_lf {w x y z : PGame} (hwx : w x) (hyz : y.LF z) :
                                                                                                                (w + y).LF (x + z)
                                                                                                                theorem SetTheory.PGame.add_congr {w x y z : PGame} (h₁ : w x) (h₂ : y z) :
                                                                                                                w + y x + z
                                                                                                                theorem SetTheory.PGame.add_congr_left {x y z : PGame} (h : x y) :
                                                                                                                x + z y + z
                                                                                                                theorem SetTheory.PGame.add_congr_right {x y z : PGame} :
                                                                                                                y zx + y x + z
                                                                                                                theorem SetTheory.PGame.sub_congr {w x y z : PGame} (h₁ : w x) (h₂ : y z) :
                                                                                                                w - y x - z
                                                                                                                theorem SetTheory.PGame.sub_congr_left {x y z : PGame} (h : x y) :
                                                                                                                x - z y - z
                                                                                                                theorem SetTheory.PGame.sub_congr_right {x y z : PGame} :
                                                                                                                y zx - y x - z
                                                                                                                theorem SetTheory.PGame.lt_iff_sub_pos {x y : PGame} :
                                                                                                                x < y 0 < y - x

                                                                                                                Inserting an option #

                                                                                                                The pregame constructed by inserting x' as a new left option into x.

                                                                                                                Equations
                                                                                                                Instances For

                                                                                                                  A new left option cannot hurt Left.

                                                                                                                  theorem SetTheory.PGame.insertLeft_equiv_of_lf {x x' : PGame} (h : x'.LF x) :

                                                                                                                  Adding a gift horse left option does not change the value of x. A gift horse left option is a game x' with x' ⧏ x. It is called "gift horse" because it seems like Left has gotten the "gift" of a new option, but actually the value of the game did not change.

                                                                                                                  The pregame constructed by inserting x' as a new right option into x.

                                                                                                                  Equations
                                                                                                                  Instances For

                                                                                                                    A new right option cannot hurt Right.

                                                                                                                    theorem SetTheory.PGame.insertRight_equiv_of_lf {x x' : PGame} (h : x.LF x') :

                                                                                                                    Adding a gift horse right option does not change the value of x. A gift horse right option is a game x' with x ⧏ x'. It is called "gift horse" because it seems like Right has gotten the "gift" of a new option, but actually the value of the game did not change.

                                                                                                                    Inserting on the left and right commutes.

                                                                                                                    Special pre-games #

                                                                                                                    The pre-game star, which is fuzzy with zero.

                                                                                                                    Equations
                                                                                                                    Instances For
                                                                                                                      @[simp]