l3lab/ntp-mathlib huggingface dataset:
instance covariantClass_swap_add_lt : CovariantClass Game Game (swap (· + ·)) (· < ·) :=
  ⟨by
    rintro ⟨a⟩ ⟨b⟩ ⟨c⟩ h
    

Proof state:
case mk.mk.mk
m✝ : Game
a : PGame
n₁✝ : Game
b : PGame
n₂✝ : Game
c : PGame
h : Quot.mk Setoid.r b < Quot.mk Setoid.r c
⊢ swap (fun x x_1 => x + x_1) (Quot.mk Setoid.r a) (Quot.mk Setoid.r b) <
    swap (fun x x_1 => x + x_1) (Quot.mk Setoid.r a) (Quot.mk Setoid.r c)

Next tactic:
exact @add_lt_add_right _ _ _ _ b c h a
theorem add_lf_add_right : ∀ {b c : Game} (_ : b ⧏ c) (a), (b + a : Game) ⧏ c + a := by
  

Proof state:
⊢ ∀ {b c : Game}, b ⧏ c → ∀ (a : Game), b + a ⧏ c + a

Next tactic:
rintro ⟨b⟩ ⟨c⟩ h ⟨a⟩
theorem add_lf_add_right : ∀ {b c : Game} (_ : b ⧏ c) (a), (b + a : Game) ⧏ c + a := by
  rintro ⟨b⟩ ⟨c⟩ h ⟨a⟩
  

Proof state:
case mk.mk.mk
b✝ : Game
b : PGame
c✝ : Game
c : PGame
h : Quot.mk Setoid.r b ⧏ Quot.mk Setoid.r c
a✝ : Game
a : PGame
⊢ Quot.mk Setoid.r b + Quot.mk Setoid.r a ⧏ Quot.mk Setoid.r c + Quot.mk Setoid.r a

Next tactic:
apply PGame.add_lf_add_right h
theorem add_lf_add_left : ∀ {b c : Game} (_ : b ⧏ c) (a), (a + b : Game) ⧏ a + c := by
  

Proof state:
⊢ ∀ {b c : Game}, b ⧏ c → ∀ (a : Game), a + b ⧏ a + c

Next tactic:
rintro ⟨b⟩ ⟨c⟩ h ⟨a⟩
theorem add_lf_add_left : ∀ {b c : Game} (_ : b ⧏ c) (a), (a + b : Game) ⧏ a + c := by
  rintro ⟨b⟩ ⟨c⟩ h ⟨a⟩
  

Proof state:
case mk.mk.mk
b✝ : Game
b : PGame
c✝ : Game
c : PGame
h : Quot.mk Setoid.r b ⧏ Quot.mk Setoid.r c
a✝ : Game
a : PGame
⊢ Quot.mk Setoid.r a + Quot.mk Setoid.r b ⧏ Quot.mk Setoid.r a + Quot.mk Setoid.r c

Next tactic:
apply PGame.add_lf_add_left h
theorem quot_eq_of_mk'_quot_eq {x y : PGame} (L : x.LeftMoves ≃ y.LeftMoves)
    (R : x.RightMoves ≃ y.RightMoves) (hl : ∀ i, (⟦x.moveLeft i⟧ : Game) = ⟦y.moveLeft (L i)⟧)
    (hr : ∀ j, (⟦x.moveRight j⟧ : Game) = ⟦y.moveRight (R j)⟧) : (⟦x⟧ : Game) = ⟦y⟧ := by
  

Proof state:
x y : PGame
L : LeftMoves x ≃ LeftMoves y
R : RightMoves x ≃ RightMoves y
hl : ∀ (i : LeftMoves x), ⟦moveLeft x i⟧ = ⟦moveLeft y (L i)⟧
hr : ∀ (j : RightMoves x), ⟦moveRight x j⟧ = ⟦moveRight y (R j)⟧
⊢ ⟦x⟧ = ⟦y⟧

Next tactic:
exact Quot.sound (equiv_of_mk_equiv L R (fun _ => Game.PGame.equiv_iff_game_eq.2 (hl _))
                                          (fun _ => Game.PGame.equiv_iff_game_eq.2 (hr _)))
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    

Proof state:
x y : PGame
⊢ PGame

Next tactic:
induction' x with xl xr _ _ IHxl IHxr generalizing y
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    

