l3lab/ntp-mathlib huggingface dataset:
theorem range_toLp [NormedField 𝕜] [NormedSpace 𝕜 E] :
    (LinearMap.range (toLp p μ 𝕜 : C(α, E) →L[𝕜] Lp E p μ)).toAddSubgroup =
      MeasureTheory.Lp.boundedContinuousFunction E p μ := by
  refine' SetLike.ext' _
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedAddCommGroup F
inst✝⁸ : NormedAddCommGroup G
inst✝⁷ : TopologicalSpace α
inst✝⁶ : BorelSpace α
inst✝⁵ : SecondCountableTopologyEither α E
inst✝⁴ : CompactSpace α
inst✝³ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝² : Fact (1 ≤ p)
inst✝¹ : NormedField 𝕜
inst✝ : NormedSpace 𝕜 E
⊢ ↑(Submodule.toAddSubgroup (LinearMap.range (toLp p μ 𝕜))) = ↑(Lp.boundedContinuousFunction E p μ)

Next tactic:
have := (linearIsometryBoundedOfCompact α E 𝕜).surjective
theorem range_toLp [NormedField 𝕜] [NormedSpace 𝕜 E] :
    (LinearMap.range (toLp p μ 𝕜 : C(α, E) →L[𝕜] Lp E p μ)).toAddSubgroup =
      MeasureTheory.Lp.boundedContinuousFunction E p μ := by
  refine' SetLike.ext' _
  have := (linearIsometryBoundedOfCompact α E 𝕜).surjective
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedAddCommGroup F
inst✝⁸ : NormedAddCommGroup G
inst✝⁷ : TopologicalSpace α
inst✝⁶ : BorelSpace α
inst✝⁵ : SecondCountableTopologyEither α E
inst✝⁴ : CompactSpace α
inst✝³ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝² : Fact (1 ≤ p)
inst✝¹ : NormedField 𝕜
inst✝ : NormedSpace 𝕜 E
this : Function.Surjective ⇑(linearIsometryBoundedOfCompact α E 𝕜)
⊢ ↑(Submodule.toAddSubgroup (LinearMap.range (toLp p μ 𝕜))) = ↑(Lp.boundedContinuousFunction E p μ)

Next tactic:
convert Function.Surjective.range_comp this (BoundedContinuousFunction.toLp (E := E) p μ 𝕜)
theorem range_toLp [NormedField 𝕜] [NormedSpace 𝕜 E] :
    (LinearMap.range (toLp p μ 𝕜 : C(α, E) →L[𝕜] Lp E p μ)).toAddSubgroup =
      MeasureTheory.Lp.boundedContinuousFunction E p μ := by
  refine' SetLike.ext' _
  have := (linearIsometryBoundedOfCompact α E 𝕜).surjective
  convert Function.Surjective.range_comp this (BoundedContinuousFunction.toLp (E := E) p μ 𝕜)
  

Proof state:
case h.e'_3
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedAddCommGroup F
inst✝⁸ : NormedAddCommGroup G
inst✝⁷ : TopologicalSpace α
inst✝⁶ : BorelSpace α
inst✝⁵ : SecondCountableTopologyEither α E
inst✝⁴ : CompactSpace α
inst✝³ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝² : Fact (1 ≤ p)
inst✝¹ : NormedField 𝕜
inst✝ : NormedSpace 𝕜 E
this : Function.Surjective ⇑(linearIsometryBoundedOfCompact α E 𝕜)
⊢ ↑(Lp.boundedContinuousFunction E p μ) = Set.range ⇑(BoundedContinuousFunction.toLp p μ 𝕜)

Next tactic:
rw [← BoundedContinuousFunction.range_toLp p μ (𝕜 := 𝕜), Submodule.coe_toAddSubgroup,
    LinearMap.range_coe]
