l3lab/ntp-mathlib huggingface dataset:
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  

Proof state:
case h.h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ (RingHom.comp (ZMod.castHom (_ : p ^ m ∣ p ^ n) (ZMod (p ^ m))) (toZModPow n)) x = 0 ↔ (toZModPow m) x = 0

Next tactic:
simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  

Proof state:
case h.h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑((toZModPow n) x) = 0 ↔ (toZModPow m) x = 0

Next tactic:
simp only [toZModPow, toZModHom, RingHom.coe_mk]
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  

Proof state:
case h.h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑({ toOneHom := { toFun := fun x => ↑(appr x n), map_one' := (_ : (fun x => ↑(appr x n)) 1 = 1) },
            map_mul' :=
              (_ :
                ∀ (x y : ℤ_[p]),
                  OneHom.toFun { toFun := fun x => ↑(appr x n), map_one' := (_ : (fun x => ↑(appr x n)) 1 = 1) }
                      (x * y) =
                    OneHom.toFun { toFun := fun x => ↑(appr x n), map_one' := (_ : (fun x => ↑(appr x n)) 1 = 1) } x *
                      OneHom.toFun { toFun := fun x => ↑(appr x n), map_one' := (_ : (fun x => ↑(appr x n)) 1 = 1) }
                        y) }
          x) =
      0 ↔
    { toOneHom := { toFun := fun x => ↑(appr x m), map_one' := (_ : (fun x => ↑(appr x m)) 1 = 1) },
          map_mul' :=
            (_ :
              ∀ (x y : ℤ_[p]),
                OneHom.toFun { toFun := fun x => ↑(appr x m), map_one' := (_ : (fun x => ↑(appr x m)) 1 = 1) } (x * y) =
                  OneHom.toFun { toFun := fun x => ↑(appr x m), map_one' := (_ : (fun x => ↑(appr x m)) 1 = 1) } x *
                    OneHom.toFun { toFun := fun x => ↑(appr x m), map_one' := (_ : (fun x => ↑(appr x m)) 1 = 1) } y) }
        x =
      0

Next tactic:
dsimp
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  

Proof state:
case h.h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑↑(appr x n) = 0 ↔ ↑(appr x m) = 0

Next tactic:
rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
  · 

Proof state:
case h.h.ha
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑(appr x n) - ↑(appr x n) ∈ Ideal.span {↑p ^ m}

Next tactic:
rw [sub_self]
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
  · rw [sub_self]
    

Proof state:
case h.h.ha
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ 0 ∈ Ideal.span {↑p ^ m}

Next tactic:
apply Ideal.zero_mem _
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
  · rw [sub_self]
    apply Ideal.zero_mem _
  · 

Proof state:
case h.h.hb
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑(appr x n) - ↑(appr x m) ∈ Ideal.span {↑p ^ m}

Next tactic:
rw [Ideal.mem_span_singleton]
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
  · rw [sub_self]
    apply Ideal.zero_mem _
  · rw [Ideal.mem_span_singleton]
    

Proof state:
case h.h.hb
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑p ^ m ∣ ↑(appr x n) - ↑(appr x m)

Next tactic:
rcases dvd_appr_sub_appr x m n h with ⟨c, hc⟩
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
  · rw [sub_self]
    apply Ideal.zero_mem _
  · rw [Ideal.mem_span_singleton]
    rcases dvd_appr_sub_appr x m n h with ⟨c, hc⟩
    

Proof state:
case h.h.hb.intro
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
c : ℕ
hc : appr x n - appr x m = p ^ m * c
⊢ ↑p ^ m ∣ ↑(appr x n) - ↑(appr x m)

Next tactic:
use c
theorem zmod_cast_comp_toZModPow (m n : ℕ) (h : m ≤ n) :
    (ZMod.castHom (pow_dvd_pow p h) (ZMod (p ^ m))).comp (@toZModPow p _ n) = @toZModPow p _ m := by
  apply ZMod.ringHom_eq_of_ker_eq
  ext x
  rw [RingHom.mem_ker, RingHom.mem_ker]
  simp only [Function.comp_apply, ZMod.castHom_apply, RingHom.coe_comp]
  simp only [toZModPow, toZModHom, RingHom.coe_mk]
  dsimp
  rw [ZMod.cast_nat_cast (pow_dvd_pow p h),
    zmod_congr_of_sub_mem_span m (x.appr n) (x.appr n) (x.appr m)]
  · rw [sub_self]
    apply Ideal.zero_mem _
  · rw [Ideal.mem_span_singleton]
    rcases dvd_appr_sub_appr x m n h with ⟨c, hc⟩
    use c
    

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
c : ℕ
hc : appr x n - appr x m = p ^ m * c
⊢ ↑(appr x n) - ↑(appr x m) = ↑p ^ m * ↑c

Next tactic:
rw [← Nat.cast_sub (appr_mono _ h), hc, Nat.cast_mul, Nat.cast_pow]
@[simp]
theorem cast_toZModPow (m n : ℕ) (h : m ≤ n) (x : ℤ_[p]) : ↑(toZModPow n x) = toZModPow m x := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑((toZModPow n) x) = (toZModPow m) x

Next tactic:
rw [← zmod_cast_comp_toZModPow _ _ h]
@[simp]
theorem cast_toZModPow (m n : ℕ) (h : m ≤ n) (x : ℤ_[p]) : ↑(toZModPow n x) = toZModPow m x := by
  rw [← zmod_cast_comp_toZModPow _ _ h]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ : ℤ_[p]
m n : ℕ
h : m ≤ n
x : ℤ_[p]
⊢ ↑((toZModPow n) x) = (RingHom.comp (ZMod.castHom (_ : p ^ m ∣ p ^ n) (ZMod (p ^ m))) (toZModPow n)) x

Next tactic:
rfl
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x : ℤ_[p]
⊢ DenseRange Nat.cast

Next tactic:
intro x
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
⊢ x ∈ closure (Set.range Nat.cast)

Next tactic:
rw [Metric.mem_closure_range_iff]
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
⊢ ∀ ε > 0, ∃ k, dist x ↑k < ε

Next tactic:
intro ε hε
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  intro ε hε
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
ε : ℝ
hε : ε > 0
⊢ ∃ k, dist x ↑k < ε

Next tactic:
obtain ⟨n, hn⟩ := exists_pow_neg_lt p hε
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  intro ε hε
  obtain ⟨n, hn⟩ := exists_pow_neg_lt p hε
  

Proof state:
case intro
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
ε : ℝ
hε : ε > 0
n : ℕ
hn : ↑p ^ (-↑n) < ε
⊢ ∃ k, dist x ↑k < ε

Next tactic:
use x.appr n
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  intro ε hε
  obtain ⟨n, hn⟩ := exists_pow_neg_lt p hε
  use x.appr n
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
ε : ℝ
hε : ε > 0
n : ℕ
hn : ↑p ^ (-↑n) < ε
⊢ dist x ↑(appr x n) < ε

Next tactic:
rw [dist_eq_norm]
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  intro ε hε
  obtain ⟨n, hn⟩ := exists_pow_neg_lt p hε
  use x.appr n
  rw [dist_eq_norm]
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
ε : ℝ
hε : ε > 0
n : ℕ
hn : ↑p ^ (-↑n) < ε
⊢ ‖x - ↑(appr x n)‖ < ε

Next tactic:
apply lt_of_le_of_lt _ hn
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  intro ε hε
  obtain ⟨n, hn⟩ := exists_pow_neg_lt p hε
  use x.appr n
  rw [dist_eq_norm]
  apply lt_of_le_of_lt _ hn
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
ε : ℝ
hε : ε > 0
n : ℕ
hn : ↑p ^ (-↑n) < ε
⊢ ‖x - ↑(appr x n)‖ ≤ ↑p ^ (-↑n)

Next tactic:
rw [norm_le_pow_iff_mem_span_pow]
theorem denseRange_nat_cast : DenseRange (Nat.cast : ℕ → ℤ_[p]) := by
  intro x
  rw [Metric.mem_closure_range_iff]
  intro ε hε
  obtain ⟨n, hn⟩ := exists_pow_neg_lt p hε
  use x.appr n
  rw [dist_eq_norm]
  apply lt_of_le_of_lt _ hn
  rw [norm_le_pow_iff_mem_span_pow]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
ε : ℝ
hε : ε > 0
n : ℕ
hn : ↑p ^ (-↑n) < ε
⊢ x - ↑(appr x n) ∈ Ideal.span {↑p ^ n}

Next tactic:
apply appr_spec
theorem denseRange_int_cast : DenseRange (Int.cast : ℤ → ℤ_[p]) := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x : ℤ_[p]
⊢ DenseRange Int.cast

Next tactic:
intro x
theorem denseRange_int_cast : DenseRange (Int.cast : ℤ → ℤ_[p]) := by
  intro x
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
⊢ x ∈ closure (Set.range Int.cast)

Next tactic:
refine DenseRange.induction_on denseRange_nat_cast x ?_ ?_
theorem denseRange_int_cast : DenseRange (Int.cast : ℤ → ℤ_[p]) := by
  intro x
  refine DenseRange.induction_on denseRange_nat_cast x ?_ ?_
  · 

Proof state:
case refine_1
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
⊢ IsClosed {b | b ∈ closure (Set.range Int.cast)}

Next tactic:
exact isClosed_closure
theorem denseRange_int_cast : DenseRange (Int.cast : ℤ → ℤ_[p]) := by
  intro x
  refine DenseRange.induction_on denseRange_nat_cast x ?_ ?_
  · exact isClosed_closure
  · 

Proof state:
case refine_2
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
⊢ ∀ (a : ℕ), ↑a ∈ closure (Set.range Int.cast)

Next tactic:
intro a
theorem denseRange_int_cast : DenseRange (Int.cast : ℤ → ℤ_[p]) := by
  intro x
  refine DenseRange.induction_on denseRange_nat_cast x ?_ ?_
  · exact isClosed_closure
  · intro a
    

Proof state:
case refine_2
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
a : ℕ
⊢ ↑a ∈ closure (Set.range Int.cast)

Next tactic:
apply subset_closure
theorem denseRange_int_cast : DenseRange (Int.cast : ℤ → ℤ_[p]) := by
  intro x
  refine DenseRange.induction_on denseRange_nat_cast x ?_ ?_
  · exact isClosed_closure
  · intro a
    apply subset_closure
    

Proof state:
case refine_2.a
p : ℕ
hp_prime : Fact (Nat.Prime p)
r : ℚ
x✝ x : ℤ_[p]
a : ℕ
⊢ ↑a ∈ Set.range Int.cast

Next tactic:
exact Set.mem_range_self _
@[simp]
theorem nthHom_zero : nthHom f 0 = 0 := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
⊢ nthHom f 0 = 0

Next tactic:
simp (config := { unfoldPartialApp := true }) [nthHom]
@[simp]
theorem nthHom_zero : nthHom f 0 = 0 := by
  simp (config := { unfoldPartialApp := true }) [nthHom]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
⊢ (fun n => 0) = 0

Next tactic:
rfl
theorem pow_dvd_nthHom_sub (r : R) (i j : ℕ) (h : i ≤ j) :
    (p : ℤ) ^ i ∣ nthHom f r j - nthHom f r i := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
i j : ℕ
h : i ≤ j
⊢ ↑p ^ i ∣ nthHom f r j - nthHom f r i

Next tactic:
specialize f_compat i j h
theorem pow_dvd_nthHom_sub (r : R) (i j : ℕ) (h : i ≤ j) :
    (p : ℤ) ^ i ∣ nthHom f r j - nthHom f r i := by
  specialize f_compat i j h
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
r : R
i j : ℕ
h : i ≤ j
f_compat : RingHom.comp (ZMod.castHom (_ : p ^ i ∣ p ^ j) (ZMod (p ^ i))) (f j) = f i
⊢ ↑p ^ i ∣ nthHom f r j - nthHom f r i

Next tactic:
rw [← Int.coe_nat_pow, ← ZMod.int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub]
theorem pow_dvd_nthHom_sub (r : R) (i j : ℕ) (h : i ≤ j) :
    (p : ℤ) ^ i ∣ nthHom f r j - nthHom f r i := by
  specialize f_compat i j h
  rw [← Int.coe_nat_pow, ← ZMod.int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
r : R
i j : ℕ
h : i ≤ j
f_compat : RingHom.comp (ZMod.castHom (_ : p ^ i ∣ p ^ j) (ZMod (p ^ i))) (f j) = f i
⊢ ↑(nthHom f r j) - ↑(nthHom f r i) = 0

Next tactic:
dsimp [nthHom]
theorem pow_dvd_nthHom_sub (r : R) (i j : ℕ) (h : i ≤ j) :
    (p : ℤ) ^ i ∣ nthHom f r j - nthHom f r i := by
  specialize f_compat i j h
  rw [← Int.coe_nat_pow, ← ZMod.int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub]
  dsimp [nthHom]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
r : R
i j : ℕ
h : i ≤ j
f_compat : RingHom.comp (ZMod.castHom (_ : p ^ i ∣ p ^ j) (ZMod (p ^ i))) (f j) = f i
⊢ ↑↑(ZMod.val ((f j) r)) - ↑↑(ZMod.val ((f i) r)) = 0

Next tactic:
rw [← f_compat, RingHom.comp_apply]
theorem pow_dvd_nthHom_sub (r : R) (i j : ℕ) (h : i ≤ j) :
    (p : ℤ) ^ i ∣ nthHom f r j - nthHom f r i := by
  specialize f_compat i j h
  rw [← Int.coe_nat_pow, ← ZMod.int_cast_zmod_eq_zero_iff_dvd, Int.cast_sub]
  dsimp [nthHom]
  rw [← f_compat, RingHom.comp_apply]
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
r : R
i j : ℕ
h : i ≤ j
f_compat : RingHom.comp (ZMod.castHom (_ : p ^ i ∣ p ^ j) (ZMod (p ^ i))) (f j) = f i
⊢ ↑↑(ZMod.val ((f j) r)) - ↑↑(ZMod.val ((ZMod.castHom (_ : p ^ i ∣ p ^ j) (ZMod (p ^ i))) ((f j) r))) = 0

Next tactic:
simp only [ZMod.cast_id, ZMod.castHom_apply, sub_self, ZMod.nat_cast_val, ZMod.int_cast_cast]
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
⊢ IsCauSeq (padicNorm p) fun n => ↑(nthHom f r n)

Next tactic:
intro ε hε
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
⊢ ∃ i, ∀ j ≥ i, padicNorm p ((fun n => ↑(nthHom f r n)) j - (fun n => ↑(nthHom f r n)) i) < ε

Next tactic:
obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  

Proof state:
case intro
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
⊢ ∃ i, ∀ j ≥ i, padicNorm p ((fun n => ↑(nthHom f r n)) j - (fun n => ↑(nthHom f r n)) i) < ε

Next tactic:
use k
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  use k
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
⊢ ∀ j ≥ k, padicNorm p ((fun n => ↑(nthHom f r n)) j - (fun n => ↑(nthHom f r n)) k) < ε

Next tactic:
intro j hj
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  use k
  intro j hj
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
j : ℕ
hj : j ≥ k
⊢ padicNorm p ((fun n => ↑(nthHom f r n)) j - (fun n => ↑(nthHom f r n)) k) < ε

Next tactic:
refine' lt_of_le_of_lt _ hk
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  use k
  intro j hj
  refine' lt_of_le_of_lt _ hk
  -- Need to do beta reduction first, as `norm_cast` doesn't.
  -- Added to adapt to leanprover/lean4#2734.
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
j : ℕ
hj : j ≥ k
⊢ padicNorm p ((fun n => ↑(nthHom f r n)) j - (fun n => ↑(nthHom f r n)) k) ≤ ↑p ^ (-↑k)

Next tactic:
beta_reduce
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  use k
  intro j hj
  refine' lt_of_le_of_lt _ hk
  -- Need to do beta reduction first, as `norm_cast` doesn't.
  -- Added to adapt to leanprover/lean4#2734.
  beta_reduce
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
j : ℕ
hj : j ≥ k
⊢ padicNorm p (↑(nthHom f r j) - ↑(nthHom f r k)) ≤ ↑p ^ (-↑k)

Next tactic:
norm_cast
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  use k
  intro j hj
  refine' lt_of_le_of_lt _ hk
  -- Need to do beta reduction first, as `norm_cast` doesn't.
  -- Added to adapt to leanprover/lean4#2734.
  beta_reduce
  norm_cast
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
j : ℕ
hj : j ≥ k
⊢ padicNorm p ↑(nthHom f r j - nthHom f r k) ≤ ↑p ^ (-↑k)

Next tactic:
rw [← padicNorm.dvd_iff_norm_le]
theorem isCauSeq_nthHom (r : R) : IsCauSeq (padicNorm p) fun n => nthHom f r n := by
  intro ε hε
  obtain ⟨k, hk⟩ : ∃ k : ℕ, (p : ℚ) ^ (-((k : ℕ) : ℤ)) < ε := exists_pow_neg_lt_rat p hε
  use k
  intro j hj
  refine' lt_of_le_of_lt _ hk
  -- Need to do beta reduction first, as `norm_cast` doesn't.
  -- Added to adapt to leanprover/lean4#2734.
  beta_reduce
  norm_cast
  rw [← padicNorm.dvd_iff_norm_le]
  

Proof state:
case h
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
r : R
ε : ℚ
hε : ε > 0
k : ℕ
hk : ↑p ^ (-↑k) < ε
j : ℕ
hj : j ≥ k
⊢ ↑(p ^ k) ∣ nthHom f r j - nthHom f r k

Next tactic:
exact mod_cast pow_dvd_nthHom_sub f_compat r k j hj
theorem nthHomSeq_one : nthHomSeq f_compat 1 ≈ 1 := by
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
⊢ nthHomSeq f_compat 1 ≈ 1

Next tactic:
intro ε hε
theorem nthHomSeq_one : nthHomSeq f_compat 1 ≈ 1 := by
  intro ε hε
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
ε : ℚ
hε : ε > 0
⊢ ∃ i, ∀ j ≥ i, padicNorm p (↑(nthHomSeq f_compat 1 - 1) j) < ε

Next tactic:
change _ < _ at hε
theorem nthHomSeq_one : nthHomSeq f_compat 1 ≈ 1 := by
  intro ε hε
  change _ < _ at hε
  

Proof state:
p : ℕ
hp_prime : Fact (Nat.Prime p)
R : Type u_1
inst✝ : NonAssocSemiring R
f : (k : ℕ) → R →+* ZMod (p ^ k)
f_compat : ∀ (k1 k2 : ℕ) (hk : k1 ≤ k2), RingHom.comp (ZMod.castHom (_ : p ^ k1 ∣ p ^ k2) (ZMod (p ^ k1))) (f k2) = f k1
ε : ℚ
hε : 0 < ε
⊢ ∃ i, ∀ j ≥ i, padicNorm p (↑(nthHomSeq f_compat 1 - 1) j) < ε

Next tactic:
use 1