Proof state:
case mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
y : PGame
⊢ PGame

Next tactic:
induction' y with yl yr yL yR IHyl IHyr
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    

Proof state:
case mk.mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
⊢ PGame

Next tactic:
have y := mk yl yr yL yR
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    

Proof state:
case mk.mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
⊢ PGame

Next tactic:
refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩ <;> 

Proof state:
case mk.mk.refine'_1
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
⊢ xl × yl ⊕ xr × yr → PGame

Next tactic:
rintro (⟨i, j⟩ | ⟨i, j⟩)
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩ <;> 

Proof state:
case mk.mk.refine'_2
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
⊢ xl × yr ⊕ xr × yl → PGame

Next tactic:
rintro (⟨i, j⟩ | ⟨i, j⟩)
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩ <;> rintro (⟨i, j⟩ | ⟨i, j⟩)
    · 

Proof state:
case mk.mk.refine'_1.inl.mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
i : xl
j : yl
⊢ PGame

Next tactic:
exact IHxl i y + IHyl j - IHxl i (yL j)
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩ <;> rintro (⟨i, j⟩ | ⟨i, j⟩)
    · exact IHxl i y + IHyl j - IHxl i (yL j)
    · 

Proof state:
case mk.mk.refine'_1.inr.mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
i : xr
j : yr
⊢ PGame

Next tactic:
exact IHxr i y + IHyr j - IHxr i (yR j)
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩ <;> rintro (⟨i, j⟩ | ⟨i, j⟩)
    · exact IHxl i y + IHyl j - IHxl i (yL j)
    · exact IHxr i y + IHyr j - IHxr i (yR j)
    · 

Proof state:
case mk.mk.refine'_2.inl.mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
i : xl
j : yr
⊢ PGame

Next tactic:
exact IHxl i y + IHyr j - IHxl i (yR j)
/-- The product of `x = {xL | xR}` and `y = {yL | yR}` is
`{xL*y + x*yL - xL*yL, xR*y + x*yR - xR*yR | xL*y + x*yR - xL*yR, x*yL + xR*y - xR*yL }`. -/
instance : Mul PGame.{u} :=
  ⟨fun x y => by
    induction' x with xl xr _ _ IHxl IHxr generalizing y
    induction' y with yl yr yL yR IHyl IHyr
    have y := mk yl yr yL yR
    refine' ⟨Sum (xl × yl) (xr × yr), Sum (xl × yr) (xr × yl), _, _⟩ <;> rintro (⟨i, j⟩ | ⟨i, j⟩)
    · exact IHxl i y + IHyl j - IHxl i (yL j)
    · exact IHxr i y + IHyr j - IHxr i (yR j)
    · exact IHxl i y + IHyr j - IHxl i (yR j)
    · 

Proof state:
case mk.mk.refine'_2.inr.mk
xl xr : Type u
a✝¹ : xl → PGame
a✝ : xr → PGame
IHxl : xl → PGame → PGame
IHxr : xr → PGame → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
IHyl : yl → PGame
IHyr : yr → PGame
y : PGame
i : xr
j : yl
⊢ PGame

Next tactic:
exact IHxr i y + IHyl j - IHxr i (yL j)
@[simp]
theorem mul_moveLeft_inl {x y : PGame} {i j} :
    (x * y).moveLeft (toLeftMovesMul (Sum.inl (i, j))) =
      x.moveLeft i * y + x * y.moveLeft j - x.moveLeft i * y.moveLeft j := by
  

Proof state:
x y : PGame
i : LeftMoves x
j : LeftMoves y
⊢ moveLeft (x * y) (toLeftMovesMul (Sum.inl (i, j))) = moveLeft x i * y + x * moveLeft y j - moveLeft x i * moveLeft y j

Next tactic:
cases x
@[simp]
theorem mul_moveLeft_inl {x y : PGame} {i j} :
    (x * y).moveLeft (toLeftMovesMul (Sum.inl (i, j))) =
      x.moveLeft i * y + x * y.moveLeft j - x.moveLeft i * y.moveLeft j := by
  cases x
  

Proof state:
case mk
y : PGame
j : LeftMoves y
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
i : LeftMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveLeft (mk α✝ β✝ a✝¹ a✝ * y) (toLeftMovesMul (Sum.inl (i, j))) =
    moveLeft (mk α✝ β✝ a✝¹ a✝) i * y + mk α✝ β✝ a✝¹ a✝ * moveLeft y j - moveLeft (mk α✝ β✝ a✝¹ a✝) i * moveLeft y j