/-- If a sum of continuous functions `g n` is convergent, and the same sum converges in `Lᵖ` to `h`,
then in fact `g n` converges uniformly to `h`.  -/
theorem hasSum_of_hasSum_Lp {β : Type*} [μ.IsOpenPosMeasure] [NormedField 𝕜] [NormedSpace 𝕜 E]
    {g : β → C(α, E)} {f : C(α, E)} (hg : Summable g)
    (hg2 : HasSum (toLp (E := E) p μ 𝕜 ∘ g) (toLp (E := E) p μ 𝕜 f)) : HasSum g f := by
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹¹ : NormedAddCommGroup E
inst✝¹⁰ : NormedAddCommGroup F
inst✝⁹ : NormedAddCommGroup G
inst✝⁸ : TopologicalSpace α
inst✝⁷ : BorelSpace α
inst✝⁶ : SecondCountableTopologyEither α E
inst✝⁵ : CompactSpace α
inst✝⁴ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝³ : Fact (1 ≤ p)
β : Type u_6
inst✝² : Measure.IsOpenPosMeasure μ
inst✝¹ : NormedField 𝕜
inst✝ : NormedSpace 𝕜 E
g : β → C(α, E)
f : C(α, E)
hg : Summable g
hg2 : HasSum (⇑(toLp p μ 𝕜) ∘ g) ((toLp p μ 𝕜) f)
⊢ HasSum g f

Next tactic:
convert Summable.hasSum hg
/-- If a sum of continuous functions `g n` is convergent, and the same sum converges in `Lᵖ` to `h`,
then in fact `g n` converges uniformly to `h`.  -/
theorem hasSum_of_hasSum_Lp {β : Type*} [μ.IsOpenPosMeasure] [NormedField 𝕜] [NormedSpace 𝕜 E]
    {g : β → C(α, E)} {f : C(α, E)} (hg : Summable g)
    (hg2 : HasSum (toLp (E := E) p μ 𝕜 ∘ g) (toLp (E := E) p μ 𝕜 f)) : HasSum g f := by
  convert Summable.hasSum hg
  

Proof state:
case h.e'_6
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹¹ : NormedAddCommGroup E
inst✝¹⁰ : NormedAddCommGroup F
inst✝⁹ : NormedAddCommGroup G
inst✝⁸ : TopologicalSpace α
inst✝⁷ : BorelSpace α
inst✝⁶ : SecondCountableTopologyEither α E
inst✝⁵ : CompactSpace α
inst✝⁴ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝³ : Fact (1 ≤ p)
β : Type u_6
inst✝² : Measure.IsOpenPosMeasure μ
inst✝¹ : NormedField 𝕜
inst✝ : NormedSpace 𝕜 E
g : β → C(α, E)
f : C(α, E)
hg : Summable g
hg2 : HasSum (⇑(toLp p μ 𝕜) ∘ g) ((toLp p μ 𝕜) f)
⊢ f = ∑' (b : β), g b

Next tactic:
exact toLp_injective μ (hg2.unique ((toLp p μ 𝕜).hasSum <| Summable.hasSum hg))
/-- Bound for the operator norm of `ContinuousMap.toLp`. -/
theorem toLp_norm_le :
    ‖(toLp p μ 𝕜 : C(α, E) →L[𝕜] Lp E p μ)‖ ≤ measureUnivNNReal μ ^ p.toReal⁻¹ := by
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedAddCommGroup F
inst✝⁸ : NormedAddCommGroup G
inst✝⁷ : TopologicalSpace α
inst✝⁶ : BorelSpace α
inst✝⁵ : SecondCountableTopologyEither α E
inst✝⁴ : CompactSpace α
inst✝³ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝² : Fact (1 ≤ p)
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedSpace 𝕜 E
⊢ ‖toLp p μ 𝕜‖ ≤ ↑(measureUnivNNReal μ) ^ (ENNReal.toReal p)⁻¹

Next tactic:
rw [toLp_norm_eq_toLp_norm_coe]
/-- Bound for the operator norm of `ContinuousMap.toLp`. -/
theorem toLp_norm_le :
    ‖(toLp p μ 𝕜 : C(α, E) →L[𝕜] Lp E p μ)‖ ≤ measureUnivNNReal μ ^ p.toReal⁻¹ := by
  rw [toLp_norm_eq_toLp_norm_coe]
  

