Theorem: ZMod.sq_add_sq
File: Mathlib/FieldTheory/Finite/Basic.lean

Proof steps:
state_before: K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
state_after: case inl
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp2 : p = 2
⊢ ∃ a b, a ^ 2 + b ^ 2 = x

case inr
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
tactic: cases' hp.1.eq_two_or_odd with hp2 hp_odd
state_before: case inr
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
state_after: case inr
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
tactic: let f : (ZMod p)[X] := X ^ 2
state_before: case inr
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
state_after: case inr
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
tactic: let g : (ZMod p)[X] := X ^ 2 - C x
state_before: case inr
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
state_after: case inr.intro.intro
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
a b : ZMod p
hab : eval a f + eval b g = 0
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
tactic: obtain ⟨a, b, hab⟩ : ∃ a b, f.eval a + g.eval b = 0 :=
    @exists_root_sum_quadratic _ _ _ _ f g (degree_X_pow 2) (degree_X_pow_sub_C (by decide) _)
      (by rw [ZMod.card, hp_odd])
state_before: case inr.intro.intro
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
a b : ZMod p
hab : eval a f + eval b g = 0
⊢ ∃ a b, a ^ 2 + b ^ 2 = x
state_after: case inr.intro.intro
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
a b : ZMod p
hab : eval a f + eval b g = 0
⊢ a ^ 2 + b ^ 2 = x
tactic: refine ⟨a, b, ?_⟩
state_before: case inr.intro.intro
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
a b : ZMod p
hab : eval a f + eval b g = 0
⊢ a ^ 2 + b ^ 2 = x
state_after: case inr.intro.intro
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
a b : ZMod p
hab : eval a f + eval b g = 0
⊢ a ^ 2 + b ^ 2 - x = 0
tactic: rw [← sub_eq_zero]
state_before: case inr.intro.intro
K : Type u_1
R : Type u_2
p : ℕ
hp : Fact (Nat.Prime p)
x : ZMod p
hp_odd : p % 2 = 1
f : (ZMod p)[X] := X ^ 2
g : (ZMod p)[X] := X ^ 2 - C x
a b : ZMod p
hab : eval a f + eval b g = 0
⊢ a ^ 2 + b ^ 2 - x = 0
state_after: no goals
tactic: simpa only [f, g, eval_C, eval_X, eval_pow, eval_sub, ← add_sub_assoc] using hab