Next tactic:
cases y
@[simp]
theorem mul_moveLeft_inl {x y : PGame} {i j} :
    (x * y).moveLeft (toLeftMovesMul (Sum.inl (i, j))) =
      x.moveLeft i * y + x * y.moveLeft j - x.moveLeft i * y.moveLeft j := by
  cases x
  cases y
  

Proof state:
case mk.mk
α✝¹ β✝¹ : Type u_1
a✝³ : α✝¹ → PGame
a✝² : β✝¹ → PGame
i : LeftMoves (mk α✝¹ β✝¹ a✝³ a✝²)
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
j : LeftMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveLeft (mk α✝¹ β✝¹ a✝³ a✝² * mk α✝ β✝ a✝¹ a✝) (toLeftMovesMul (Sum.inl (i, j))) =
    moveLeft (mk α✝¹ β✝¹ a✝³ a✝²) i * mk α✝ β✝ a✝¹ a✝ + mk α✝¹ β✝¹ a✝³ a✝² * moveLeft (mk α✝ β✝ a✝¹ a✝) j -
      moveLeft (mk α✝¹ β✝¹ a✝³ a✝²) i * moveLeft (mk α✝ β✝ a✝¹ a✝) j

Next tactic:
rfl
@[simp]
theorem mul_moveLeft_inr {x y : PGame} {i j} :
    (x * y).moveLeft (toLeftMovesMul (Sum.inr (i, j))) =
      x.moveRight i * y + x * y.moveRight j - x.moveRight i * y.moveRight j := by
  

Proof state:
x y : PGame
i : RightMoves x
j : RightMoves y
⊢ moveLeft (x * y) (toLeftMovesMul (Sum.inr (i, j))) =
    moveRight x i * y + x * moveRight y j - moveRight x i * moveRight y j

Next tactic:
cases x
@[simp]
theorem mul_moveLeft_inr {x y : PGame} {i j} :
    (x * y).moveLeft (toLeftMovesMul (Sum.inr (i, j))) =
      x.moveRight i * y + x * y.moveRight j - x.moveRight i * y.moveRight j := by
  cases x
  

Proof state:
case mk
y : PGame
j : RightMoves y
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
i : RightMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveLeft (mk α✝ β✝ a✝¹ a✝ * y) (toLeftMovesMul (Sum.inr (i, j))) =
    moveRight (mk α✝ β✝ a✝¹ a✝) i * y + mk α✝ β✝ a✝¹ a✝ * moveRight y j - moveRight (mk α✝ β✝ a✝¹ a✝) i * moveRight y j

Next tactic:
cases y
@[simp]
theorem mul_moveLeft_inr {x y : PGame} {i j} :
    (x * y).moveLeft (toLeftMovesMul (Sum.inr (i, j))) =
      x.moveRight i * y + x * y.moveRight j - x.moveRight i * y.moveRight j := by
  cases x
  cases y
  

Proof state:
case mk.mk
α✝¹ β✝¹ : Type u_1
a✝³ : α✝¹ → PGame
a✝² : β✝¹ → PGame
i : RightMoves (mk α✝¹ β✝¹ a✝³ a✝²)
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
j : RightMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveLeft (mk α✝¹ β✝¹ a✝³ a✝² * mk α✝ β✝ a✝¹ a✝) (toLeftMovesMul (Sum.inr (i, j))) =
    moveRight (mk α✝¹ β✝¹ a✝³ a✝²) i * mk α✝ β✝ a✝¹ a✝ + mk α✝¹ β✝¹ a✝³ a✝² * moveRight (mk α✝ β✝ a✝¹ a✝) j -
      moveRight (mk α✝¹ β✝¹ a✝³ a✝²) i * moveRight (mk α✝ β✝ a✝¹ a✝) j

Next tactic:
rfl
@[simp]
theorem mul_moveRight_inl {x y : PGame} {i j} :
    (x * y).moveRight (toRightMovesMul (Sum.inl (i, j))) =
      x.moveLeft i * y + x * y.moveRight j - x.moveLeft i * y.moveRight j := by
  