Proof state:
α : Type u_1
E : Type u_2
F : Type u_3
G : Type u_4
m m0 : MeasurableSpace α
p : ℝ≥0∞
q : ℝ
μ ν : Measure α
inst✝¹⁰ : NormedAddCommGroup E
inst✝⁹ : NormedAddCommGroup F
inst✝⁸ : NormedAddCommGroup G
inst✝⁷ : TopologicalSpace α
inst✝⁶ : BorelSpace α
inst✝⁵ : SecondCountableTopologyEither α E
inst✝⁴ : CompactSpace α
inst✝³ : IsFiniteMeasure μ
𝕜 : Type u_5
inst✝² : Fact (1 ≤ p)
inst✝¹ : NontriviallyNormedField 𝕜
inst✝ : NormedSpace 𝕜 E
⊢ ‖BoundedContinuousFunction.toLp p μ 𝕜‖ ≤ ↑(measureUnivNNReal μ) ^ (ENNReal.toReal p)⁻¹

Next tactic:
exact BoundedContinuousFunction.toLp_norm_le μ
theorem sq_ne_two_fin_zmod_four (z : ZMod 4) : z * z ≠ 2 := by
  

Proof state:
z : ZMod 4
⊢ z * z ≠ 2

Next tactic:
change Fin 4 at z
theorem sq_ne_two_fin_zmod_four (z : ZMod 4) : z * z ≠ 2 := by
  change Fin 4 at z
  

Proof state:
z : Fin 4
⊢ z * z ≠ 2

Next tactic:
fin_cases z
theorem sq_ne_two_fin_zmod_four (z : ZMod 4) : z * z ≠ 2 := by
  change Fin 4 at z
  fin_cases z <;> 

Proof state:
case head
⊢ { val := 0, isLt := (_ : 0 < 4) } * { val := 0, isLt := (_ : 0 < 4) } ≠ 2

Next tactic:
decide
theorem sq_ne_two_fin_zmod_four (z : ZMod 4) : z * z ≠ 2 := by
  change Fin 4 at z
  fin_cases z <;> 

Proof state:
case tail.head
⊢ { val := 1, isLt := (_ : (fun a => a < 4) 1) } * { val := 1, isLt := (_ : (fun a => a < 4) 1) } ≠ 2

Next tactic:
decide
theorem sq_ne_two_fin_zmod_four (z : ZMod 4) : z * z ≠ 2 := by
  change Fin 4 at z
  fin_cases z <;> 

Proof state:
case tail.tail.head
⊢ { val := 2, isLt := (_ : (fun a => (fun a => a < 4) a) 2) } *
      { val := 2, isLt := (_ : (fun a => (fun a => a < 4) a) 2) } ≠
    2

Next tactic:
decide
theorem sq_ne_two_fin_zmod_four (z : ZMod 4) : z * z ≠ 2 := by
  change Fin 4 at z
  fin_cases z <;> 

Proof state:
case tail.tail.tail.head
⊢ { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 4) a) a) 3) } *
      { val := 3, isLt := (_ : (fun a => (fun a => (fun a => a < 4) a) a) 3) } ≠
    2

Next tactic:
decide
theorem Int.sq_ne_two_mod_four (z : ℤ) : z * z % 4 ≠ 2 := by
  

Proof state:
z : ℤ
⊢ z * z % 4 ≠ 2

Next tactic:
suffices ¬z * z % (4 : ℕ) = 2 % (4 : ℕ) by exact this
theorem Int.sq_ne_two_mod_four (z : ℤ) : z * z % 4 ≠ 2 := by
  suffices ¬z * z % (4 : ℕ) = 2 % (4 : ℕ) by 

Proof state:
z : ℤ
this : ¬z * z % ↑4 = 2 % ↑4
⊢ z * z % 4 ≠ 2

Next tactic:
exact this
theorem Int.sq_ne_two_mod_four (z : ℤ) : z * z % 4 ≠ 2 := by
  suffices ¬z * z % (4 : ℕ) = 2 % (4 : ℕ) by exact this
  

Proof state:
z : ℤ
⊢ ¬z * z % ↑4 = 2 % ↑4

