l3lab/ntp-mathlib huggingface dataset:
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · 

Proof state:
case refine'_2.right_inv
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
⊢ Function.RightInverse
    (fun a =>
      Sum.casesOn a
        (fun val =>
          Prod.casesOn val fun fst snd =>
            Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inl (fst, fst_1), snd))
              fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inl (fst, fst_1), snd))
        fun val =>
        Prod.casesOn val fun fst snd =>
          Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inr (fst, fst_1), snd)) fun val =>
            Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inr (fst, fst_1), snd))
    fun a =>
    Sum.casesOn a
      (fun val =>
        Prod.casesOn val fun fst snd =>
          Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inl (snd_1, snd))) fun val =>
            Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inr (snd_1, snd)))
      fun val =>
      Prod.casesOn val fun fst snd =>
        Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inr (snd_1, snd))) fun val =>
          Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inl (snd_1, snd))

Next tactic:
rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩)
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> 

Proof state:
case refine'_2.right_inv.inl.mk.inl.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
fst✝¹ : xl
fst✝ : yl
snd✝ : zr
⊢ (fun a =>
        Sum.casesOn a
          (fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inl (snd_1, snd)))
                fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inr (snd_1, snd)))
          fun val =>
          Prod.casesOn val fun fst snd =>
            Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inr (snd_1, snd)))
              fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inl (snd_1, snd)))
      ((fun a =>
          Sum.casesOn a
            (fun val =>
              Prod.casesOn val fun fst snd =>
                Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inl (fst, fst_1), snd))
                  fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inl (fst, fst_1), snd))
            fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inr (fst, fst_1), snd))
                fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inr (fst, fst_1), snd))
        (Sum.inl (fst✝¹, Sum.inl (fst✝, snd✝)))) =
    Sum.inl (fst✝¹, Sum.inl (fst✝, snd✝))

Next tactic:
rfl
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> 

Proof state:
case refine'_2.right_inv.inl.mk.inr.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
fst✝¹ : xl
fst✝ : yr
snd✝ : zl
⊢ (fun a =>
        Sum.casesOn a
          (fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inl (snd_1, snd)))
                fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inr (snd_1, snd)))
          fun val =>
          Prod.casesOn val fun fst snd =>
            Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inr (snd_1, snd)))
              fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inl (snd_1, snd)))
      ((fun a =>
          Sum.casesOn a
            (fun val =>
              Prod.casesOn val fun fst snd =>
                Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inl (fst, fst_1), snd))
                  fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inl (fst, fst_1), snd))
            fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inr (fst, fst_1), snd))
                fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inr (fst, fst_1), snd))
        (Sum.inl (fst✝¹, Sum.inr (fst✝, snd✝)))) =
    Sum.inl (fst✝¹, Sum.inr (fst✝, snd✝))

Next tactic:
rfl
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> 

Proof state:
case refine'_2.right_inv.inr.mk.inl.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
fst✝¹ : xr
fst✝ : yl
snd✝ : zl
⊢ (fun a =>
        Sum.casesOn a
          (fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inl (snd_1, snd)))
                fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inr (snd_1, snd)))
          fun val =>
          Prod.casesOn val fun fst snd =>
            Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inr (snd_1, snd)))
              fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inl (snd_1, snd)))
      ((fun a =>
          Sum.casesOn a
            (fun val =>
              Prod.casesOn val fun fst snd =>
                Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inl (fst, fst_1), snd))
                  fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inl (fst, fst_1), snd))
            fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inr (fst, fst_1), snd))
                fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inr (fst, fst_1), snd))
        (Sum.inr (fst✝¹, Sum.inl (fst✝, snd✝)))) =
    Sum.inr (fst✝¹, Sum.inl (fst✝, snd✝))

Next tactic:
rfl
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> 