Proof state:
x y : PGame
i : LeftMoves x
j : RightMoves y
⊢ moveRight (x * y) (toRightMovesMul (Sum.inl (i, j))) =
    moveLeft x i * y + x * moveRight y j - moveLeft x i * moveRight y j

Next tactic:
cases x
@[simp]
theorem mul_moveRight_inl {x y : PGame} {i j} :
    (x * y).moveRight (toRightMovesMul (Sum.inl (i, j))) =
      x.moveLeft i * y + x * y.moveRight j - x.moveLeft i * y.moveRight j := by
  cases x
  

Proof state:
case mk
y : PGame
j : RightMoves y
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
i : LeftMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveRight (mk α✝ β✝ a✝¹ a✝ * y) (toRightMovesMul (Sum.inl (i, j))) =
    moveLeft (mk α✝ β✝ a✝¹ a✝) i * y + mk α✝ β✝ a✝¹ a✝ * moveRight y j - moveLeft (mk α✝ β✝ a✝¹ a✝) i * moveRight y j

Next tactic:
cases y
@[simp]
theorem mul_moveRight_inl {x y : PGame} {i j} :
    (x * y).moveRight (toRightMovesMul (Sum.inl (i, j))) =
      x.moveLeft i * y + x * y.moveRight j - x.moveLeft i * y.moveRight j := by
  cases x
  cases y
  

Proof state:
case mk.mk
α✝¹ β✝¹ : Type u_1
a✝³ : α✝¹ → PGame
a✝² : β✝¹ → PGame
i : LeftMoves (mk α✝¹ β✝¹ a✝³ a✝²)
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
j : RightMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveRight (mk α✝¹ β✝¹ a✝³ a✝² * mk α✝ β✝ a✝¹ a✝) (toRightMovesMul (Sum.inl (i, j))) =
    moveLeft (mk α✝¹ β✝¹ a✝³ a✝²) i * mk α✝ β✝ a✝¹ a✝ + mk α✝¹ β✝¹ a✝³ a✝² * moveRight (mk α✝ β✝ a✝¹ a✝) j -
      moveLeft (mk α✝¹ β✝¹ a✝³ a✝²) i * moveRight (mk α✝ β✝ a✝¹ a✝) j

Next tactic:
rfl
@[simp]
theorem mul_moveRight_inr {x y : PGame} {i j} :
    (x * y).moveRight (toRightMovesMul (Sum.inr (i, j))) =
      x.moveRight i * y + x * y.moveLeft j - x.moveRight i * y.moveLeft j := by
  

Proof state:
x y : PGame
i : RightMoves x
j : LeftMoves y
⊢ moveRight (x * y) (toRightMovesMul (Sum.inr (i, j))) =
    moveRight x i * y + x * moveLeft y j - moveRight x i * moveLeft y j

Next tactic:
cases x
@[simp]
theorem mul_moveRight_inr {x y : PGame} {i j} :
    (x * y).moveRight (toRightMovesMul (Sum.inr (i, j))) =
      x.moveRight i * y + x * y.moveLeft j - x.moveRight i * y.moveLeft j := by
  cases x
  

Proof state:
case mk
y : PGame
j : LeftMoves y
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
i : RightMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveRight (mk α✝ β✝ a✝¹ a✝ * y) (toRightMovesMul (Sum.inr (i, j))) =
    moveRight (mk α✝ β✝ a✝¹ a✝) i * y + mk α✝ β✝ a✝¹ a✝ * moveLeft y j - moveRight (mk α✝ β✝ a✝¹ a✝) i * moveLeft y j

Next tactic:
cases y
@[simp]
theorem mul_moveRight_inr {x y : PGame} {i j} :
    (x * y).moveRight (toRightMovesMul (Sum.inr (i, j))) =
      x.moveRight i * y + x * y.moveLeft j - x.moveRight i * y.moveLeft j := by
  cases x
  cases y
  