Next tactic:
rw [← ZMod.int_cast_eq_int_cast_iff']
theorem Int.sq_ne_two_mod_four (z : ℤ) : z * z % 4 ≠ 2 := by
  suffices ¬z * z % (4 : ℕ) = 2 % (4 : ℕ) by exact this
  rw [← ZMod.int_cast_eq_int_cast_iff']
  

Proof state:
z : ℤ
⊢ ¬↑(z * z) = ↑2

Next tactic:
simpa using sq_ne_two_fin_zmod_four _
/-- Pythagorean triples are interchangeable, i.e `x * x + y * y = y * y + x * x = z * z`.
This comes from additive commutativity. -/
theorem pythagoreanTriple_comm {x y z : ℤ} : PythagoreanTriple x y z ↔ PythagoreanTriple y x z := by
  

Proof state:
x y z : ℤ
⊢ PythagoreanTriple x y z ↔ PythagoreanTriple y x z

Next tactic:
delta PythagoreanTriple
/-- Pythagorean triples are interchangeable, i.e `x * x + y * y = y * y + x * x = z * z`.
This comes from additive commutativity. -/
theorem pythagoreanTriple_comm {x y z : ℤ} : PythagoreanTriple x y z ↔ PythagoreanTriple y x z := by
  delta PythagoreanTriple
  

Proof state:
x y z : ℤ
⊢ x * x + y * y = z * z ↔ y * y + x * x = z * z

Next tactic:
rw [add_comm]
/-- The zeroth Pythagorean triple is all zeros. -/
theorem PythagoreanTriple.zero : PythagoreanTriple 0 0 0 := by
  

Proof state:
⊢ PythagoreanTriple 0 0 0

Next tactic:
simp only [PythagoreanTriple, zero_mul, zero_add]
@[symm]
theorem symm : PythagoreanTriple y x z := by 

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
⊢ PythagoreanTriple y x z

Next tactic:
rwa [pythagoreanTriple_comm]
/-- A triple is still a triple if you multiply `x`, `y` and `z`
by a constant `k`. -/
theorem mul (k : ℤ) : PythagoreanTriple (k * x) (k * y) (k * z) :=
  calc
    k * x * (k * x) + k * y * (k * y) = k ^ 2 * (x * x + y * y) := by 

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
⊢ k * x * (k * x) + k * y * (k * y) = k ^ 2 * (x * x + y * y)

Next tactic:
ring
/-- A triple is still a triple if you multiply `x`, `y` and `z`
by a constant `k`. -/
theorem mul (k : ℤ) : PythagoreanTriple (k * x) (k * y) (k * z) :=
  calc
    k * x * (k * x) + k * y * (k * y) = k ^ 2 * (x * x + y * y) := by ring
    _ = k ^ 2 * (z * z) := by 

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
⊢ k ^ 2 * (x * x + y * y) = k ^ 2 * (z * z)

Next tactic:
rw [h.eq]
/-- A triple is still a triple if you multiply `x`, `y` and `z`
by a constant `k`. -/
theorem mul (k : ℤ) : PythagoreanTriple (k * x) (k * y) (k * z) :=
  calc
    k * x * (k * x) + k * y * (k * y) = k ^ 2 * (x * x + y * y) := by ring
    _ = k ^ 2 * (z * z) := by rw [h.eq]
    _ = k * z * (k * z) := by 

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
⊢ k ^ 2 * (z * z) = k * z * (k * z)

Next tactic:
ring
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
⊢ PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z

Next tactic:
refine' ⟨_, fun h => h.mul k⟩
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  refine' ⟨_, fun h => h.mul k⟩
  

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
⊢ PythagoreanTriple (k * x) (k * y) (k * z) → PythagoreanTriple x y z

Next tactic:
simp only [PythagoreanTriple]
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  refine' ⟨_, fun h => h.mul k⟩
  simp only [PythagoreanTriple]
  

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
⊢ k * x * (k * x) + k * y * (k * y) = k * z * (k * z) → x * x + y * y = z * z

Next tactic:
intro h
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  refine' ⟨_, fun h => h.mul k⟩
  simp only [PythagoreanTriple]
  intro h
  

Proof state:
x y z : ℤ
h✝ : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
h : k * x * (k * x) + k * y * (k * y) = k * z * (k * z)
⊢ x * x + y * y = z * z

Next tactic:
rw [← mul_left_inj' (mul_ne_zero hk hk)]
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  refine' ⟨_, fun h => h.mul k⟩
  simp only [PythagoreanTriple]
  intro h
  rw [← mul_left_inj' (mul_ne_zero hk hk)]
  

Proof state:
x y z : ℤ
h✝ : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
h : k * x * (k * x) + k * y * (k * y) = k * z * (k * z)
⊢ (x * x + y * y) * (k * k) = z * z * (k * k)

Next tactic:
convert h using 1
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  refine' ⟨_, fun h => h.mul k⟩
  simp only [PythagoreanTriple]
  intro h
  rw [← mul_left_inj' (mul_ne_zero hk hk)]
  convert h using 1 <;> 

Proof state:
case h.e'_2
x y z : ℤ
h✝ : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
h : k * x * (k * x) + k * y * (k * y) = k * z * (k * z)
⊢ (x * x + y * y) * (k * k) = k * x * (k * x) + k * y * (k * y)

Next tactic:
ring
/-- `(k*x, k*y, k*z)` is a Pythagorean triple if and only if
`(x, y, z)` is also a triple. -/
theorem mul_iff (k : ℤ) (hk : k ≠ 0) :
    PythagoreanTriple (k * x) (k * y) (k * z) ↔ PythagoreanTriple x y z := by
  refine' ⟨_, fun h => h.mul k⟩
  simp only [PythagoreanTriple]
  intro h
  rw [← mul_left_inj' (mul_ne_zero hk hk)]
  convert h using 1 <;> 

Proof state:
case h.e'_3
x y z : ℤ
h✝ : PythagoreanTriple x y z
k : ℤ
hk : k ≠ 0
h : k * x * (k * x) + k * y * (k * y) = k * z * (k * z)
⊢ z * z * (k * k) = k * z * (k * z)

Next tactic:
ring
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
k : ℤ
hc : IsClassified h
⊢ IsClassified (_ : PythagoreanTriple (k * x) (k * y) (k * z))

Next tactic:
obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · 

Proof state:
case intro.intro.intro.intro.inl.intro
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (m ^ 2 - n ^ 2)) (l * (2 * m * n)) z
⊢ IsClassified (_ : PythagoreanTriple (k * (l * (m ^ 2 - n ^ 2))) (k * (l * (2 * m * n))) (k * z))

Next tactic:
use k * l, m, n
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    

Proof state:
case h
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (m ^ 2 - n ^ 2)) (l * (2 * m * n)) z
⊢ (k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2) ∧ k * (l * (2 * m * n)) = k * l * (2 * m * n) ∨
      k * (l * (m ^ 2 - n ^ 2)) = k * l * (2 * m * n) ∧ k * (l * (2 * m * n)) = k * l * (m ^ 2 - n ^ 2)) ∧
    Int.gcd m n = 1

Next tactic:
apply And.intro _ co
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    

Proof state:
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (m ^ 2 - n ^ 2)) (l * (2 * m * n)) z
⊢ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2) ∧ k * (l * (2 * m * n)) = k * l * (2 * m * n) ∨
    k * (l * (m ^ 2 - n ^ 2)) = k * l * (2 * m * n) ∧ k * (l * (2 * m * n)) = k * l * (m ^ 2 - n ^ 2)

Next tactic:
left
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    

Proof state:
case h
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (m ^ 2 - n ^ 2)) (l * (2 * m * n)) z
⊢ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2) ∧ k * (l * (2 * m * n)) = k * l * (2 * m * n)

