Theorem: SetTheory.PGame.equiv_nim_grundyValue
File: Mathlib/SetTheory/Game/Nim.lean

tactic: rw [Impartial.equiv_iff_add_equiv_zero, ← Impartial.forall_leftMoves_fuzzy_iff_equiv_zero]
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
⊢ x✝ ≈ nim x✝.grundyValue
state_after: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
⊢ ∀ (i : (x✝ + nim x✝.grundyValue).LeftMoves), (x✝ + nim x✝.grundyValue).moveLeft i ‖ 0

tactic: intro i
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
⊢ ∀ (i : (x✝ + nim x✝.grundyValue).LeftMoves), (x✝ + nim x✝.grundyValue).moveLeft i ‖ 0
state_after: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ (x✝ + nim x✝.grundyValue).moveLeft i ‖ 0

tactic: apply leftMoves_add_cases i
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ (x✝ + nim x✝.grundyValue).moveLeft i ‖ 0
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀ (i : x✝.LeftMoves), (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inl i)) ‖ 0

case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀ (i : (nim x✝.grundyValue).LeftMoves), (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inr i)) ‖ 0

tactic: intro i₁
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀ (i : x✝.LeftMoves), (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inl i)) ‖ 0
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inl i₁)) ‖ 0

tactic: rw [add_moveLeft_inl]
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inl i₁)) ‖ 0
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ x✝.moveLeft i₁ + nim x✝.grundyValue ‖ 0

tactic: apply
  (fuzzy_congr_left (add_congr_left (Equiv.symm (equiv_nim_grundyValue (G.moveLeft i₁))))).1
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ x✝.moveLeft i₁ + nim x✝.grundyValue ‖ 0
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ nim (G.moveLeft i₁).grundyValue + nim x✝.grundyValue ‖ 0

tactic: rw [nim_add_fuzzy_zero_iff]
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ nim (G.moveLeft i₁).grundyValue + nim x✝.grundyValue ‖ 0
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ (G.moveLeft i₁).grundyValue ≠ x✝.grundyValue

tactic: intro heq
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
⊢ (G.moveLeft i₁).grundyValue ≠ x✝.grundyValue
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (G.moveLeft i₁).grundyValue = x✝.grundyValue
⊢ False

tactic: rw [eq_comm, grundyValue_eq_mex_left G] at heq
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (G.moveLeft i₁).grundyValue = x✝.grundyValue
⊢ False
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (mex fun i => (G.moveLeft i).grundyValue) = (G.moveLeft i₁).grundyValue
⊢ False

tactic: have h := Ordinal.ne_mex.{u, u} (fun i ↦ grundyValue (moveLeft G i))
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (mex fun i => (G.moveLeft i).grundyValue) = (G.moveLeft i₁).grundyValue
⊢ False
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (mex fun i => (G.moveLeft i).grundyValue) = (G.moveLeft i₁).grundyValue
h : ∀ (i : G.LeftMoves), (G.moveLeft i).grundyValue ≠ mex fun i => (G.moveLeft i).grundyValue
⊢ False

tactic: rw [heq] at h
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (mex fun i => (G.moveLeft i).grundyValue) = (G.moveLeft i₁).grundyValue
h : ∀ (i : G.LeftMoves), (G.moveLeft i).grundyValue ≠ mex fun i => (G.moveLeft i).grundyValue
⊢ False
state_after: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (mex fun i => (G.moveLeft i).grundyValue) = (G.moveLeft i₁).grundyValue
h : ∀ (i : G.LeftMoves), (G.moveLeft i).grundyValue ≠ (G.moveLeft i₁).grundyValue
⊢ False

tactic: exact (h i₁).irrefl
state_before: case hl
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₁ : x✝.LeftMoves
heq : (mex fun i => (G.moveLeft i).grundyValue) = (G.moveLeft i₁).grundyValue
h : ∀ (i : G.LeftMoves), (G.moveLeft i).grundyValue ≠ (G.moveLeft i₁).grundyValue
⊢ False
state_after: no goals

tactic: intro i₂
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀ (i : (nim x✝.grundyValue).LeftMoves), (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inr i)) ‖ 0
state_after: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ : (nim x✝.grundyValue).LeftMoves
⊢ (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inr i₂)) ‖ 0