Proof state:
case mk.mk
α✝¹ β✝¹ : Type u_1
a✝³ : α✝¹ → PGame
a✝² : β✝¹ → PGame
i : RightMoves (mk α✝¹ β✝¹ a✝³ a✝²)
α✝ β✝ : Type u_1
a✝¹ : α✝ → PGame
a✝ : β✝ → PGame
j : LeftMoves (mk α✝ β✝ a✝¹ a✝)
⊢ moveRight (mk α✝¹ β✝¹ a✝³ a✝² * mk α✝ β✝ a✝¹ a✝) (toRightMovesMul (Sum.inr (i, j))) =
    moveRight (mk α✝¹ β✝¹ a✝³ a✝²) i * mk α✝ β✝ a✝¹ a✝ + mk α✝¹ β✝¹ a✝³ a✝² * moveLeft (mk α✝ β✝ a✝¹ a✝) j -
      moveRight (mk α✝¹ β✝¹ a✝³ a✝²) i * moveLeft (mk α✝ β✝ a✝¹ a✝) j

Next tactic:
rfl
theorem leftMoves_mul_cases {x y : PGame} (k) {P : (x * y).LeftMoves → Prop}
    (hl : ∀ ix iy, P <| toLeftMovesMul (Sum.inl ⟨ix, iy⟩))
    (hr : ∀ jx jy, P <| toLeftMovesMul (Sum.inr ⟨jx, jy⟩)) : P k := by
  

Proof state:
x y : PGame
k : LeftMoves (x * y)
P : LeftMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (iy : LeftMoves y), P (toLeftMovesMul (Sum.inl (ix, iy)))
hr : ∀ (jx : RightMoves x) (jy : RightMoves y), P (toLeftMovesMul (Sum.inr (jx, jy)))
⊢ P k

Next tactic:
rw [← toLeftMovesMul.apply_symm_apply k]
theorem leftMoves_mul_cases {x y : PGame} (k) {P : (x * y).LeftMoves → Prop}
    (hl : ∀ ix iy, P <| toLeftMovesMul (Sum.inl ⟨ix, iy⟩))
    (hr : ∀ jx jy, P <| toLeftMovesMul (Sum.inr ⟨jx, jy⟩)) : P k := by
  rw [← toLeftMovesMul.apply_symm_apply k]
  

Proof state:
x y : PGame
k : LeftMoves (x * y)
P : LeftMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (iy : LeftMoves y), P (toLeftMovesMul (Sum.inl (ix, iy)))
hr : ∀ (jx : RightMoves x) (jy : RightMoves y), P (toLeftMovesMul (Sum.inr (jx, jy)))
⊢ P (toLeftMovesMul (toLeftMovesMul.symm k))

Next tactic:
rcases toLeftMovesMul.symm k with (⟨ix, iy⟩ | ⟨jx, jy⟩)
theorem leftMoves_mul_cases {x y : PGame} (k) {P : (x * y).LeftMoves → Prop}
    (hl : ∀ ix iy, P <| toLeftMovesMul (Sum.inl ⟨ix, iy⟩))
    (hr : ∀ jx jy, P <| toLeftMovesMul (Sum.inr ⟨jx, jy⟩)) : P k := by
  rw [← toLeftMovesMul.apply_symm_apply k]
  rcases toLeftMovesMul.symm k with (⟨ix, iy⟩ | ⟨jx, jy⟩)
  · 

Proof state:
case inl.mk
x y : PGame
k : LeftMoves (x * y)
P : LeftMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (iy : LeftMoves y), P (toLeftMovesMul (Sum.inl (ix, iy)))
hr : ∀ (jx : RightMoves x) (jy : RightMoves y), P (toLeftMovesMul (Sum.inr (jx, jy)))
ix : LeftMoves x
iy : LeftMoves y
⊢ P (toLeftMovesMul (Sum.inl (ix, iy)))

Next tactic:
apply hl
theorem leftMoves_mul_cases {x y : PGame} (k) {P : (x * y).LeftMoves → Prop}
    (hl : ∀ ix iy, P <| toLeftMovesMul (Sum.inl ⟨ix, iy⟩))
    (hr : ∀ jx jy, P <| toLeftMovesMul (Sum.inr ⟨jx, jy⟩)) : P k := by
  rw [← toLeftMovesMul.apply_symm_apply k]
  rcases toLeftMovesMul.symm k with (⟨ix, iy⟩ | ⟨jx, jy⟩)
  · apply hl
  · 

Proof state:
case inr.mk
x y : PGame
k : LeftMoves (x * y)
P : LeftMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (iy : LeftMoves y), P (toLeftMovesMul (Sum.inl (ix, iy)))
hr : ∀ (jx : RightMoves x) (jy : RightMoves y), P (toLeftMovesMul (Sum.inr (jx, jy)))
jx : RightMoves x
jy : RightMoves y
⊢ P (toLeftMovesMul (Sum.inr (jx, jy)))

