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

tactic: clear h
state_before: x y z : ℤ
h : PythagoreanTriple x y z
⊢ PythagoreanTriple x y z ∧ Int.gcd x y = 1 ↔
    ∃ m n,
      (x = m ^ 2 - n ^ 2 ∧ y = 2 * m * n ∨ x = 2 * m * n ∧ y = m ^ 2 - n ^ 2) ∧
        (z = m ^ 2 + n ^ 2 ∨ z = -(m ^ 2 + n ^ 2)) ∧ Int.gcd m n = 1 ∧ (m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0)

tactic: constructor
state_before: x y z : ℤ
⊢ PythagoreanTriple x y z ∧ Int.gcd x y = 1 ↔
    ∃ m n,
      (x = m ^ 2 - n ^ 2 ∧ y = 2 * m * n ∨ x = 2 * m * n ∧ y = m ^ 2 - n ^ 2) ∧
        (z = m ^ 2 + n ^ 2 ∨ z = -(m ^ 2 + n ^ 2)) ∧ Int.gcd m n = 1 ∧ (m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0)

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

tactic: obtain ⟨m, n, H⟩ := h.left.isPrimitiveClassified_of_coprime h.right
state_before: case mp
x y z : ℤ
h : PythagoreanTriple x y z ∧ Int.gcd x y = 1
⊢ ∃ m n,
    (x = m ^ 2 - n ^ 2 ∧ y = 2 * m * n ∨ x = 2 * m * n ∧ y = m ^ 2 - n ^ 2) ∧
      (z = m ^ 2 + n ^ 2 ∨ z = -(m ^ 2 + n ^ 2)) ∧ Int.gcd m n = 1 ∧ (m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0)

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

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

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

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

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

tactic: rw [sq, ← h.left.eq]
state_before: z m n : ℤ
h : PythagoreanTriple (m ^ 2 - n ^ 2) (2 * m * n) z ∧ Int.gcd (m ^ 2 - n ^ 2) (2 * m * n) = 1
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ z ^ 2 = (m ^ 2 + n ^ 2) ^ 2

tactic: ring
state_before: z m n : ℤ
h : PythagoreanTriple (m ^ 2 - n ^ 2) (2 * m * n) z ∧ Int.gcd (m ^ 2 - n ^ 2) (2 * m * n) = 1
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ (m ^ 2 - n ^ 2) * (m ^ 2 - n ^ 2) + 2 * m * n * (2 * m * n) = (m ^ 2 + n ^ 2) ^ 2

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

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

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

tactic: rw [sq, ← h.left.eq]
state_before: z m n : ℤ
h : PythagoreanTriple (2 * m * n) (m ^ 2 - n ^ 2) z ∧ Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ z ^ 2 = (m ^ 2 + n ^ 2) ^ 2

tactic: ring
state_before: z m n : ℤ
h : PythagoreanTriple (2 * m * n) (m ^ 2 - n ^ 2) z ∧ Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ 2 * m * n * (2 * m * n) + (m ^ 2 - n ^ 2) * (m ^ 2 - n ^ 2) = (m ^ 2 + n ^ 2) ^ 2

tactic: delta PythagoreanTriple
state_before: case mpr
x y z : ℤ
⊢ (∃ m n,
      (x = m ^ 2 - n ^ 2 ∧ y = 2 * m * n ∨ x = 2 * m * n ∧ y = m ^ 2 - n ^ 2) ∧
        (z = m ^ 2 + n ^ 2 ∨ z = -(m ^ 2 + n ^ 2)) ∧
          Int.gcd m n = 1 ∧ (m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0)) →
    PythagoreanTriple x y z ∧ Int.gcd x y = 1

tactic: rintro ⟨m, n, ⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, rfl | rfl, co, pp⟩ <;>
  first
  | constructor; ring; exact coprime_sq_sub_mul co pp
  | constructor; ring; rw [Int.gcd_comm]; exact coprime_sq_sub_mul co pp
state_before: case mpr
x y z : ℤ
⊢ (∃ m n,
      (x = m ^ 2 - n ^ 2 ∧ y = 2 * m * n ∨ x = 2 * m * n ∧ y = m ^ 2 - n ^ 2) ∧
        (z = m ^ 2 + n ^ 2 ∨ z = -(m ^ 2 + n ^ 2)) ∧
          Int.gcd m n = 1 ∧ (m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0)) →
    x * x + y * y = z * z ∧ Int.gcd x y = 1

tactic: constructor
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ 2 * m * n * (2 * m * n) + (m ^ 2 - n ^ 2) * (m ^ 2 - n ^ 2) = -(m ^ 2 + n ^ 2) * -(m ^ 2 + n ^ 2) ∧
    Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1

tactic: ring
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro.left
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ 2 * m * n * (2 * m * n) + (m ^ 2 - n ^ 2) * (m ^ 2 - n ^ 2) = -(m ^ 2 + n ^ 2) * -(m ^ 2 + n ^ 2)

case mpr.intro.intro.intro.inr.intro.intro.inr.intro.right
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1

tactic: exact coprime_sq_sub_mul co pp
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro.right
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1

tactic: constructor
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ 2 * m * n * (2 * m * n) + (m ^ 2 - n ^ 2) * (m ^ 2 - n ^ 2) = -(m ^ 2 + n ^ 2) * -(m ^ 2 + n ^ 2) ∧
    Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1

tactic: ring
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro.left
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ 2 * m * n * (2 * m * n) + (m ^ 2 - n ^ 2) * (m ^ 2 - n ^ 2) = -(m ^ 2 + n ^ 2) * -(m ^ 2 + n ^ 2)

case mpr.intro.intro.intro.inr.intro.intro.inr.intro.right
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1

tactic: rw [Int.gcd_comm]
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro.right
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ Int.gcd (2 * m * n) (m ^ 2 - n ^ 2) = 1

tactic: exact coprime_sq_sub_mul co pp
state_before: case mpr.intro.intro.intro.inr.intro.intro.inr.intro.right
m n : ℤ
co : Int.gcd m n = 1
pp : m % 2 = 0 ∧ n % 2 = 1 ∨ m % 2 = 1 ∧ n % 2 = 0
⊢ Int.gcd (m ^ 2 - n ^ 2) (2 * m * n) = 1