Theorem: ZMod.unitsMap_surjective
File: Mathlib/Data/ZMod/Units.lean

tactic: suffices ∀ x : ℕ, x.Coprime n → ∃ k : ℕ, (x + k * n).Coprime m by
  intro x
  have ⟨k, hk⟩ := this x.val.val (val_coe_unit_coprime x)
  refine ⟨unitOfCoprime _ hk, Units.ext ?_⟩
  have : NeZero n := ⟨fun hn ↦ hm.out (eq_zero_of_zero_dvd (hn ▸ h))⟩
  simp [unitsMap_def]
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
⊢ Function.Surjective ⇑(unitsMap h)
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
⊢ ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m

tactic: intro x hx
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
⊢ ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
⊢ ∃ k, (x + k * n).Coprime m

tactic: let ps := m.primeFactors.filter (fun p ↦ ¬p ∣ x)
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
⊢ ∃ k, (x + k * n).Coprime m
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
⊢ ∃ k, (x + k * n).Coprime m

tactic: use ps.prod id
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
⊢ ∃ k, (x + k * n).Coprime m
state_after: case h
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
⊢ (x + ps.prod id * n).Coprime m

tactic: apply Nat.coprime_of_dvd
state_before: case h
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
⊢ (x + ps.prod id * n).Coprime m
state_after: case h.H
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
⊢ ∀ (k : ℕ), Nat.Prime k → k ∣ x + ps.prod id * n → ¬k ∣ m

tactic: intro p pp hp hpn
state_before: case h.H
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
⊢ ∀ (k : ℕ), Nat.Prime k → k ∣ x + ps.prod id * n → ¬k ∣ m
state_after: case h.H
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
⊢ False

tactic: by_cases hpx : p ∣ x
state_before: case h.H
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
⊢ False
state_after: case pos
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
⊢ False

case neg
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
⊢ False

tactic: intro x
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
⊢ Function.Surjective ⇑(unitsMap h)
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
⊢ ∃ a, (unitsMap h) a = x

tactic: have ⟨k, hk⟩ := this x.val.val (val_coe_unit_coprime x)
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
⊢ ∃ a, (unitsMap h) a = x
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
k : ℕ
hk : ((↑x).val + k * n).Coprime m
⊢ ∃ a, (unitsMap h) a = x

tactic: refine ⟨unitOfCoprime _ hk, Units.ext ?_⟩
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
k : ℕ
hk : ((↑x).val + k * n).Coprime m
⊢ ∃ a, (unitsMap h) a = x
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
k : ℕ
hk : ((↑x).val + k * n).Coprime m
⊢ ↑((unitsMap h) (unitOfCoprime ((↑x).val + k * n) hk)) = ↑x

tactic: have : NeZero n := ⟨fun hn ↦ hm.out (eq_zero_of_zero_dvd (hn ▸ h))⟩
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
this : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
k : ℕ
hk : ((↑x).val + k * n).Coprime m
⊢ ↑((unitsMap h) (unitOfCoprime ((↑x).val + k * n) hk)) = ↑x
state_after: n m : ℕ
hm : NeZero m
h : n ∣ m
this✝ : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
k : ℕ
hk : ((↑x).val + k * n).Coprime m
this : NeZero n
⊢ ↑((unitsMap h) (unitOfCoprime ((↑x).val + k * n) hk)) = ↑x

tactic: simp [unitsMap_def]
state_before: n m : ℕ
hm : NeZero m
h : n ∣ m
this✝ : ∀ (x : ℕ), x.Coprime n → ∃ k, (x + k * n).Coprime m
x : (ZMod n)ˣ
k : ℕ
hk : ((↑x).val + k * n).Coprime m
this : NeZero n
⊢ ↑((unitsMap h) (unitOfCoprime ((↑x).val + k * n) hk)) = ↑x
state_after: no goals

tactic: have h := Nat.dvd_sub' hp hpx
state_before: case pos
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
⊢ False
state_after: case pos
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h : p ∣ x + ps.prod id * n - x
⊢ False

tactic: rw [add_comm, Nat.add_sub_cancel] at h
state_before: case pos
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h : p ∣ x + ps.prod id * n - x
⊢ False
state_after: case pos
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h : p ∣ ps.prod id * n
⊢ False

tactic: rcases pp.dvd_mul.mp h with h | h
state_before: case pos
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h : p ∣ ps.prod id * n
⊢ False
state_after: case pos.inl
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ ps.prod id
⊢ False

case pos.inr
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ n
⊢ False

tactic: have ⟨q, hq, hq'⟩ := (pp.prime.dvd_finset_prod_iff id).mp h
state_before: case pos.inl
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ ps.prod id
⊢ False
state_after: case pos.inl
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ ps.prod id
q : ℕ
hq : q ∈ ps
hq' : p ∣ id q
⊢ False

tactic: rw [Finset.mem_filter, Nat.mem_primeFactors,
  ← (Nat.prime_dvd_prime_iff_eq pp hq.1.1).mp hq'] at hq
state_before: case pos.inl
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ ps.prod id
q : ℕ
hq : q ∈ ps
hq' : p ∣ id q
⊢ False
state_after: case pos.inl
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ ps.prod id
q : ℕ
hq : (Nat.Prime p ∧ p ∣ m ∧ m ≠ 0) ∧ ¬p ∣ x
hq' : p ∣ id q
⊢ False

tactic: exact hq.2 hpx
state_before: case pos.inl
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ ps.prod id
q : ℕ
hq : (Nat.Prime p ∧ p ∣ m ∧ m ≠ 0) ∧ ¬p ∣ x
hq' : p ∣ id q
⊢ False
state_after: no goals

tactic: exact Nat.Prime.not_coprime_iff_dvd.mpr ⟨p, pp, hpx, h⟩ hx
state_before: case pos.inr
n m : ℕ
hm : NeZero m
h✝¹ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : p ∣ x
h✝ : p ∣ ps.prod id * n
h : p ∣ n
⊢ False
state_after: no goals

tactic: have pps : p ∈ ps := Finset.mem_filter.mpr ⟨Nat.mem_primeFactors.mpr ⟨pp, hpn, hm.out⟩, hpx⟩
state_before: case neg
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
⊢ False
state_after: case neg
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
pps : p ∈ ps
⊢ False

tactic: have h := Nat.dvd_sub' hp ((Finset.dvd_prod_of_mem id pps).mul_right n)
state_before: case neg
n m : ℕ
hm : NeZero m
h : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
pps : p ∈ ps
⊢ False
state_after: case neg
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
pps : p ∈ ps
h : p ∣ x + ps.prod id * n - (∏ i ∈ ps, id i) * n
⊢ False

tactic: rw [Nat.add_sub_cancel] at h
state_before: case neg
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
pps : p ∈ ps
h : p ∣ x + ps.prod id * n - (∏ i ∈ ps, id i) * n
⊢ False
state_after: case neg
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
pps : p ∈ ps
h : p ∣ x
⊢ False

tactic: contradiction
state_before: case neg
n m : ℕ
hm : NeZero m
h✝ : n ∣ m
x : ℕ
hx : x.Coprime n
ps : Finset ℕ := Finset.filter (fun p => ¬p ∣ x) m.primeFactors
p : ℕ
pp : Nat.Prime p
hp : p ∣ x + ps.prod id * n
hpn : p ∣ m
hpx : ¬p ∣ x
pps : p ∈ ps
h : p ∣ x
⊢ False
state_after: no goals