tactic: rw [add_moveLeft_inr, ← Impartial.exists_left_move_equiv_iff_fuzzy_zero]
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ : (nim x✝.grundyValue).LeftMoves
⊢ (x✝ + nim x✝.grundyValue).moveLeft (toLeftMovesAdd (Sum.inr i₂)) ‖ 0
state_after: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ : (nim x✝.grundyValue).LeftMoves
⊢ ∃ i, (x✝ + (nim x✝.grundyValue).moveLeft i₂).moveLeft i ≈ 0

tactic: revert i₂
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ : (nim x✝.grundyValue).LeftMoves
⊢ ∃ i, (x✝ + (nim x✝.grundyValue).moveLeft i₂).moveLeft i ≈ 0
state_after: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀ (i₂ : (nim x✝.grundyValue).LeftMoves), ∃ i, (x✝ + (nim x✝.grundyValue).moveLeft i₂).moveLeft i ≈ 0

tactic: rw [nim_def]
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀ (i₂ : (nim x✝.grundyValue).LeftMoves), ∃ i, (x✝ + (nim x✝.grundyValue).moveLeft i₂).moveLeft i ≈ 0
state_after: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀
    (i₂ :
      (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
          (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
          nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves),
    ∃ i,
      (x✝ +
              (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                    (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                    nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
                i₂).moveLeft
          i ≈
        0

tactic: intro i₂
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀
    (i₂ :
      (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
          (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
          nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves),
    ∃ i,
      (x✝ +
              (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                    (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                    nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
                i₂).moveLeft
          i ≈
        0
state_after: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
⊢ ∃ i,
    (x✝ +
            (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                  (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                  nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
              i₂).moveLeft
        i ≈
      0

tactic: have h' :
  ∃ i : G.LeftMoves,
    grundyValue (G.moveLeft i) = Ordinal.typein (Quotient.out (grundyValue G)).r i₂ := by
  revert i₂
  rw [grundyValue_eq_mex_left]
  intro i₂
  have hnotin : _ ∉ _ := fun hin =>
    (le_not_le_of_lt (Ordinal.typein_lt_self i₂)).2 (csInf_le' hin)
  simpa using hnotin
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
⊢ ∃ i,
    (x✝ +
            (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                  (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                  nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
              i₂).moveLeft
        i ≈
      0
state_after: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
h' : ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ ∃ i,
    (x✝ +
            (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                  (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                  nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
              i₂).moveLeft
        i ≈
      0

tactic: cases' h' with i hi
state_before: case hr
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
h' : ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ ∃ i,
    (x✝ +
            (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                  (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                  nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
              i₂).moveLeft
        i ≈
      0
state_after: case hr.intro
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ ∃ i,
    (x✝ +
            (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                  (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                  nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
              i₂).moveLeft
        i ≈
      0

tactic: use toLeftMovesAdd (Sum.inl i)
state_before: case hr.intro
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ ∃ i,
    (x✝ +
            (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                  (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                  nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
              i₂).moveLeft
        i ≈
      0
state_after: case h
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ (x✝ +
          (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
            i₂).moveLeft
      (toLeftMovesAdd (Sum.inl i)) ≈
    0

tactic: rw [add_moveLeft_inl, moveLeft_mk]
state_before: case h
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ (x✝ +
          (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
                (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
                nim (typein (fun x x_1 => x < x_1) o₂)).moveLeft
            i₂).moveLeft
      (toLeftMovesAdd (Sum.inl i)) ≈
    0
state_after: case h
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ x✝.moveLeft i + nim (typein (fun x x_1 => x < x_1) i₂) ≈ 0

tactic: apply Equiv.trans (add_congr_left (equiv_nim_grundyValue (G.moveLeft i)))
state_before: case h
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ x✝.moveLeft i + nim (typein (fun x x_1 => x < x_1) i₂) ≈ 0
state_after: case h
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ nim (G.moveLeft i).grundyValue + nim (typein (fun x x_1 => x < x_1) i₂) ≈ 0

tactic: simpa only [hi] using Impartial.add_self (nim (grundyValue (G.moveLeft i)))
state_before: case h
x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i✝ : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
⊢ nim (G.moveLeft i).grundyValue + nim (typein (fun x x_1 => x < x_1) i₂) ≈ 0
state_after: no goals

tactic: revert i₂
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
⊢ ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
state_after: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀
    (i₂ :
      (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
          (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
          nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves),
    ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂

tactic: rw [grundyValue_eq_mex_left]
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀
    (i₂ :
      (mk (Quotient.out x✝.grundyValue).α (Quotient.out x✝.grundyValue).α
          (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)) fun o₂ =>
          nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves),
    ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
state_after: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀
    (i₂ :
      (mk (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α
          (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
          fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves),
    ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).r i₂

tactic: intro i₂
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
⊢ ∀
    (i₂ :
      (mk (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α
          (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
          fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves),
    ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).r i₂
state_after: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α
      (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
⊢ ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).r i₂

tactic: have hnotin : _ ∉ _ := fun hin =>
  (le_not_le_of_lt (Ordinal.typein_lt_self i₂)).2 (csInf_le' hin)
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α
      (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
⊢ ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).r i₂
state_after: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α
      (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
hnotin : typein (fun x x_1 => x < x_1) i₂ ∉ (Set.range fun i => (x✝.moveLeft i).grundyValue)ᶜ
⊢ ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).r i₂

tactic: simpa using hnotin
state_before: x✝ : PGame
inst✝ : x✝.Impartial
G : PGame := x✝
i : (x✝ + nim x✝.grundyValue).LeftMoves
i₂ :
  (mk (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α
      (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
hnotin : typein (fun x x_1 => x < x_1) i₂ ∉ (Set.range fun i => (x✝.moveLeft i).grundyValue)ᶜ
⊢ ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out (mex fun i => (x✝.moveLeft i).grundyValue)).r i₂
state_after: no goals

tactic: all_goals pgame_wf_tac
state_before: G✝ : PGame
inst✝ : G✝.Impartial
a✝ :
  ∀ (y : (G : PGame) ×' G.Impartial),
    (invImage (fun x => PSigma.casesOn x fun G inst => G) instWellFoundedRelation).1 y ⟨G✝, inst✝⟩ →
      y.1 ≈ nim y.1.grundyValue
G : PGame := G✝
i₁ : G✝.LeftMoves
⊢ (invImage (fun x => PSigma.casesOn x fun G inst => G) instWellFoundedRelation).1 ⟨G.moveLeft i₁, ⋯⟩ ⟨G✝, inst✝⟩

G✝ : PGame
inst✝ : G✝.Impartial
a✝ :
  ∀ (y : (G : PGame) ×' G.Impartial),
    (invImage (fun x => PSigma.casesOn x fun G inst => G) instWellFoundedRelation).1 y ⟨G✝, inst✝⟩ →
      y.1 ≈ nim y.1.grundyValue
G : PGame := G✝
i₂ :
  (mk (Quotient.out G✝.grundyValue).α (Quotient.out G✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
h' : ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
h✝ : h' = ⋯
⊢ (invImage (fun x => PSigma.casesOn x fun G inst => G) instWellFoundedRelation).1 ⟨G.moveLeft i, ⋯⟩ ⟨G✝, inst✝⟩
state_after: no goals

tactic: pgame_wf_tac
state_before: G✝ : PGame
inst✝ : G✝.Impartial
a✝ :
  ∀ (y : (G : PGame) ×' G.Impartial),
    (invImage (fun x => PSigma.casesOn x fun G inst => G) instWellFoundedRelation).1 y ⟨G✝, inst✝⟩ →
      y.1 ≈ nim y.1.grundyValue
G : PGame := G✝
i₂ :
  (mk (Quotient.out G✝.grundyValue).α (Quotient.out G✝.grundyValue).α (fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂))
      fun o₂ => nim (typein (fun x x_1 => x < x_1) o₂)).LeftMoves
h' : ∃ i, (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
i : G.LeftMoves
hi : (G.moveLeft i).grundyValue = typein (Quotient.out G.grundyValue).r i₂
h✝ : h' = ⋯
⊢ (invImage (fun x => PSigma.casesOn x fun G inst => G) instWellFoundedRelation).1 ⟨G.moveLeft i, ⋯⟩ ⟨G✝, inst✝⟩
state_after: no goals