Next tactic:
apply hr
theorem rightMoves_mul_cases {x y : PGame} (k) {P : (x * y).RightMoves → Prop}
    (hl : ∀ ix jy, P <| toRightMovesMul (Sum.inl ⟨ix, jy⟩))
    (hr : ∀ jx iy, P <| toRightMovesMul (Sum.inr ⟨jx, iy⟩)) : P k := by
  

Proof state:
x y : PGame
k : RightMoves (x * y)
P : RightMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (jy : RightMoves y), P (toRightMovesMul (Sum.inl (ix, jy)))
hr : ∀ (jx : RightMoves x) (iy : LeftMoves y), P (toRightMovesMul (Sum.inr (jx, iy)))
⊢ P k

Next tactic:
rw [← toRightMovesMul.apply_symm_apply k]
theorem rightMoves_mul_cases {x y : PGame} (k) {P : (x * y).RightMoves → Prop}
    (hl : ∀ ix jy, P <| toRightMovesMul (Sum.inl ⟨ix, jy⟩))
    (hr : ∀ jx iy, P <| toRightMovesMul (Sum.inr ⟨jx, iy⟩)) : P k := by
  rw [← toRightMovesMul.apply_symm_apply k]
  

Proof state:
x y : PGame
k : RightMoves (x * y)
P : RightMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (jy : RightMoves y), P (toRightMovesMul (Sum.inl (ix, jy)))
hr : ∀ (jx : RightMoves x) (iy : LeftMoves y), P (toRightMovesMul (Sum.inr (jx, iy)))
⊢ P (toRightMovesMul (toRightMovesMul.symm k))

Next tactic:
rcases toRightMovesMul.symm k with (⟨ix, iy⟩ | ⟨jx, jy⟩)
theorem rightMoves_mul_cases {x y : PGame} (k) {P : (x * y).RightMoves → Prop}
    (hl : ∀ ix jy, P <| toRightMovesMul (Sum.inl ⟨ix, jy⟩))
    (hr : ∀ jx iy, P <| toRightMovesMul (Sum.inr ⟨jx, iy⟩)) : P k := by
  rw [← toRightMovesMul.apply_symm_apply k]
  rcases toRightMovesMul.symm k with (⟨ix, iy⟩ | ⟨jx, jy⟩)
  · 

Proof state:
case inl.mk
x y : PGame
k : RightMoves (x * y)
P : RightMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (jy : RightMoves y), P (toRightMovesMul (Sum.inl (ix, jy)))
hr : ∀ (jx : RightMoves x) (iy : LeftMoves y), P (toRightMovesMul (Sum.inr (jx, iy)))
ix : LeftMoves x
iy : RightMoves y
⊢ P (toRightMovesMul (Sum.inl (ix, iy)))

Next tactic:
apply hl
theorem rightMoves_mul_cases {x y : PGame} (k) {P : (x * y).RightMoves → Prop}
    (hl : ∀ ix jy, P <| toRightMovesMul (Sum.inl ⟨ix, jy⟩))
    (hr : ∀ jx iy, P <| toRightMovesMul (Sum.inr ⟨jx, iy⟩)) : P k := by
  rw [← toRightMovesMul.apply_symm_apply k]
  rcases toRightMovesMul.symm k with (⟨ix, iy⟩ | ⟨jx, jy⟩)
  · apply hl
  · 

Proof state:
case inr.mk
x y : PGame
k : RightMoves (x * y)
P : RightMoves (x * y) → Prop
hl : ∀ (ix : LeftMoves x) (jy : RightMoves y), P (toRightMovesMul (Sum.inl (ix, jy)))
hr : ∀ (jx : RightMoves x) (iy : LeftMoves y), P (toRightMovesMul (Sum.inr (jx, iy)))
jx : RightMoves x
jy : LeftMoves y
⊢ P (toRightMovesMul (Sum.inr (jx, jy)))

Next tactic:
apply hr
/-- `x * y` and `y * x` have the same moves. -/
def mulCommRelabelling (x y : PGame.{u}) : x * y ≡r y * x :=
  match x, y with
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩ => by
    

