Documentation

CombinatorialGames.Game.Loopy.Basic

Loopy games #

The standard notion of a game studied in combinatorial game theory is that of a terminating game, meaning that there exists no infinite sequence of moves. Loopy games relax this condition by allowing "self-refential" games, with the basic examples being on = {on | }, off = { | off}, and dud = {dud | dud}.

In the literature, loopy games are defined as rooted directed graphs up to isomorphism. However, it's simpler to define LGame as the coinductive type for the single constructor:

  | ofSets (s t : Set LGame.{u}) [Small.{u} s] [Small.{u} t] : LGame.{u}

(The inductive type for this same constructor would be IGame.) This gives us a powerful corecursion principle LGame.corec, which can be interpreted as saying "for any graph we can draw on a type α, as long as the amount of branches per node is u-small, there's an LGame isomorphic to it".

Although extensionality still holds, it's not always sufficient to prove two games equal. For instance, if x = {x | x}ᴸ and y = {y | y}ᴸ, then x = y, but trying to use extensionality to prove this just leads to a cyclic argument. Instead, we can use LGame.eq_of_bisim, which can roughly be interpreted as saying "if two games have the same shape, they're equal". In this case, the relation r a b ↔ a = x ∧ b = y is a bisimulation between both games, which proves their equality.

For Mathlib #

theorem QPF.Cofix.unique {F : Type u → Type u} [QPF F] {α : Type u} (a : αF α) (f g : αCofix F) (hf : dest f = Functor.map f a) (hg : dest g = Functor.map g a) :
f = g

Game moves #

@[irreducible]
def LGame :
Type (u_1 + 1)

The type of loopy games.

Most games studied within game theory are terminating, which means that the IsOption relation is well-founded. A loopy game relaxes this constraint. Thus, LGame contains all normal IGames, but it also contains games such as on = {on | }, off = { | off}, and dud = {dud | dud}.

See the module docstring for guidance on how to make use of this type.

