l3lab/ntp-mathlib huggingface dataset:
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> 

Proof state:
case refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
⊢ ((∀ (i' : LeftMoves x), moveLeft x i' ⧏ moveLeft y x_1) ∧
      ∀ (j : RightMoves (moveLeft y x_1)), x ⧏ moveRight (moveLeft y x_1) j) ↔
    (∀ (i' : LeftMoves x), moveLeft x i' < moveLeft y x_1) ∧
      ∀ (j : RightMoves (moveLeft y x_1)), x < moveRight (moveLeft y x_1) j

Next tactic:
refine' and_congr _ _
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> 

Proof state:
case refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
⊢ ((∀ (i : LeftMoves (moveRight x x_1)), moveLeft (moveRight x x_1) i ⧏ y) ∧
      ∀ (j' : RightMoves y), moveRight x x_1 ⧏ moveRight y j') ↔
    (∀ (i : LeftMoves (moveRight x x_1)), moveLeft (moveRight x x_1) i < y) ∧
      ∀ (j' : RightMoves y), moveRight x x_1 < moveRight y j'

Next tactic:
refine' and_congr _ _
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      

Proof state:
case refine'_1.refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
⊢ (∀ (i' : LeftMoves x), moveLeft x i' ⧏ moveLeft y x_1) ↔ ∀ (i' : LeftMoves x), moveLeft x i' < moveLeft y x_1

Next tactic:
refine' forall_congr' fun i => lf_iff_lt _ _
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      

Proof state:
case refine'_1.refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
⊢ (∀ (j : RightMoves (moveLeft y x_1)), x ⧏ moveRight (moveLeft y x_1) j) ↔
    ∀ (j : RightMoves (moveLeft y x_1)), x < moveRight (moveLeft y x_1) j

Next tactic:
refine' forall_congr' fun i => lf_iff_lt _ _
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      

Proof state:
case refine'_2.refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
⊢ (∀ (i : LeftMoves (moveRight x x_1)), moveLeft (moveRight x x_1) i ⧏ y) ↔
    ∀ (i : LeftMoves (moveRight x x_1)), moveLeft (moveRight x x_1) i < y

Next tactic:
refine' forall_congr' fun i => lf_iff_lt _ _
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      

Proof state:
case refine'_2.refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
⊢ (∀ (j' : RightMoves y), moveRight x x_1 ⧏ moveRight y j') ↔ ∀ (j' : RightMoves y), moveRight x x_1 < moveRight y j'

Next tactic:
refine' forall_congr' fun i => lf_iff_lt _ _
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_1.refine'_1.refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
i : LeftMoves x
⊢ Numeric (moveLeft x i)

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_1.refine'_1.refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
i : LeftMoves x
⊢ Numeric (moveLeft y x_1)

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_1.refine'_2.refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
i : RightMoves (moveLeft y x_1)
⊢ Numeric x

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_1.refine'_2.refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : LeftMoves y
i : RightMoves (moveLeft y x_1)
⊢ Numeric (moveRight (moveLeft y x_1) i)

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_2.refine'_1.refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
i : LeftMoves (moveRight x x_1)
⊢ Numeric (moveLeft (moveRight x x_1) i)

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_2.refine'_1.refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
i : LeftMoves (moveRight x x_1)
⊢ Numeric y

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_2.refine'_2.refine'_1
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
i : RightMoves y
⊢ Numeric (moveRight x x_1)

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
/-- The definition of `x < y` on numeric pre-games, in terms of `<` two moves later. -/
theorem lt_def {x y : PGame} (ox : x.Numeric) (oy : y.Numeric) :
    x < y ↔
      (∃ i, (∀ i', x.moveLeft i' < y.moveLeft i) ∧ ∀ j, x < (y.moveLeft i).moveRight j) ∨
        ∃ j, (∀ i, (x.moveRight j).moveLeft i < y) ∧ ∀ j', x.moveRight j < y.moveRight j' := by
  rw [← lf_iff_lt ox oy, lf_def]
  refine' or_congr _ _ <;> refine' exists_congr fun x_1 => _ <;> refine' and_congr _ _ <;>
      refine' forall_congr' fun i => lf_iff_lt _ _ <;>
    

Proof state:
case refine'_2.refine'_2.refine'_2
x y : PGame
ox : Numeric x
oy : Numeric y
x_1 : RightMoves x
i : RightMoves y
⊢ Numeric (moveRight y i)

Next tactic:
apply_rules [Numeric.moveLeft, Numeric.moveRight]
theorem add : ∀ {x y : PGame} (_ : Numeric x) (_ : Numeric y), Numeric (x + y)
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩, ox, oy =>
    ⟨by
      rintro (ix | iy) (jx | jy)
      · exact add_lt_add_right (ox.1 ix jx) _
      · exact (add_lf_add_of_lf_of_le (lf_mk _ _ ix) (oy.le_moveRight jy)).lt
          ((ox.moveLeft ix).add oy) (ox.add (oy.moveRight jy))
      · exact (add_lf_add_of_lf_of_le (mk_lf _ _ jx) (oy.moveLeft_le iy)).lt
          (ox.add (oy.moveLeft iy)) ((ox.moveRight jx).add oy)
      · exact add_lt_add_left (oy.1 iy jy) ⟨xl, xr, xL, xR⟩, by
      constructor
      · rintro (ix | iy)
        · 

Proof state:
case left.inl
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
ox : Numeric (PGame.mk xl xr xL xR)
oy : Numeric (PGame.mk yl yr yL yR)
ix : xl
⊢ Numeric
    ((fun t =>
        Sum.rec
          (fun i =>
            (fun a =>
                rec (motive := fun x => PGame → PGame)
                  (fun xl xr a a IHxl IHxr y =>
                    rec
                      (fun yl yr yL yR IHyl IHyr =>
                        let_fun y := PGame.mk yl yr yL yR;
                        PGame.mk (xl ⊕ yl) (xr ⊕ yr) (fun t => Sum.rec (fun i => IHxl i y) IHyl t) fun t =>
                          Sum.rec (fun i => IHxr i y) IHyr t)
                      y)
                  (xL a))
              i (PGame.mk yl yr yL yR))
          (fun a =>
            rec
              (fun yl yr yL yR IHyl IHyr =>
                let_fun y := PGame.mk yl yr yL yR;
                PGame.mk (xl ⊕ yl) (xr ⊕ yr)
                  (fun t =>
                    Sum.rec
                      (fun i =>
                        (fun a =>
                            rec (motive := fun x => PGame → PGame)
                              (fun xl xr a a IHxl IHxr y =>
                                rec
                                  (fun yl yr yL yR IHyl IHyr =>
                                    let_fun y := PGame.mk yl yr yL yR;
                                    PGame.mk (xl ⊕ yl) (xr ⊕ yr) (fun t => Sum.rec (fun i => IHxl i y) IHyl t) fun t =>
                                      Sum.rec (fun i => IHxr i y) IHyr t)
                                  y)
                              (xL a))
                          i y)
                      IHyl t)
                  fun t =>
                  Sum.rec
                    (fun i =>
                      (fun a =>
                          rec (motive := fun x => PGame → PGame)
                            (fun xl xr a a IHxl IHxr y =>
                              rec
                                (fun yl yr yL yR IHyl IHyr =>
                                  let_fun y := PGame.mk yl yr yL yR;
                                  PGame.mk (xl ⊕ yl) (xr ⊕ yr) (fun t => Sum.rec (fun i => IHxl i y) IHyl t) fun t =>
                                    Sum.rec (fun i => IHxr i y) IHyr t)
                                y)
                            (xR a))
                        i y)
                    IHyr t)
              (yL a))
          t)
      (Sum.inl ix))

Next tactic:
exact (ox.moveLeft ix).add oy
theorem add : ∀ {x y : PGame} (_ : Numeric x) (_ : Numeric y), Numeric (x + y)
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩, ox, oy =>
    ⟨by
      rintro (ix | iy) (jx | jy)
      · exact add_lt_add_right (ox.1 ix jx) _
      · exact (add_lf_add_of_lf_of_le (lf_mk _ _ ix) (oy.le_moveRight jy)).lt
          ((ox.moveLeft ix).add oy) (ox.add (oy.moveRight jy))
      · exact (add_lf_add_of_lf_of_le (mk_lf _ _ jx) (oy.moveLeft_le iy)).lt
          (ox.add (oy.moveLeft iy)) ((ox.moveRight jx).add oy)
      · exact add_lt_add_left (oy.1 iy jy) ⟨xl, xr, xL, xR⟩, by
      constructor
      · rintro (ix | iy)
        · exact (ox.moveLeft ix).add oy
        · 

Proof state:
case left.inr
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
ox : Numeric (PGame.mk xl xr xL xR)
oy : Numeric (PGame.mk yl yr yL yR)
iy : yl
⊢ Numeric
    ((fun t =>
        Sum.rec
          (fun i =>
            (fun a =>
                rec (motive := fun x => PGame → PGame)
                  (fun xl xr a a IHxl IHxr y =>
                    rec
                      (fun yl yr yL yR IHyl IHyr =>
                        let_fun y := PGame.mk yl yr yL yR;
                        PGame.mk (xl ⊕ yl) (xr ⊕ yr) (fun t => Sum.rec (fun i => IHxl i y) IHyl t) fun t =>
                          Sum.rec (fun i => IHxr i y) IHyr t)
                      y)
                  (xL a))
              i (PGame.mk yl yr yL yR))
          (fun a =>
            rec
              (fun yl yr yL yR IHyl IHyr =>
                let_fun y := PGame.mk yl yr yL yR;
                PGame.mk (xl ⊕ yl) (xr ⊕ yr)
                  (fun t =>
                    Sum.rec
                      (fun i =>
                        (fun a =>
                            rec (motive := fun x => PGame → PGame)
                              (fun xl xr a a IHxl IHxr y =>
                                rec
                                  (fun yl yr yL yR IHyl IHyr =>
                                    let_fun y := PGame.mk yl yr yL yR;
                                    PGame.mk (xl ⊕ yl) (xr ⊕ yr) (fun t => Sum.rec (fun i => IHxl i y) IHyl t) fun t =>
                                      Sum.rec (fun i => IHxr i y) IHyr t)
                                  y)
                              (xL a))
                          i y)
                      IHyl t)
                  fun t =>
                  Sum.rec
                    (fun i =>
                      (fun a =>
                          rec (motive := fun x => PGame → PGame)
                            (fun xl xr a a IHxl IHxr y =>
                              rec
                                (fun yl yr yL yR IHyl IHyr =>
                                  let_fun y := PGame.mk yl yr yL yR;
                                  PGame.mk (xl ⊕ yl) (xr ⊕ yr) (fun t => Sum.rec (fun i => IHxl i y) IHyl t) fun t =>
                                    Sum.rec (fun i => IHxr i y) IHyr t)
                                y)
                            (xR a))
                        i y)
                    IHyr t)
              (yL a))
          t)
      (Sum.inr iy))

Next tactic:
exact ox.add (oy.moveLeft iy)
theorem add : ∀ {x y : PGame} (_ : Numeric x) (_ : Numeric y), Numeric (x + y)
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩, ox, oy =>
    ⟨by
      rintro (ix | iy) (jx | jy)
      · exact add_lt_add_right (ox.1 ix jx) _
      · exact (add_lf_add_of_lf_of_le (lf_mk _ _ ix) (oy.le_moveRight jy)).lt
          ((ox.moveLeft ix).add oy) (ox.add (oy.moveRight jy))
      · exact (add_lf_add_of_lf_of_le (mk_lf _ _ jx) (oy.moveLeft_le iy)).lt
          (ox.add (oy.moveLeft iy)) ((ox.moveRight jx).add oy)
      · exact add_lt_add_left (oy.1 iy jy) ⟨xl, xr, xL, xR⟩, by
      constructor
      · rintro (ix | iy)
        · exact (ox.moveLeft ix).add oy
        · exact ox.add (oy.moveLeft iy)
      · rintro (jx | jy)
        · apply (ox.moveRight jx).add oy
        · apply ox.add (oy.moveRight jy)⟩
termination_by _ x y _ _ => (x, y) -- Porting note: Added `termination_by`
decreasing_by 

Proof state:
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
ox : Numeric (PGame.mk xl xr xL xR)
oy : Numeric (PGame.mk yl yr yL yR)
x✝ :
  ∀ (y : (x : PGame) ×' (x_1 : PGame) ×' (_ : Numeric x) ×' Numeric x_1),
    (invImage
            (fun a =>
              PSigma.casesOn a fun x snd => PSigma.casesOn snd fun y snd => PSigma.casesOn snd fun x_1 snd => (x, y))
            Prod.instWellFoundedRelationProd).1
        y { fst := PGame.mk xl xr xL xR, snd := { fst := PGame.mk yl yr yL yR, snd := { fst := ox, snd := oy } } } →
      Numeric (y.1 + y.2.1)
ix : xl
⊢ (invImage
        (fun a =>
          PSigma.casesOn a fun x snd => PSigma.casesOn snd fun y snd => PSigma.casesOn snd fun x_1 snd => (x, y))
        Prod.instWellFoundedRelationProd).1
    { fst := PGame.moveLeft (PGame.mk xl xr xL xR) ix,
      snd :=
        { fst := PGame.mk yl yr yL yR,
          snd := { fst := (_ : Numeric (PGame.moveLeft (PGame.mk xl xr xL xR) ix)), snd := oy } } }
    { fst := PGame.mk xl xr xL xR, snd := { fst := PGame.mk yl yr yL yR, snd := { fst := ox, snd := oy } } }

Next tactic:
pgame_wf_tac
theorem add : ∀ {x y : PGame} (_ : Numeric x) (_ : Numeric y), Numeric (x + y)
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩, ox, oy =>
    ⟨by
      rintro (ix | iy) (jx | jy)
      · exact add_lt_add_right (ox.1 ix jx) _
      · exact (add_lf_add_of_lf_of_le (lf_mk _ _ ix) (oy.le_moveRight jy)).lt
          ((ox.moveLeft ix).add oy) (ox.add (oy.moveRight jy))
      · exact (add_lf_add_of_lf_of_le (mk_lf _ _ jx) (oy.moveLeft_le iy)).lt
          (ox.add (oy.moveLeft iy)) ((ox.moveRight jx).add oy)
      · exact add_lt_add_left (oy.1 iy jy) ⟨xl, xr, xL, xR⟩, by
      constructor
      · rintro (ix | iy)
        · exact (ox.moveLeft ix).add oy
        · exact ox.add (oy.moveLeft iy)
      · rintro (jx | jy)
        · apply (ox.moveRight jx).add oy
        · apply ox.add (oy.moveRight jy)⟩
termination_by _ x y _ _ => (x, y) -- Porting note: Added `termination_by`
decreasing_by 

Proof state:
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
ox : Numeric (PGame.mk xl xr xL xR)
oy : Numeric (PGame.mk yl yr yL yR)
x✝ :
  ∀ (y : (x : PGame) ×' (x_1 : PGame) ×' (_ : Numeric x) ×' Numeric x_1),
    (invImage
            (fun a =>
              PSigma.casesOn a fun x snd => PSigma.casesOn snd fun y snd => PSigma.casesOn snd fun x_1 snd => (x, y))
            Prod.instWellFoundedRelationProd).1
        y { fst := PGame.mk xl xr xL xR, snd := { fst := PGame.mk yl yr yL yR, snd := { fst := ox, snd := oy } } } →
      Numeric (y.1 + y.2.1)
jy : yr
⊢ (invImage
        (fun a =>
          PSigma.casesOn a fun x snd => PSigma.casesOn snd fun y snd => PSigma.casesOn snd fun x_1 snd => (x, y))
        Prod.instWellFoundedRelationProd).1
    { fst := PGame.mk xl xr xL xR,
      snd :=
        { fst := PGame.moveRight (PGame.mk yl yr yL yR) jy,
          snd := { fst := ox, snd := (_ : Numeric (PGame.moveRight (PGame.mk yl yr yL yR) jy)) } } }
    { fst := PGame.mk xl xr xL xR, snd := { fst := PGame.mk yl yr yL yR, snd := { fst := ox, snd := oy } } }

Next tactic:
pgame_wf_tac
theorem add : ∀ {x y : PGame} (_ : Numeric x) (_ : Numeric y), Numeric (x + y)
  | ⟨xl, xr, xL, xR⟩, ⟨yl, yr, yL, yR⟩, ox, oy =>
    ⟨by
      rintro (ix | iy) (jx | jy)
      · exact add_lt_add_right (ox.1 ix jx) _
      · exact (add_lf_add_of_lf_of_le (lf_mk _ _ ix) (oy.le_moveRight jy)).lt
          ((ox.moveLeft ix).add oy) (ox.add (oy.moveRight jy))
      · exact (add_lf_add_of_lf_of_le (mk_lf _ _ jx) (oy.moveLeft_le iy)).lt
          (ox.add (oy.moveLeft iy)) ((ox.moveRight jx).add oy)
      · exact add_lt_add_left (oy.1 iy jy) ⟨xl, xr, xL, xR⟩, by
      constructor
      · rintro (ix | iy)
        · exact (ox.moveLeft ix).add oy
        · exact ox.add (oy.moveLeft iy)
      · rintro (jx | jy)
        · apply (ox.moveRight jx).add oy
        · apply ox.add (oy.moveRight jy)⟩
termination_by _ x y _ _ => (x, y) -- Porting note: Added `termination_by`
decreasing_by 

Proof state:
xl xr : Type u_1
xL : xl → PGame
xR : xr → PGame
yl yr : Type u_1
yL : yl → PGame
yR : yr → PGame
ox : Numeric (PGame.mk xl xr xL xR)
oy : Numeric (PGame.mk yl yr yL yR)
x✝ :
  ∀ (y : (x : PGame) ×' (x_1 : PGame) ×' (_ : Numeric x) ×' Numeric x_1),
    (invImage
            (fun a =>
              PSigma.casesOn a fun x snd => PSigma.casesOn snd fun y snd => PSigma.casesOn snd fun x_1 snd => (x, y))
            Prod.instWellFoundedRelationProd).1
        y { fst := PGame.mk xl xr xL xR, snd := { fst := PGame.mk yl yr yL yR, snd := { fst := ox, snd := oy } } } →
      Numeric (y.1 + y.2.1)
iy : yl
⊢ (invImage
        (fun a =>
          PSigma.casesOn a fun x snd => PSigma.casesOn snd fun y snd => PSigma.casesOn snd fun x_1 snd => (x, y))
        Prod.instWellFoundedRelationProd).1
    { fst := PGame.mk xl xr xL xR,
      snd :=
        { fst := PGame.moveLeft (PGame.mk yl yr yL yR) iy,
          snd := { fst := ox, snd := (_ : Numeric (PGame.moveLeft (PGame.mk yl yr yL yR) iy)) } } }
    { fst := PGame.mk xl xr xL xR, snd := { fst := PGame.mk yl yr yL yR, snd := { fst := ox, snd := oy } } }

Next tactic:
pgame_wf_tac