Theorem: PythagoreanTriple.classification
File: Mathlib/NumberTheory/PythagoreanTriples.lean

tactic: constructor
state_before: x y z : ℤ
h : PythagoreanTriple x y z
⊢ PythagoreanTriple x y z ↔
    ∃ k m n,
      (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧
        (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: intro h
state_before: case mp
x y z : ℤ
h : PythagoreanTriple x y z
⊢ PythagoreanTriple x y z →
    ∃ k m n,
      (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧
        (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: obtain ⟨k, m, n, H⟩ := h.classified
state_before: case mp
x y z : ℤ
h✝ h : PythagoreanTriple x y z
⊢ ∃ k m n,
    (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧
      (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: use k, m, n
state_before: case mp.intro.intro.intro
x y z : ℤ
h✝ h : PythagoreanTriple x y z
k m n : ℤ
H : (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧ Int.gcd m n = 1
⊢ ∃ k m n,
    (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧
      (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: rcases H with (⟨rfl, rfl⟩ | ⟨rfl, rfl⟩)
state_before: case mp.intro.intro.intro
x y z : ℤ
h✝ h : PythagoreanTriple x y z
k m n : ℤ
H : (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧ Int.gcd m n = 1
⊢ (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧
    (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: refine' ⟨Or.inl ⟨rfl, rfl⟩, _⟩
state_before: case mp.intro.intro.intro.intro.inl.intro
z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (m ^ 2 - n ^ 2)) (k * (2 * m * n)) z
⊢ (k * (m ^ 2 - n ^ 2) = k * (m ^ 2 - n ^ 2) ∧ k * (2 * m * n) = k * (2 * m * n) ∨
      k * (m ^ 2 - n ^ 2) = k * (2 * m * n) ∧ k * (2 * m * n) = k * (m ^ 2 - n ^ 2)) ∧
    (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: have : z ^ 2 = (k * (m ^ 2 + n ^ 2)) ^ 2 := by
  rw [sq, ← h.eq]
  ring
state_before: case mp.intro.intro.intro.intro.inl.intro
z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (m ^ 2 - n ^ 2)) (k * (2 * m * n)) z
⊢ z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2)

tactic: simpa using eq_or_eq_neg_of_sq_eq_sq _ _ this
state_before: case mp.intro.intro.intro.intro.inl.intro
z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (m ^ 2 - n ^ 2)) (k * (2 * m * n)) z
this : z ^ 2 = (k * (m ^ 2 + n ^ 2)) ^ 2
⊢ z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2)

tactic: rw [sq, ← h.eq]
state_before: z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (m ^ 2 - n ^ 2)) (k * (2 * m * n)) z
⊢ z ^ 2 = (k * (m ^ 2 + n ^ 2)) ^ 2

tactic: ring
state_before: z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (m ^ 2 - n ^ 2)) (k * (2 * m * n)) z
⊢ k * (m ^ 2 - n ^ 2) * (k * (m ^ 2 - n ^ 2)) + k * (2 * m * n) * (k * (2 * m * n)) = (k * (m ^ 2 + n ^ 2)) ^ 2

tactic: refine' ⟨Or.inr ⟨rfl, rfl⟩, _⟩
state_before: case mp.intro.intro.intro.intro.inr.intro
z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (2 * m * n)) (k * (m ^ 2 - n ^ 2)) z
⊢ (k * (2 * m * n) = k * (m ^ 2 - n ^ 2) ∧ k * (m ^ 2 - n ^ 2) = k * (2 * m * n) ∨
      k * (2 * m * n) = k * (2 * m * n) ∧ k * (m ^ 2 - n ^ 2) = k * (m ^ 2 - n ^ 2)) ∧
    (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))

tactic: have : z ^ 2 = (k * (m ^ 2 + n ^ 2)) ^ 2 := by
  rw [sq, ← h.eq]
  ring
state_before: case mp.intro.intro.intro.intro.inr.intro
z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (2 * m * n)) (k * (m ^ 2 - n ^ 2)) z
⊢ z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2)

tactic: simpa using eq_or_eq_neg_of_sq_eq_sq _ _ this
state_before: case mp.intro.intro.intro.intro.inr.intro
z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (2 * m * n)) (k * (m ^ 2 - n ^ 2)) z
this : z ^ 2 = (k * (m ^ 2 + n ^ 2)) ^ 2
⊢ z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2)

tactic: rw [sq, ← h.eq]
state_before: z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (2 * m * n)) (k * (m ^ 2 - n ^ 2)) z
⊢ z ^ 2 = (k * (m ^ 2 + n ^ 2)) ^ 2

tactic: ring
state_before: z k m n : ℤ
right✝ : Int.gcd m n = 1
h✝ h : PythagoreanTriple (k * (2 * m * n)) (k * (m ^ 2 - n ^ 2)) z
⊢ k * (2 * m * n) * (k * (2 * m * n)) + k * (m ^ 2 - n ^ 2) * (k * (m ^ 2 - n ^ 2)) = (k * (m ^ 2 + n ^ 2)) ^ 2

tactic: rintro ⟨k, m, n, ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, rfl | rfl⟩ <;> delta PythagoreanTriple <;> ring
state_before: case mpr
x y z : ℤ
h : PythagoreanTriple x y z
⊢ (∃ k m n,
      (x = k * (m ^ 2 - n ^ 2) ∧ y = k * (2 * m * n) ∨ x = k * (2 * m * n) ∧ y = k * (m ^ 2 - n ^ 2)) ∧
        (z = k * (m ^ 2 + n ^ 2) ∨ z = -k * (m ^ 2 + n ^ 2))) →
    PythagoreanTriple x y z