Next tactic:
constructor
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> 

Proof state:
case h.left
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (m ^ 2 - n ^ 2)) (l * (2 * m * n)) z
⊢ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2)

Next tactic:
ring
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> 

Proof state:
case h.right
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (m ^ 2 - n ^ 2)) (l * (2 * m * n)) z
⊢ k * (l * (2 * m * n)) = k * l * (2 * m * n)

Next tactic:
ring
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> ring
  · 

Proof state:
case intro.intro.intro.intro.inr.intro
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (2 * m * n)) (l * (m ^ 2 - n ^ 2)) z
⊢ IsClassified (_ : PythagoreanTriple (k * (l * (2 * m * n))) (k * (l * (m ^ 2 - n ^ 2))) (k * z))

Next tactic:
use k * l, m, n
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> ring
  · use k * l, m, n
    

Proof state:
case h
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (2 * m * n)) (l * (m ^ 2 - n ^ 2)) z
⊢ (k * (l * (2 * m * n)) = k * l * (m ^ 2 - n ^ 2) ∧ k * (l * (m ^ 2 - n ^ 2)) = k * l * (2 * m * n) ∨
      k * (l * (2 * m * n)) = k * l * (2 * m * n) ∧ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2)) ∧
    Int.gcd m n = 1

Next tactic:
apply And.intro _ co
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> ring
  · use k * l, m, n
    apply And.intro _ co
    