Proof state:
x y : PGame
xl xr : Type u
xL : xl → PGame
xR : xr → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
⊢ mk xl xr xL xR * mk yl yr yL yR ≡r mk yl yr yL yR * mk xl xr xL xR

Next tactic:
refine' ⟨Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _),
      (Equiv.sumComm _ _).trans (Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _)), _, _⟩
/-- `x * y` and `y * x` have the same moves. -/
def mulCommRelabelling (x y : PGame.{u}) : x * y ≡r y * x :=
  match x, y with
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩ => by
    refine' ⟨Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _),
      (Equiv.sumComm _ _).trans (Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _)), _, _⟩
      <;>
    

Proof state:
case refine'_1
x y : PGame
xl xr : Type u
xL : xl → PGame
xR : xr → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
⊢ (i : LeftMoves (mk xl xr xL xR * mk yl yr yL yR)) →
    moveLeft (mk xl xr xL xR * mk yl yr yL yR) i ≡r
      moveLeft (mk yl yr yL yR * mk xl xr xL xR) ((Equiv.sumCongr (Equiv.prodComm xl yl) (Equiv.prodComm xr yr)) i)

Next tactic:
rintro (⟨i, j⟩ | ⟨i, j⟩)
/-- `x * y` and `y * x` have the same moves. -/
def mulCommRelabelling (x y : PGame.{u}) : x * y ≡r y * x :=
  match x, y with
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩ => by
    refine' ⟨Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _),
      (Equiv.sumComm _ _).trans (Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _)), _, _⟩
      <;>
    

Proof state:
case refine'_2
x y : PGame
xl xr : Type u
xL : xl → PGame
xR : xr → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
⊢ (j : RightMoves (mk xl xr xL xR * mk yl yr yL yR)) →
    moveRight (mk xl xr xL xR * mk yl yr yL yR) j ≡r
      moveRight (mk yl yr yL yR * mk xl xr xL xR)
        (((Equiv.sumComm (xl × yr) (xr × yl)).trans (Equiv.sumCongr (Equiv.prodComm xr yl) (Equiv.prodComm xl yr))) j)

Next tactic:
rintro (⟨i, j⟩ | ⟨i, j⟩)
/-- `x * y` and `y * x` have the same moves. -/
def mulCommRelabelling (x y : PGame.{u}) : x * y ≡r y * x :=
  match x, y with
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩ => by
    refine' ⟨Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _),
      (Equiv.sumComm _ _).trans (Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _)), _, _⟩
      <;>
    rintro (⟨i, j⟩ | ⟨i, j⟩) <;>
    

Proof state:
case refine'_1.inl.mk
x y : PGame
xl xr : Type u
xL : xl → PGame
xR : xr → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
i : xl
j : yl
⊢ moveLeft (mk xl xr xL xR * mk yl yr yL yR) (Sum.inl (i, j)) ≡r
    moveLeft (mk yl yr yL yR * mk xl xr xL xR)
      ((Equiv.sumCongr (Equiv.prodComm xl yl) (Equiv.prodComm xr yr)) (Sum.inl (i, j)))

Next tactic:
{ dsimp
      exact ((addCommRelabelling _ _).trans <|
        (mulCommRelabelling _ _).addCongr (mulCommRelabelling _ _)).subCongr
        (mulCommRelabelling _ _) }
/-- `x * y` and `y * x` have the same moves. -/
def mulCommRelabelling (x y : PGame.{u}) : x * y ≡r y * x :=
  match x, y with
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩ => by
    refine' ⟨Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _),
      (Equiv.sumComm _ _).trans (Equiv.sumCongr (Equiv.prodComm _ _) (Equiv.prodComm _ _)), _, _⟩
      <;>
    rintro (⟨i, j⟩ | ⟨i, j⟩) <;>
    { 

Proof state:
case refine'_1.inl.mk
x y : PGame
xl xr : Type u
xL : xl → PGame
xR : xr → PGame
yl yr : Type u
yL : yl → PGame
yR : yr → PGame
i : xl
j : yl
⊢ moveLeft (mk xl xr xL xR * mk yl yr yL yR) (Sum.inl (i, j)) ≡r
    moveLeft (mk yl yr yL yR * mk xl xr xL xR)
      ((Equiv.sumCongr (Equiv.prodComm xl yl) (Equiv.prodComm xr yr)) (Sum.inl (i, j)))

Next tactic:
dsimp