Theorem: Nat.totient_prime_pow_succ
File: Mathlib/Data/Nat/Totient.lean

tactic: rw [sdiff_eq_filter]
state_before: p : ℕ
hp : Prime p
n : ℕ
⊢ filter (p ^ (n + 1)).Coprime (range (p ^ (n + 1))) = range (p ^ (n + 1)) \ image (fun x => x * p) (range (p ^ n))
state_after: p : ℕ
hp : Prime p
n : ℕ
⊢ filter (p ^ (n + 1)).Coprime (range (p ^ (n + 1))) =
    filter (fun x => x ∉ image (fun x => x * p) (range (p ^ n))) (range (p ^ (n + 1)))

tactic: apply filter_congr
state_before: p : ℕ
hp : Prime p
n : ℕ
⊢ filter (p ^ (n + 1)).Coprime (range (p ^ (n + 1))) =
    filter (fun x => x ∉ image (fun x => x * p) (range (p ^ n))) (range (p ^ (n + 1)))
state_after: case H
p : ℕ
hp : Prime p
n : ℕ
⊢ ∀ x ∈ range (p ^ (n + 1)), (p ^ (n + 1)).Coprime x ↔ x ∉ image (fun x => x * p) (range (p ^ n))

tactic: simp only [mem_range, mem_filter, coprime_pow_left_iff n.succ_pos, mem_image, not_exists,
  hp.coprime_iff_not_dvd]
state_before: case H
p : ℕ
hp : Prime p
n : ℕ
⊢ ∀ x ∈ range (p ^ (n + 1)), (p ^ (n + 1)).Coprime x ↔ x ∉ image (fun x => x * p) (range (p ^ n))
state_after: case H
p : ℕ
hp : Prime p
n : ℕ
⊢ ∀ x < p ^ (n + 1), ¬p ∣ x ↔ ∀ (x_1 : ℕ), ¬(x_1 < p ^ n ∧ x_1 * p = x)

tactic: intro a ha
state_before: case H
p : ℕ
hp : Prime p
n : ℕ
⊢ ∀ x < p ^ (n + 1), ¬p ∣ x ↔ ∀ (x_1 : ℕ), ¬(x_1 < p ^ n ∧ x_1 * p = x)
state_after: case H
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
⊢ ¬p ∣ a ↔ ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = a)

tactic: constructor
state_before: case H
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
⊢ ¬p ∣ a ↔ ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = a)
state_after: case H.mp
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
⊢ ¬p ∣ a → ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = a)

case H.mpr
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
⊢ (∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = a)) → ¬p ∣ a

tactic: intro hap b h
state_before: case H.mp
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
⊢ ¬p ∣ a → ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = a)
state_after: case H.mp
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
hap : ¬p ∣ a
b : ℕ
h : b < p ^ n ∧ b * p = a
⊢ False

tactic: rcases h with ⟨_, rfl⟩
state_before: case H.mp
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
hap : ¬p ∣ a
b : ℕ
h : b < p ^ n ∧ b * p = a
⊢ False
state_after: case H.mp.intro
p : ℕ
hp : Prime p
n b : ℕ
left✝ : b < p ^ n
ha : b * p < p ^ (n + 1)
hap : ¬p ∣ b * p
⊢ False

tactic: exact hap (dvd_mul_left _ _)
state_before: case H.mp.intro
p : ℕ
hp : Prime p
n b : ℕ
left✝ : b < p ^ n
ha : b * p < p ^ (n + 1)
hap : ¬p ∣ b * p
⊢ False
state_after: no goals

tactic: rintro h ⟨b, rfl⟩
state_before: case H.mpr
p : ℕ
hp : Prime p
n a : ℕ
ha : a < p ^ (n + 1)
⊢ (∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = a)) → ¬p ∣ a
state_after: case H.mpr.intro
p : ℕ
hp : Prime p
n b : ℕ
ha : p * b < p ^ (n + 1)
h : ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = p * b)
⊢ False

tactic: rw [pow_succ'] at ha
state_before: case H.mpr.intro
p : ℕ
hp : Prime p
n b : ℕ
ha : p * b < p ^ (n + 1)
h : ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = p * b)
⊢ False
state_after: case H.mpr.intro
p : ℕ
hp : Prime p
n b : ℕ
ha : p * b < p * p ^ n
h : ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = p * b)
⊢ False

tactic: exact h b ⟨lt_of_mul_lt_mul_left ha (zero_le _), mul_comm _ _⟩
state_before: case H.mpr.intro
p : ℕ
hp : Prime p
n b : ℕ
ha : p * b < p * p ^ n
h : ∀ (x : ℕ), ¬(x < p ^ n ∧ x * p = p * b)
⊢ False
state_after: no goals

tactic: rw [card_sdiff h2, Finset.card_image_of_injective _ h1, card_range, card_range, ←
  one_mul (p ^ n), pow_succ', ← tsub_mul, one_mul, mul_comm]
state_before: p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
h2 : image (fun x => x * p) (range (p ^ n)) ⊆ range (p ^ (n + 1))
⊢ (range (p ^ (n + 1)) \ image (fun x => x * p) (range (p ^ n))).card = p ^ n * (p - 1)
state_after: no goals

tactic: simp only [mem_image, mem_range, exists_imp]
state_before: p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
a : ℕ
⊢ a ∈ image (fun x => x * p) (range (p ^ n)) → a ∈ range (p ^ (n + 1))
state_after: p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
a : ℕ
⊢ ∀ (x : ℕ), x < p ^ n ∧ x * p = a → a < p ^ (n + 1)

tactic: rintro b ⟨h, rfl⟩
state_before: p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
a : ℕ
⊢ ∀ (x : ℕ), x < p ^ n ∧ x * p = a → a < p ^ (n + 1)
state_after: case intro
p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
b : ℕ
h : b < p ^ n
⊢ b * p < p ^ (n + 1)

tactic: rw [Nat.pow_succ]
state_before: case intro
p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
b : ℕ
h : b < p ^ n
⊢ b * p < p ^ (n + 1)
state_after: case intro
p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
b : ℕ
h : b < p ^ n
⊢ b * p < p ^ n * p

tactic: exact (mul_lt_mul_right hp.pos).2 h
state_before: case intro
p : ℕ
hp : Prime p
n : ℕ
h1 : Function.Injective fun x => x * p
b : ℕ
h : b < p ^ n
⊢ b * p < p ^ n * p
state_after: no goals