Proof state:
case refine'_2.right_inv.inr.mk.inr.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
fst✝¹ : xr
fst✝ : yr
snd✝ : zr
⊢ (fun a =>
        Sum.casesOn a
          (fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inl (snd_1, snd)))
                fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inr (snd_1, snd)))
          fun val =>
          Prod.casesOn val fun fst snd =>
            Sum.casesOn fst (fun val => Prod.casesOn val fun fst snd_1 => Sum.inl (fst, Sum.inr (snd_1, snd)))
              fun val => Prod.casesOn val fun fst snd_1 => Sum.inr (fst, Sum.inl (snd_1, snd)))
      ((fun a =>
          Sum.casesOn a
            (fun val =>
              Prod.casesOn val fun fst snd =>
                Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inl (fst, fst_1), snd))
                  fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inl (fst, fst_1), snd))
            fun val =>
            Prod.casesOn val fun fst snd =>
              Sum.casesOn snd (fun val => Prod.casesOn val fun fst_1 snd => Sum.inr (Sum.inr (fst, fst_1), snd))
                fun val => Prod.casesOn val fun fst_1 snd => Sum.inl (Sum.inr (fst, fst_1), snd))
        (Sum.inr (fst✝¹, Sum.inr (fst✝, snd✝)))) =
    Sum.inr (fst✝¹, Sum.inr (fst✝, snd✝))

Next tactic:
rfl
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    -- Porting note: explicitly wrote out arguments to each recursive
    -- quot_mul_assoc reference below, because otherwise the decreasing_by block
    -- failed. Each branch previously ended with: `simp [quot_mul_assoc]; abel`
    -- See https://github.com/leanprover/lean4/issues/2288
    · rintro (⟨⟨i, j⟩ | ⟨i, j⟩, k⟩ | ⟨⟨i, j⟩ | ⟨i, j⟩, k⟩)
      · change
          ⟦(xL i * y + x * yL j - xL i * yL j) * z + x * y * zL k -
                (xL i * y + x * yL j - xL i * yL j) * zL k⟧ =
            ⟦xL i * (y * z) + x * (yL j * z + y * zL k - yL j * zL k) -
                xL i * (yL j * z + y * zL k - yL j * zL k)⟧
        

Proof state:
case refine'_3.inl.mk.inl.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
k : zl
i : xl
j : yl
⊢ ⟦(xL i * y + x * yL j - xL i * yL j) * z + x * y * zL k - (xL i * y + x * yL j - xL i * yL j) * zL k⟧ =
    ⟦xL i * (y * z) + x * (yL j * z + y * zL k - yL j * zL k) - xL i * (yL j * z + y * zL k - yL j * zL k)⟧

Next tactic:
simp only [quot_sub, quot_add, quot_right_distrib_sub, quot_right_distrib,
                   quot_left_distrib_sub, quot_left_distrib]
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    -- Porting note: explicitly wrote out arguments to each recursive
    -- quot_mul_assoc reference below, because otherwise the decreasing_by block
    -- failed. Each branch previously ended with: `simp [quot_mul_assoc]; abel`
    -- See https://github.com/leanprover/lean4/issues/2288
    · rintro (⟨⟨i, j⟩ | ⟨i, j⟩, k⟩ | ⟨⟨i, j⟩ | ⟨i, j⟩, k⟩)
      · change
          ⟦(xL i * y + x * yL j - xL i * yL j) * z + x * y * zL k -
                (xL i * y + x * yL j - xL i * yL j) * zL k⟧ =
            ⟦xL i * (y * z) + x * (yL j * z + y * zL k - yL j * zL k) -
                xL i * (yL j * z + y * zL k - yL j * zL k)⟧
        simp only [quot_sub, quot_add, quot_right_distrib_sub, quot_right_distrib,
                   quot_left_distrib_sub, quot_left_distrib]
        

Proof state:
case refine'_3.inl.mk.inl.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
k : zl
i : xl
j : yl
⊢ ⟦xL i * mk yl yr yL yR * mk zl zr zL zR⟧ + ⟦mk xl xr xL xR * yL j * mk zl zr zL zR⟧ - ⟦xL i * yL j * mk zl zr zL zR⟧ +
        ⟦mk xl xr xL xR * mk yl yr yL yR * zL k⟧ -
      (⟦xL i * mk yl yr yL yR * zL k⟧ + ⟦mk xl xr xL xR * yL j * zL k⟧ - ⟦xL i * yL j * zL k⟧) =
    ⟦xL i * (mk yl yr yL yR * mk zl zr zL zR)⟧ +
        (⟦mk xl xr xL xR * (yL j * mk zl zr zL zR)⟧ + ⟦mk xl xr xL xR * (mk yl yr yL yR * zL k)⟧ -
          ⟦mk xl xr xL xR * (yL j * zL k)⟧) -
      (⟦xL i * (yL j * mk zl zr zL zR)⟧ + ⟦xL i * (mk yl yr yL yR * zL k)⟧ - ⟦xL i * (yL j * zL k)⟧)