Equations
Instances For

    The set of left moves of the game.

    Equations
    Instances For

      The set of right moves of the game.

      Equations
      Instances For

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

        Equations
        Instances For

          A (proper) subposition is any game in the transitive closure of IsOption.

          Equations
          Instances For
            theorem LGame.Subposition.trans {x y z : LGame} (h₁ : x.Subposition y) (h₂ : y.Subposition z) :
            theorem LGame.eq_of_bisim (r : LGameLGameProp) (H : ∀ (x y : LGame), r x y(∃ (s : Set (LGame × LGame)), Prod.fst '' s = x.leftMoves Prod.snd '' s = y.leftMoves zs, r z.1 z.2) ∃ (t : Set (LGame × LGame)), Prod.fst '' t = x.rightMoves Prod.snd '' t = y.rightMoves zt, r z.1 z.2) {x y : LGame} (hxy : r x y) :
            x = y

            Two loopy games are equal when there exists a bisimulation between them.

            A way to think about this is that r defines a pairing between nodes of the game trees, which then shows that the trees are isomorphic.

            theorem LGame.ext {x y : LGame} (hl : x.leftMoves = y.leftMoves) (hr : x.rightMoves = y.rightMoves) :
            x = y

            Two LGames are equal when their move sets are.

            This is not always sufficient to prove that two games are equal. For instance, if x = {x | x}ᴸ and y = {y | y}ᴸ, then x = y, but trying to use extensionality to prove this just leads to a cyclic argument. For these situations, you can use eq_of_bisim instead.

            def LGame.corec {α : Type v} (leftMoves rightMoves : αSet α) [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] (init : α) :

            The corecursor on LGame.

            You can use this in order to define an arbitrary LGame by "drawing" its move graph on some other type. As an example, on = {on | }ᴸ is defined as corec ⊤ ⊥ ().

            Equations
            Instances For
              @[simp]
              theorem LGame.leftMoves_corec {α : Type v} (leftMoves rightMoves : αSet α) [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] (init : α) :
              (corec leftMoves rightMoves init).leftMoves = corec leftMoves rightMoves '' leftMoves init
              @[simp]
              theorem LGame.rightMoves_corec {α : Type v} (leftMoves rightMoves : αSet α) [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] (init : α) :
              (corec leftMoves rightMoves init).rightMoves = corec leftMoves rightMoves '' rightMoves init
              theorem LGame.leftMoves_comp_corec {α : Type v} (leftMoves rightMoves : αSet α) [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] :
              LGame.leftMoves corec leftMoves rightMoves = Set.image (corec leftMoves rightMoves) leftMoves
              theorem LGame.rightMoves_comp_corec {α : Type v} (leftMoves rightMoves : αSet α) [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] :
              LGame.rightMoves corec leftMoves rightMoves = Set.image (corec leftMoves rightMoves) rightMoves
              theorem LGame.hom_unique_apply {α : Type v} {leftMoves rightMoves : αSet α} [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] (f g : αLGame) (hlf : LGame.leftMoves f = Set.image f leftMoves) (hrf : LGame.rightMoves f = Set.image f rightMoves) (hlg : LGame.leftMoves g = Set.image g leftMoves) (hrg : LGame.rightMoves g = Set.image g rightMoves) (x : α) :
              f x = g x
              theorem LGame.hom_unique {α : Type v} {leftMoves rightMoves : αSet α} [∀ (a : α), Small.{u, v} (leftMoves a)] [∀ (a : α), Small.{u, v} (rightMoves a)] (f g : αLGame) (hlf : LGame.leftMoves f = Set.image f leftMoves) (hrf : LGame.rightMoves f = Set.image f rightMoves) (hlg : LGame.leftMoves g = Set.image g leftMoves) (hrg : LGame.rightMoves g = Set.image g rightMoves) :
              f = g
              theorem LGame.corec_comp_hom {α : Type v} {β : Type w} {leftMovesα rightMovesα : αSet α} {leftMovesβ rightMovesβ : βSet β} [∀ (a : α), Small.{u, v} (leftMovesα a)] [∀ (a : α), Small.{u, v} (rightMovesα a)] [∀ (b : β), Small.{u, w} (leftMovesβ b)] [∀ (b : β), Small.{u, w} (rightMovesβ b)] (f : αβ) (hlf : leftMovesβ f = Set.image f leftMovesα) (hrf : rightMovesβ f = Set.image f rightMovesα) :
              corec leftMovesβ rightMovesβ f = corec leftMovesα rightMovesα
              theorem LGame.corec_comp_hom_apply {α : Type v} {β : Type w} {leftMovesα rightMovesα : αSet α} {leftMovesβ rightMovesβ : βSet β} [∀ (a : α), Small.{u, v} (leftMovesα a)] [∀ (a : α), Small.{u, v} (rightMovesα a)] [∀ (b : β), Small.{u, w} (leftMovesβ b)] [∀ (b : β), Small.{u, w} (rightMovesβ b)] (f : αβ) (hlf : leftMovesβ f = Set.image f leftMovesα) (hrf : rightMovesβ f = Set.image f rightMovesα) (x : α) :
              corec leftMovesβ rightMovesβ (f x) = corec leftMovesα rightMovesα x
              noncomputable def LGame.ofSets (l r : Set LGame) [Small.{u, u + 1} l] [Small.{u, u + 1} r] :

              Construct an LGame from its left and right sets.

              This is given notation {s | t}ᴸ, where the superscript L is to disambiguate from set builder notation, and from the analogous constructors on other game types.

              It's not possible to create a non-well-founded game through this constructor alone. For that, see LGame.corec.

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

                Construct an LGame from its left and right sets.

                This is given notation {s | t}ᴸ, where the superscript L is to disambiguate from set builder notation, and from the analogous constructors on other game types.

                It's not possible to create a non-well-founded game through this constructor alone. For that, see LGame.corec.

                Conventions for notations in identifiers:

                • The recommended spelling of {· | ·}ᴸ in identifiers is ofSets.
                Equations
                • One or more equations did not get rendered due to their size.
                Instances For

                  Basic games #

                  The game 0 = {∅ | ∅}ᴸ.

                  Equations

                  The game 1 = {{0} | ∅}ᴵ.

                  Equations

                  The game on = {{on} | ∅}ᴸ.

                  Equations
                  Instances For

                    The game off = {∅ | {off}}ᴸ.

                    Equations
                    Instances For

                      The game dud = {{dud} | {dud}}ᴸ.

                      Equations
                      Instances For

                        The game tis = {{tisn} | ∅}ᴸ, where tisn = {∅ | {tis}}ᴸ.

                        Equations
                        Instances For

                          The game tisn = {∅ | {tis}}ᴸ, where tis = {{tisn} | ∅}ᴸ.

                          Equations
                          Instances For

                            Negation #

                            The negative of a game is defined by -{s | t}ᴸ = {-t | -s}ᴸ.

                            Equations
                            theorem LGame.neg_corec {α : Type v} (leftMoves rightMoves : αSet α) [∀ (x : α), Small.{u, v} (leftMoves x)] [∀ (x : α), Small.{u, v} (rightMoves x)] :
                            -corec leftMoves rightMoves = corec rightMoves leftMoves
                            theorem LGame.neg_corec_apply {α : Type v} (leftMoves rightMoves : αSet α) [∀ (x : α), Small.{u, v} (leftMoves x)] [∀ (x : α), Small.{u, v} (rightMoves x)] (init : α) :
                            -corec leftMoves rightMoves init = corec rightMoves leftMoves init
                            @[simp]
                            @[simp]
                            @[simp]
                            @[simp]
                            @[simp]
                            @[simp]

                            Addition #

                            The sum of x = {s₁ | t₁}ᴸ and y = {s₂ | t₂}ᴸ is {s₁ + y, x + s₂ | t₁ + y, x + t₂}ᴸ.

                            Equations
                            • One or more equations did not get rendered due to their size.
                            theorem LGame.corec_add_corec {α : Type v} {β : Type w} {leftMovesα rightMovesα : αSet α} {leftMovesβ rightMovesβ : βSet β} [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (initα : α) (initβ : β) :
                            corec leftMovesα rightMovesα initα + corec leftMovesβ rightMovesβ initβ = corec (fun (x : α × β) => (fun (y : α) => (y, x.2)) '' leftMovesα x.1 (fun (y : β) => (x.1, y)) '' leftMovesβ x.2) (fun (x : α × β) => (fun (y : α) => (y, x.2)) '' rightMovesα x.1 (fun (y : β) => (x.1, y)) '' rightMovesβ x.2) (initα, initβ)
                            @[simp]
                            theorem LGame.leftMoves_add (x y : LGame) :
                            (x + y).leftMoves = (fun (x : LGame) => x + y) '' x.leftMoves (fun (x_1 : LGame) => x + x_1) '' y.leftMoves
                            @[simp]
                            theorem LGame.rightMoves_add (x y : LGame) :
                            (x + y).rightMoves = (fun (x : LGame) => x + y) '' x.rightMoves (fun (x_1 : LGame) => x + x_1) '' y.rightMoves
                            @[simp]
                            theorem LGame.add_eq_zero_iff {x y : LGame} :
                            x + y = 0 x = 0 y = 0
                            Equations
                            • One or more equations did not get rendered due to their size.
                            @[simp]
                            @[simp]
                            @[simp]
                            theorem LGame.add_dud (x : LGame) :
                            @[simp]
                            theorem LGame.dud_add (x : LGame) :
                            theorem LGame.leftMoves_sum (m : Multiset LGame) :
                            m.sum.leftMoves = ym, (fun (x : LGame) => x + (m.erase y).sum) '' y.leftMoves
                            theorem LGame.rightMoves_sum (m : Multiset LGame) :
                            m.sum.rightMoves = ym, (fun (x : LGame) => x + (m.erase y).sum) '' y.rightMoves

                            The subtraction of x and y is defined as x + (-y).

                            Equations
                            • One or more equations did not get rendered due to their size.
                            theorem LGame.corec_sub_corec {α : Type v} {β : Type w} {leftMovesα rightMovesα : αSet α} {leftMovesβ rightMovesβ : βSet β} [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (initα : α) (initβ : β) :
                            corec leftMovesα rightMovesα initα - corec leftMovesβ rightMovesβ initβ = corec (fun (x : α × β) => (fun (y : α) => (y, x.2)) '' leftMovesα x.1 (fun (y : β) => (x.1, y)) '' rightMovesβ x.2) (fun (x : α × β) => (fun (y : α) => (y, x.2)) '' rightMovesα x.1 (fun (y : β) => (x.1, y)) '' leftMovesβ x.2) (initα, initβ)
                            @[simp]
                            theorem LGame.leftMoves_sub (x y : LGame) :
                            (x - y).leftMoves = (fun (x : LGame) => x - y) '' x.leftMoves (fun (x_1 : LGame) => x + x_1) '' (-y.rightMoves)
                            @[simp]
                            theorem LGame.rightMoves_sub (x y : LGame) :
                            (x - y).rightMoves = (fun (x : LGame) => x - y) '' x.rightMoves (fun (x_1 : LGame) => x + x_1) '' (-y.leftMoves)
                            Equations
                            • One or more equations did not get rendered due to their size.
                            @[simp]
                            @[simp]
                            theorem LGame.sub_dud (x : LGame) :

                            Multiplication #

                            @[reducible, inline]
                            abbrev LGame.MulTy (α : Type u_1) (β : Type u_2) :
                            Type (max u_2 u_1)

                            Given two game graphs drawn on types α and β, the graph for the product can be drawn on the type Multiset (Bool × α × β). Each term corresponds to a sum Σ ±aᵢ * bᵢ, where aᵢ and bᵢ are terms of α and β respectively, and the attached bool represents each term's sign.

                            Equations
                            Instances For
                              instance LGame.MulTy.instInvolutiveNeg {α : Type v} {β : Type w} :

                              Inverts the sign of all entries.

                              Equations
                              theorem LGame.MulTy.neg_def {α : Type v} {β : Type w} (x : MulTy α β) :
                              -x = Multiset.map (fun (y : Bool × α × β) => (!y.1, y.2)) x
                              @[simp]
                              theorem LGame.MulTy.mem_neg {α : Type v} {β : Type w} {x : Bool × α × β} {y : MulTy α β} :
                              x -y (!x.1, x.2) y
                              @[simp]
                              theorem LGame.MulTy.neg_zero {α : Type v} {β : Type w} :
                              -0 = 0
                              @[simp]
                              theorem LGame.MulTy.neg_singleton {α : Type v} {β : Type w} (a : Bool × α × β) :
                              -{a} = {(!a.1, a.2)}
                              @[simp]
                              theorem LGame.MulTy.neg_cons {α : Type v} {β : Type w} (a : Bool × α × β) (x : MulTy α β) :
                              -(a ::ₘ x) = (!a.1, a.2) ::ₘ -x
                              @[simp]
                              theorem LGame.MulTy.neg_add {α : Type v} {β : Type w} (x y : MulTy α β) :
                              -(x + y) = -x + -y
                              @[simp]
                              theorem LGame.MulTy.neg_erase {α : Type v} {β : Type w} [DecidableEq α] [DecidableEq β] (x : MulTy α β) (a : Bool × α × β) :
                              def LGame.MulTy.swap {α : Type v} {β : Type w} (x : MulTy α β) :
                              MulTy β α

                              Swaps the entries in all pairs.

                              Equations
                              Instances For
                                theorem LGame.MulTy.swap_def {α : Type v} {β : Type w} (x : MulTy α β) :
                                x.swap = Multiset.map (fun (a : Bool × α × β) => (a.1, a.2.swap)) x
                                @[simp]
                                theorem LGame.MulTy.mem_swap {α : Type v} {β : Type w} {x : Bool × β × α} {y : MulTy α β} :
                                x y.swap (x.1, x.2.swap) y
                                @[simp]
                                theorem LGame.MulTy.swap_zero {α : Type v} {β : Type w} :
                                swap 0 = 0
                                @[simp]
                                theorem LGame.MulTy.swap_singleton {α : Type v} {β : Type w} (a : Bool × α × β) :
                                {a}.swap = {(a.1, a.2.swap)}
                                @[simp]
                                theorem LGame.MulTy.swap_cons {α : Type v} {β : Type w} (a : Bool × α × β) (x : MulTy α β) :
                                swap (a ::ₘ x) = (a.1, a.2.swap) ::ₘ x.swap
                                @[simp]
                                theorem LGame.MulTy.swap_add {α : Type v} {β : Type w} (x y : MulTy α β) :
                                (x + y).swap = x.swap + y.swap
                                @[simp]
                                theorem LGame.MulTy.swap_erase {α : Type v} {β : Type w} [DecidableEq α] [DecidableEq β] (x : MulTy α β) (a : Bool × α × β) :
                                def LGame.MulTy.mulOption {α : Type v} {β : Type w} (b : Bool) (x y : α × β) :
                                MulTy α β

                                The general form of an option of x * y is a * y + x * b - a * b.

                                If the boolean argument is false, all signs are flipped.

                                Equations
                                Instances For
                                  @[simp]
                                  theorem LGame.MulTy.neg_mulOption {α : Type v} {β : Type w} (b : Bool) (x y : α × β) :
                                  -mulOption b x y = mulOption (!b) x y
                                  @[simp]
                                  theorem LGame.MulTy.swap_mulOption {α : Type v} {β : Type w} (b : Bool) (x y : α × β) :
                                  theorem LGame.MulTy.mulOption_eq_add {α : Type v} {β : Type w} (b : Bool) (x y : α × β) :
                                  mulOption b x y = {(b, y.1, x.2)} + {(b, x.1, y.2)} + {(!b, y.1, y.2)}
                                  def LGame.MulTy.leftMovesSet {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                  Set (α × β)

                                  The set of pairs α × β used in leftMovesSingle.

                                  Equations
                                  • One or more equations did not get rendered due to their size.
                                  Instances For
                                    def LGame.MulTy.rightMovesSet {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                    Set (α × β)

                                    The set of pairs α × β used in rightMovesSingle.

                                    Equations
                                    Instances For
                                      theorem LGame.MulTy.leftMovesSet_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                      leftMovesSet leftMovesα rightMovesα leftMovesβ rightMovesβ (!x.1, x.2) = rightMovesSet leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                      theorem LGame.MulTy.rightMovesSet_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                      rightMovesSet leftMovesα rightMovesα leftMovesβ rightMovesβ (!x.1, x.2) = leftMovesSet leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                      theorem LGame.MulTy.leftMovesSet_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                      leftMovesSet leftMovesβ rightMovesβ leftMovesα rightMovesα (x.1, x.2.swap) = Prod.swap '' leftMovesSet leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                      theorem LGame.MulTy.rightMovesSet_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                      rightMovesSet leftMovesβ rightMovesβ leftMovesα rightMovesα (x.1, x.2.swap) = Prod.swap '' rightMovesSet leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                      def LGame.MulTy.leftMovesSingle {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                      Set (MulTy α β)

                                      The left moves of ±x * y are left moves of x * y if the sign is positive, or the negatives of right moves of x * y if the sign is negative.

                                      Equations
                                      Instances For
                                        def LGame.MulTy.rightMovesSingle {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                        Set (MulTy α β)

                                        The right moves of ±x * y are right moves of x * y if the sign is positive, or the negatives of left moves of x * y if the sign is negative.

                                        Equations
                                        Instances For
                                          theorem LGame.MulTy.leftMovesSingle_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                          leftMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ (!x.1, x.2) = -rightMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                          theorem LGame.MulTy.rightMovesSingle_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                          rightMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ (!x.1, x.2) = -leftMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                          theorem LGame.MulTy.leftMovesSingle_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                          leftMovesSingle leftMovesβ rightMovesβ leftMovesα rightMovesα (x.1, x.2.swap) = swap '' leftMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                          theorem LGame.MulTy.rightMovesSingle_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) (x : Bool × α × β) :
                                          rightMovesSingle leftMovesβ rightMovesβ leftMovesα rightMovesα (x.1, x.2.swap) = swap '' rightMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                          def LGame.MulTy.leftMoves {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] (x : MulTy α β) :
                                          Set (MulTy α β)

                                          The set of left moves of Σ ±xᵢ * yᵢ are zᵢ + Σ ±xⱼ * yⱼ for all i, where cᵢ is a left move of ±xᵢ * yᵢ, and the summation is taken over indices j ≠ i.

                                          Equations
                                          • One or more equations did not get rendered due to their size.
                                          Instances For
                                            def LGame.MulTy.rightMoves {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] (x : MulTy α β) :
                                            Set (MulTy α β)

                                            The set of right moves of Σ ±xᵢ * yᵢ are zᵢ + Σ ±xⱼ * yⱼ for all i, where cᵢ is a right move of ±xᵢ * yᵢ, and the summation is taken over indices j ≠ i.

                                            Equations
                                            • One or more equations did not get rendered due to their size.
                                            Instances For
                                              theorem Multiset.iUnion_map {α : Type u_1} {β : Type u_2} {γ : Type u_3} (m : Multiset α) (f : αβ) (g : βSet γ) :
                                              xmap f m, g x = xm, g (f x)
                                              theorem LGame.MulTy.leftMoves_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] (x : MulTy α β) :
                                              leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ (-x) = -rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                              theorem LGame.MulTy.rightMoves_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] (x : MulTy α β) :
                                              rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ (-x) = -leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                              theorem LGame.MulTy.leftMoves_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] (x : MulTy α β) :
                                              leftMoves leftMovesβ rightMovesβ leftMovesα rightMovesα x.swap = swap '' leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                              theorem LGame.MulTy.rightMoves_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] (x : MulTy α β) :
                                              rightMoves leftMovesβ rightMovesβ leftMovesα rightMovesα x.swap = swap '' rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                              def LGame.MulTy.map {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} (f : α₁α₂) (g : β₁β₂) :
                                              MulTy α₁ β₁MulTy α₂ β₂

                                              Map MulTy α₁ β₁ to MulTy α₂ β₂ using f : α₁ → α₂ and g : β₁ → β₂ in the natural way.

                                              Equations
                                              Instances For
                                                @[simp]
                                                theorem LGame.MulTy.map_add {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} (f : α₁α₂) (g : β₁β₂) (x y : MulTy α₁ β₁) :
                                                map f g (x + y) = map f g x + map f g y
                                                theorem LGame.MulTy.map_erase {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} (f : α₁α₂) (g : β₁β₂) [DecidableEq α₁] [DecidableEq β₁] [DecidableEq α₂] [DecidableEq β₂] {x : MulTy α₁ β₁} {y : Bool × α₁ × β₁} (hy : y x) :
                                                map f g (Multiset.erase x y) = Multiset.erase (map f g x) (y.1, f y.2.1, g y.2.2)
                                                @[simp]
                                                theorem LGame.MulTy.map_mulOption {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} (f : α₁α₂) (g : β₁β₂) (b : Bool) (x y : α₁ × β₁) :
                                                map f g (mulOption b x y) = mulOption b (Prod.map f g x) (Prod.map f g y)
                                                theorem LGame.MulTy.leftMovesSingle_comp_prodMap {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} {leftMovesα₁ rightMovesα₁ : α₁Set α₁} {leftMovesβ₁ rightMovesβ₁ : β₁Set β₁} {leftMovesα₂ rightMovesα₂ : α₂Set α₂} {leftMovesβ₂ rightMovesβ₂ : β₂Set β₂} {f : α₁α₂} {g : β₁β₂} (hlf : leftMovesα₂ f = Set.image f leftMovesα₁) (hrf : rightMovesα₂ f = Set.image f rightMovesα₁) (hlg : leftMovesβ₂ g = Set.image g leftMovesβ₁) (hrg : rightMovesβ₂ g = Set.image g rightMovesβ₁) :
                                                leftMovesSingle leftMovesα₂ rightMovesα₂ leftMovesβ₂ rightMovesβ₂ Prod.map id (Prod.map f g) = Set.image (map f g) leftMovesSingle leftMovesα₁ rightMovesα₁ leftMovesβ₁ rightMovesβ₁
                                                theorem LGame.MulTy.rightMovesSingle_comp_prodMap {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} {leftMovesα₁ rightMovesα₁ : α₁Set α₁} {leftMovesβ₁ rightMovesβ₁ : β₁Set β₁} {leftMovesα₂ rightMovesα₂ : α₂Set α₂} {leftMovesβ₂ rightMovesβ₂ : β₂Set β₂} {f : α₁α₂} {g : β₁β₂} (hlf : leftMovesα₂ f = Set.image f leftMovesα₁) (hrf : rightMovesα₂ f = Set.image f rightMovesα₁) (hlg : leftMovesβ₂ g = Set.image g leftMovesβ₁) (hrg : rightMovesβ₂ g = Set.image g rightMovesβ₁) :
                                                rightMovesSingle leftMovesα₂ rightMovesα₂ leftMovesβ₂ rightMovesβ₂ Prod.map id (Prod.map f g) = Set.image (map f g) rightMovesSingle leftMovesα₁ rightMovesα₁ leftMovesβ₁ rightMovesβ₁
                                                theorem LGame.MulTy.leftMoves_comp_map {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} {leftMovesα₁ rightMovesα₁ : α₁Set α₁} {leftMovesβ₁ rightMovesβ₁ : β₁Set β₁} {leftMovesα₂ rightMovesα₂ : α₂Set α₂} {leftMovesβ₂ rightMovesβ₂ : β₂Set β₂} {f : α₁α₂} {g : β₁β₂} [Hα₁ : DecidableEq α₁] [Hβ₁ : DecidableEq β₁] [Hα₂ : DecidableEq α₂] [Hβ₂ : DecidableEq β₂] (hlf : leftMovesα₂ f = Set.image f leftMovesα₁) (hrf : rightMovesα₂ f = Set.image f rightMovesα₁) (hlg : leftMovesβ₂ g = Set.image g leftMovesβ₁) (hrg : rightMovesβ₂ g = Set.image g rightMovesβ₁) :
                                                leftMoves leftMovesα₂ rightMovesα₂ leftMovesβ₂ rightMovesβ₂ map f g = Set.image (map f g) leftMoves leftMovesα₁ rightMovesα₁ leftMovesβ₁ rightMovesβ₁
                                                theorem LGame.MulTy.rightMoves_comp_map {α₁ : Type u_1} {β₁ : Type u_2} {α₂ : Type u_3} {β₂ : Type u_4} {leftMovesα₁ rightMovesα₁ : α₁Set α₁} {leftMovesβ₁ rightMovesβ₁ : β₁Set β₁} {leftMovesα₂ rightMovesα₂ : α₂Set α₂} {leftMovesβ₂ rightMovesβ₂ : β₂Set β₂} {f : α₁α₂} {g : β₁β₂} [Hα₁ : DecidableEq α₁] [Hβ₁ : DecidableEq β₁] [Hα₂ : DecidableEq α₂] [Hβ₂ : DecidableEq β₂] (hlf : leftMovesα₂ f = Set.image f leftMovesα₁) (hrf : rightMovesα₂ f = Set.image f rightMovesα₁) (hlg : leftMovesβ₂ g = Set.image g leftMovesβ₁) (hrg : rightMovesβ₂ g = Set.image g rightMovesβ₁) :
                                                rightMoves leftMovesα₂ rightMovesα₂ leftMovesβ₂ rightMovesβ₂ map f g = Set.image (map f g) rightMoves leftMovesα₁ rightMovesα₁ leftMovesβ₁ rightMovesβ₁
                                                instance LGame.MulTy.instSmallElemLeftMovesSingle {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : Bool × α × β) :
                                                Small.{u, max v w} (leftMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x)
                                                instance LGame.MulTy.instSmallElemRightMovesSingle {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : Bool × α × β) :
                                                Small.{u, max v w} (rightMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x)
                                                instance LGame.MulTy.instSmallElemLeftMoves {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : MulTy α β) :
                                                Small.{u, max v w} (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ x)
                                                instance LGame.MulTy.instSmallElemRightMoves {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : MulTy α β) :
                                                Small.{u, max v w} (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ x)
                                                @[reducible, inline]
                                                abbrev LGame.MulTy.toLGame {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : Bool × α × β) :

                                                The game ±xᵢ * yᵢ.

                                                Equations
                                                • One or more equations did not get rendered due to their size.
                                                Instances For
                                                  theorem LGame.MulTy.leftMoves_toLGame {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : Bool × α × β) :
                                                  (toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ x).leftMoves = corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) '' leftMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                                  theorem LGame.MulTy.rightMoves_toLGame {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : Bool × α × β) :
                                                  (toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ x).rightMoves = corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) '' rightMovesSingle leftMovesα rightMovesα leftMovesβ rightMovesβ x
                                                  @[simp]
                                                  theorem LGame.MulTy.corec_zero {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] :
                                                  corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) 0 = 0
                                                  theorem LGame.MulTy.corec_neg {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (init : MulTy α β) :
                                                  corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (-init) = -corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) init
                                                  theorem LGame.MulTy.corec_add {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (init₁ init₂ : MulTy α β) :
                                                  corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (init₁ + init₂) = corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) init₁ + corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) init₂
                                                  theorem LGame.MulTy.corec_mulOption {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (b : Bool) (x y : α × β) :
                                                  corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (mulOption b x y) = toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ (b, y.1, x.2) + toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ (b, x.1, y.2) - toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ (b, y.1, y.2)
                                                  theorem LGame.corec_mulTy {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : MulTy α β) :
                                                  corec (MulTy.leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (MulTy.rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) x = (Multiset.map (MulTy.toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ) x).sum
                                                  theorem LGame.MulTy.corec_swap {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (x : MulTy α β) :
                                                  corec (leftMoves leftMovesβ rightMovesβ leftMovesα rightMovesα) (rightMoves leftMovesβ rightMovesβ leftMovesα rightMovesα) x.swap = corec (leftMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) (rightMoves leftMovesα rightMovesα leftMovesβ rightMovesβ) x

                                                  The product of x = {s₁ | t₁}ᴵ and y = {s₂ | t₂}ᴵ is {a₁ * y + x * b₁ - a₁ * b₁ | a₂ * y + x * b₂ - a₂ * b₂}ᴵ, where (a₁, b₁) ∈ s₁ ×ˢ s₂ ∪ t₁ ×ˢ t₂ and (a₂, b₂) ∈ s₁ ×ˢ t₂ ∪ t₁ ×ˢ s₂.

                                                  Using LGame.mulOption, this can alternatively be written as x * y = {mulOption x y a₁ b₁ | mulOption x y a₂ b₂}ᴵ.

                                                  Equations
                                                  theorem LGame.corec_mul_corec {α : Type v} {β : Type w} (leftMovesα rightMovesα : αSet α) (leftMovesβ rightMovesβ : βSet β) [ : DecidableEq α] [ : DecidableEq β] [∀ (x : α), Small.{u, v} (leftMovesα x)] [∀ (x : α), Small.{u, v} (rightMovesα x)] [∀ (x : β), Small.{u, w} (leftMovesβ x)] [∀ (x : β), Small.{u, w} (rightMovesβ x)] (initα : α) (initβ : β) :
                                                  corec leftMovesα rightMovesα initα * corec leftMovesβ rightMovesβ initβ = MulTy.toLGame leftMovesα rightMovesα leftMovesβ rightMovesβ (true, initα, initβ)
                                                  def LGame.mulOption (x y a b : LGame) :

                                                  The general option of x * y looks like a * y + x * b - a * b, for a and b options of x and y, respectively.

                                                  Equations
                                                  Instances For
                                                    @[simp]
                                                    theorem LGame.leftMoves_mul (x y : LGame) :
                                                    (x * y).leftMoves = (fun (a : LGame × LGame) => mulOption x y a.1 a.2) '' (x.leftMoves ×ˢ y.leftMoves x.rightMoves ×ˢ y.rightMoves)
                                                    @[simp]
                                                    theorem LGame.rightMoves_mul (x y : LGame) :
                                                    (x * y).rightMoves = (fun (a : LGame × LGame) => mulOption x y a.1 a.2) '' (x.leftMoves ×ˢ y.rightMoves x.rightMoves ×ˢ y.leftMoves)
                                                    @[simp]
                                                    theorem LGame.leftMoves_mulOption (x y a b : LGame) :
                                                    (mulOption x y a b).leftMoves = (a * y + x * b - a * b).leftMoves
                                                    @[simp]
                                                    theorem LGame.rightMoves_mulOption (x y a b : LGame) :
                                                    (mulOption x y a b).rightMoves = (a * y + x * b - a * b).rightMoves