Documentation

Mathlib.SetTheory.PGame.Basic

Combinatorial pregames #

This is the first in a series of files developing the basic theory of combinatorial games, following Conway's book On Numbers and Games:

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.

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.

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

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

                                          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))) :

                                          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

                                                                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

                                                                        Inserting an option #

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

                                                                        Equations
                                                                        Instances For

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

                                                                          Equations
                                                                          Instances For

                                                                            Inserting on the left and right commutes.