Proof state:
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (2 * m * n)) (l * (m ^ 2 - n ^ 2)) z
⊢ k * (l * (2 * m * n)) = k * l * (m ^ 2 - n ^ 2) ∧ k * (l * (m ^ 2 - n ^ 2)) = k * l * (2 * m * n) ∨
    k * (l * (2 * m * n)) = k * l * (2 * m * n) ∧ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2)

Next tactic:
right
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> ring
  · use k * l, m, n
    apply And.intro _ co
    right
    

Proof state:
case h
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (2 * m * n)) (l * (m ^ 2 - n ^ 2)) z
⊢ k * (l * (2 * m * n)) = k * l * (2 * m * n) ∧ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2)

Next tactic:
constructor
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> ring
  · use k * l, m, n
    apply And.intro _ co
    right
    constructor <;> 

Proof state:
case h.left
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (2 * m * n)) (l * (m ^ 2 - n ^ 2)) z
⊢ k * (l * (2 * m * n)) = k * l * (2 * m * n)

Next tactic:
ring
theorem mul_isClassified (k : ℤ) (hc : h.IsClassified) : (h.mul k).IsClassified := by
  obtain ⟨l, m, n, ⟨⟨rfl, rfl⟩ | ⟨rfl, rfl⟩, co⟩⟩ := hc
  · use k * l, m, n
    apply And.intro _ co
    left
    constructor <;> ring
  · use k * l, m, n
    apply And.intro _ co
    right
    constructor <;> 

Proof state:
case h.right
z k l m n : ℤ
co : Int.gcd m n = 1
h : PythagoreanTriple (l * (2 * m * n)) (l * (m ^ 2 - n ^ 2)) z
⊢ k * (l * (m ^ 2 - n ^ 2)) = k * l * (m ^ 2 - n ^ 2)

Next tactic:
ring
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
⊢ x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0

Next tactic:
cases' Int.emod_two_eq_zero_or_one x with hx hx
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    

Proof state:
case inl
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 0
⊢ x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0

Next tactic:
cases' Int.emod_two_eq_zero_or_one y with hy hy
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    

Proof state:
case inr
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 1
⊢ x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0

Next tactic:
cases' Int.emod_two_eq_zero_or_one y with hy hy
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    cases' Int.emod_two_eq_zero_or_one y with hy hy
  -- x even, y even
  · 

Proof state:
case inl.inl
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 0
hy : y % 2 = 0
⊢ x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0

Next tactic:
exfalso
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    cases' Int.emod_two_eq_zero_or_one y with hy hy
  -- x even, y even
  · exfalso
    

Proof state:
case inl.inl.h
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 0
hy : y % 2 = 0
⊢ False

Next tactic:
apply Nat.not_coprime_of_dvd_of_dvd (by decide : 1 < 2) _ _ hc
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    cases' Int.emod_two_eq_zero_or_one y with hy hy
  -- x even, y even
  · exfalso
    apply Nat.not_coprime_of_dvd_of_dvd (by 

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 0
hy : y % 2 = 0
⊢ 1 < 2

Next tactic:
decide
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    cases' Int.emod_two_eq_zero_or_one y with hy hy
  -- x even, y even
  · exfalso
    apply Nat.not_coprime_of_dvd_of_dvd (by decide : 1 < 2) _ _ hc
    · 

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 0
hy : y % 2 = 0
⊢ 2 ∣ Int.natAbs x

Next tactic:
apply Int.coe_nat_dvd_left.1
theorem even_odd_of_coprime (hc : Int.gcd x y = 1) :
    x % 2 = 0 ∧ y % 2 = 1 ∨ x % 2 = 1 ∧ y % 2 = 0 := by
  cases' Int.emod_two_eq_zero_or_one x with hx hx <;>
    cases' Int.emod_two_eq_zero_or_one y with hy hy
  -- x even, y even
  · exfalso
    apply Nat.not_coprime_of_dvd_of_dvd (by decide : 1 < 2) _ _ hc
    · apply Int.coe_nat_dvd_left.1
      

Proof state:
x y z : ℤ
h : PythagoreanTriple x y z
hc : Int.gcd x y = 1
hx : x % 2 = 0
hy : y % 2 = 0
⊢ ↑2 ∣ x

Next tactic:
apply Int.dvd_of_emod_eq_zero hx