Next tactic:
rw [quot_mul_assoc (xL i) (mk yl yr yL yR) (mk zl zr zL zR)]
theorem quot_mul_assoc (x y z : PGame) : (⟦x * y * z⟧ : Game) = ⟦x * (y * z)⟧ :=
  match x, y, z with
  | mk xl xr xL xR, mk yl yr yL yR, mk zl zr zL zR => by
    let x := mk xl xr xL xR
    let y := mk yl yr yL yR
    let z := mk zl zr zL zR
    refine' quot_eq_of_mk'_quot_eq _ _ _ _
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          -- Porting note: as above, increased the `maxDepth` here by 1.
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    · fconstructor
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;>
          solve_by_elim (config := { maxDepth := 8 }) [Sum.inl, Sum.inr, Prod.mk]
      · rintro (⟨⟨_, _⟩ | ⟨_, _⟩, _⟩ | ⟨⟨_, _⟩ | ⟨_, _⟩, _⟩) <;> rfl
      · rintro (⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩ | ⟨_, ⟨_, _⟩ | ⟨_, _⟩⟩) <;> rfl
    -- Porting note: explicitly wrote out arguments to each recursive
    -- quot_mul_assoc reference below, because otherwise the decreasing_by block
    -- failed. Each branch previously ended with: `simp [quot_mul_assoc]; abel`
    -- See https://github.com/leanprover/lean4/issues/2288
    · rintro (⟨⟨i, j⟩ | ⟨i, j⟩, k⟩ | ⟨⟨i, j⟩ | ⟨i, j⟩, k⟩)
      · change
          ⟦(xL i * y + x * yL j - xL i * yL j) * z + x * y * zL k -
                (xL i * y + x * yL j - xL i * yL j) * zL k⟧ =
            ⟦xL i * (y * z) + x * (yL j * z + y * zL k - yL j * zL k) -
                xL i * (yL j * z + y * zL k - yL j * zL k)⟧
        simp only [quot_sub, quot_add, quot_right_distrib_sub, quot_right_distrib,
                   quot_left_distrib_sub, quot_left_distrib]
        rw [quot_mul_assoc (xL i) (mk yl yr yL yR) (mk zl zr zL zR)]
        

Proof state:
case refine'_3.inl.mk.inl.mk
x✝ y✝ z✝ : PGame
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
zl zr : Type u_1
zL : zl → PGame
zR : zr → PGame
x : PGame := mk xl xr xL xR
y : PGame := mk yl yr yL yR
z : PGame := mk zl zr zL zR
k : zl
i : xl
j : yl
⊢ ⟦xL i * (mk yl yr yL yR * mk zl zr zL zR)⟧ + ⟦mk xl xr xL xR * yL j * mk zl zr zL zR⟧ -
          ⟦xL i * yL j * mk zl zr zL zR⟧ +
        ⟦mk xl xr xL xR * mk yl yr yL yR * zL k⟧ -
      (⟦xL i * mk yl yr yL yR * zL k⟧ + ⟦mk xl xr xL xR * yL j * zL k⟧ - ⟦xL i * yL j * zL k⟧) =
    ⟦xL i * (mk yl yr yL yR * mk zl zr zL zR)⟧ +
        (⟦mk xl xr xL xR * (yL j * mk zl zr zL zR)⟧ + ⟦mk xl xr xL xR * (mk yl yr yL yR * zL k)⟧ -
          ⟦mk xl xr xL xR * (yL j * zL k)⟧) -
      (⟦xL i * (yL j * mk zl zr zL zR)⟧ + ⟦xL i * (mk yl yr yL yR * zL k)⟧ - ⟦xL i * (yL j * zL k)⟧)

Next tactic:
rw [quot_mul_assoc (mk xl xr xL xR) (yL j) (mk zl zr zL zR)]