l3lab/ntp-mathlib huggingface dataset:
/-- The torsion subgroup is finite. -/
instance [NumberField K] : Fintype (torsion K) := by
  refine @Fintype.ofFinite _ (Set.finite_coe_iff.mpr ?_)
  refine Set.Finite.of_finite_image ?_ ((coe_injective K).injOn _)
  refine (Embeddings.finite_of_norm_le K ℂ 1).subset
    (fun a ⟨u, ⟨h_tors, h_ua⟩⟩ => ⟨?_, fun φ => ?_⟩)
  · rw [← h_ua]
    

Proof state:
case refine_1
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
a : K
x✝ : a ∈ (fun x => ↑↑x) '' ↑(torsion K)
u : (↥(𝓞 K))ˣ
h_tors : u ∈ ↑(torsion K)
h_ua : (fun x => ↑↑x) u = a
⊢ IsIntegral ℤ ((fun x => ↑↑x) u)

Next tactic:
exact u.val.prop
/-- The torsion subgroup is finite. -/
instance [NumberField K] : Fintype (torsion K) := by
  refine @Fintype.ofFinite _ (Set.finite_coe_iff.mpr ?_)
  refine Set.Finite.of_finite_image ?_ ((coe_injective K).injOn _)
  refine (Embeddings.finite_of_norm_le K ℂ 1).subset
    (fun a ⟨u, ⟨h_tors, h_ua⟩⟩ => ⟨?_, fun φ => ?_⟩)
  · rw [← h_ua]
    exact u.val.prop
  · 

Proof state:
case refine_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
a : K
x✝ : a ∈ (fun x => ↑↑x) '' ↑(torsion K)
u : (↥(𝓞 K))ˣ
h_tors : u ∈ ↑(torsion K)
h_ua : (fun x => ↑↑x) u = a
φ : K →+* ℂ
⊢ ‖φ a‖ ≤ 1

Next tactic:
rw [← h_ua]
/-- The torsion subgroup is finite. -/
instance [NumberField K] : Fintype (torsion K) := by
  refine @Fintype.ofFinite _ (Set.finite_coe_iff.mpr ?_)
  refine Set.Finite.of_finite_image ?_ ((coe_injective K).injOn _)
  refine (Embeddings.finite_of_norm_le K ℂ 1).subset
    (fun a ⟨u, ⟨h_tors, h_ua⟩⟩ => ⟨?_, fun φ => ?_⟩)
  · rw [← h_ua]
    exact u.val.prop
  · rw [← h_ua]
    

Proof state:
case refine_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
a : K
x✝ : a ∈ (fun x => ↑↑x) '' ↑(torsion K)
u : (↥(𝓞 K))ˣ
h_tors : u ∈ ↑(torsion K)
h_ua : (fun x => ↑↑x) u = a
φ : K →+* ℂ
⊢ ‖φ ((fun x => ↑↑x) u)‖ ≤ 1

Next tactic:
exact le_of_eq ((eq_iff_eq _ 1).mp ((mem_torsion K).mp h_tors) φ)
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
⊢ ζ ∈ rootsOfUnity k ↥(𝓞 K) ↔ ζ = 1

Next tactic:
rw [mem_rootsOfUnity]
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
⊢ ζ ^ ↑k = 1 ↔ ζ = 1

Next tactic:
refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ = 1
⊢ ζ ^ ↑k = 1

Next tactic:
rw [h, one_pow]
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
⊢ ζ = 1

Next tactic:
refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
  · 

Proof state:
case refine_1
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
⊢ orderOf ζ ∣ ↑k

Next tactic:
exact orderOf_dvd_of_pow_eq_one h
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
  · exact orderOf_dvd_of_pow_eq_one h
  · 

Proof state:
case refine_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
⊢ orderOf ζ ∣ ↑(torsionOrder K)

Next tactic:
have hζ : ζ ∈ torsion K := by
      rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
      exact ⟨k, k.prop, h⟩
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
  · exact orderOf_dvd_of_pow_eq_one h
  · have hζ : ζ ∈ torsion K := by
      

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
⊢ ζ ∈ torsion K

Next tactic:
rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
  · exact orderOf_dvd_of_pow_eq_one h
  · have hζ : ζ ∈ torsion K := by
      rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
      

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
⊢ ∃ n, 0 < n ∧ ζ ^ n = 1

Next tactic:
exact ⟨k, k.prop, h⟩
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
  · exact orderOf_dvd_of_pow_eq_one h
  · have hζ : ζ ∈ torsion K := by
      rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
      exact ⟨k, k.prop, h⟩
    

Proof state:
case refine_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
hζ : ζ ∈ torsion K
⊢ orderOf ζ ∣ ↑(torsionOrder K)

Next tactic:
rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)]
/-- If `k` does not divide `torsionOrder` then there are no nontrivial roots of unity of
  order dividing `k`. -/
theorem rootsOfUnity_eq_one [NumberField K] {k : ℕ+} (hc : Nat.Coprime k (torsionOrder K))
    {ζ : (𝓞 K)ˣ} : ζ ∈ rootsOfUnity k (𝓞 K) ↔ ζ = 1 := by
  rw [mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => by rw [h, one_pow]⟩
  refine orderOf_eq_one_iff.mp (Nat.eq_one_of_dvd_coprimes hc ?_ ?_)
  · exact orderOf_dvd_of_pow_eq_one h
  · have hζ : ζ ∈ torsion K := by
      rw [torsion, CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
      exact ⟨k, k.prop, h⟩
    rw [orderOf_submonoid (⟨ζ, hζ⟩ : torsion K)]
    

Proof state:
case refine_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
k : ℕ+
hc : Nat.Coprime ↑k ↑(torsionOrder K)
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑k = 1
hζ : ζ ∈ torsion K
⊢ orderOf { val := ζ, property := hζ } ∣ ↑(torsionOrder K)

Next tactic:
exact orderOf_dvd_card
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
    rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
⊢ rootsOfUnity (torsionOrder K) ↥(𝓞 K) = torsion K

Next tactic:
ext ζ
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
    rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
  ext ζ
  

Proof state:
case h
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
ζ : (↥(𝓞 K))ˣ
⊢ ζ ∈ rootsOfUnity (torsionOrder K) ↥(𝓞 K) ↔ ζ ∈ torsion K

Next tactic:
rw [torsion, mem_rootsOfUnity]
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
    rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
  ext ζ
  rw [torsion, mem_rootsOfUnity]
  

Proof state:
case h
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
ζ : (↥(𝓞 K))ˣ
⊢ ζ ^ ↑(torsionOrder K) = 1 ↔ ζ ∈ CommGroup.torsion (↥(𝓞 K))ˣ

Next tactic:
refine ⟨fun h => ?_, fun h => ?_⟩
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
    rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
  ext ζ
  rw [torsion, mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => ?_⟩
  · 

Proof state:
case h.refine_1
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑(torsionOrder K) = 1
⊢ ζ ∈ CommGroup.torsion (↥(𝓞 K))ˣ

Next tactic:
rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
    rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
  ext ζ
  rw [torsion, mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => ?_⟩
  · rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
    

Proof state:
case h.refine_1
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
ζ : (↥(𝓞 K))ˣ
h : ζ ^ ↑(torsionOrder K) = 1
⊢ ∃ n, 0 < n ∧ ζ ^ n = 1

Next tactic:
exact ⟨↑(torsionOrder K), (torsionOrder K).prop, h⟩
/-- The group of roots of unity of order dividing `torsionOrder` is equal to the torsion
group. -/
theorem rootsOfUnity_eq_torsion [NumberField K] :
    rootsOfUnity (torsionOrder K) (𝓞 K) = torsion K := by
  ext ζ
  rw [torsion, mem_rootsOfUnity]
  refine ⟨fun h => ?_, fun h => ?_⟩
  · rw [CommGroup.mem_torsion, isOfFinOrder_iff_pow_eq_one]
    exact ⟨↑(torsionOrder K), (torsionOrder K).prop, h⟩
  · 

Proof state:
case h.refine_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
ζ : (↥(𝓞 K))ˣ
h : ζ ∈ CommGroup.torsion (↥(𝓞 K))ˣ
⊢ ζ ^ ↑(torsionOrder K) = 1

Next tactic:
exact Subtype.ext_iff.mp (@pow_card_eq_one (torsion K) _ _ ⟨ζ, h⟩)
/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
{ toFun := fun x w => mult w.val * Real.log (w.val ↑(Additive.toMul x))
  map_zero' := by 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
⊢ (fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x))) 0 = 0

Next tactic:
simp
/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
{ toFun := fun x w => mult w.val * Real.log (w.val ↑(Additive.toMul x))
  map_zero' := by simp; 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
⊢ (fun w => 0) = 0

Next tactic:
rfl
/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
{ toFun := fun x w => mult w.val * Real.log (w.val ↑(Additive.toMul x))
  map_zero' := by simp; rfl
  map_add' := fun _ _ => by 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x✝¹ x✝ : Additive (↥(𝓞 K))ˣ
⊢ ZeroHom.toFun
      { toFun := fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x)),
        map_zero' := (_ : (fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x))) 0 = 0) }
      (x✝¹ + x✝) =
    ZeroHom.toFun
        { toFun := fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x)),
          map_zero' := (_ : (fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x))) 0 = 0) }
        x✝¹ +
      ZeroHom.toFun
        { toFun := fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x)),
          map_zero' := (_ : (fun x w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x))) 0 = 0) }
        x✝

Next tactic:
simp [Real.log_mul, mul_add]
/-- The logarithmic embedding of the units (seen as an `Additive` group). -/
def logEmbedding : Additive ((𝓞 K)ˣ) →+ ({w : InfinitePlace K // w ≠ w₀} → ℝ) :=
{ toFun := fun x w => mult w.val * Real.log (w.val ↑(Additive.toMul x))
  map_zero' := by simp; rfl
  map_add' := fun _ _ => by simp [Real.log_mul, mul_add]; 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x✝¹ x✝ : Additive (↥(𝓞 K))ˣ
⊢ (fun w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x✝¹)) + ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x✝))) =
    (fun w => ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x✝¹))) + fun w =>
      ↑(mult ↑w) * Real.log (↑w ↑↑(Additive.toMul x✝))

Next tactic:
rfl
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
⊢ ∑ w : { w // w ≠ w₀ }, (logEmbedding K) x w = -↑(mult w₀) * Real.log (w₀ ↑↑x)

Next tactic:
have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : Real.log (∏ w : InfinitePlace K, w ↑↑x ^ mult w) = Real.log ↑|(Algebra.norm ℚ) ↑↑x|
⊢ ∑ w : { w // w ≠ w₀ }, (logEmbedding K) x w = -↑(mult w₀) * Real.log (w₀ ↑↑x)

Next tactic:
rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : ∑ i : InfinitePlace K, Real.log (i ↑↑x ^ mult i) = 0
⊢ ∑ w : { w // w ≠ w₀ }, (logEmbedding K) x w = -↑(mult w₀) * Real.log (w₀ ↑↑x)

Next tactic:
simp_rw [Real.log_pow] at h
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · simp_rw [Real.log_pow] at h
    

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : ∑ x_1 : InfinitePlace K, ↑(mult x_1) * Real.log (x_1 ↑↑x) = 0
⊢ ∑ w : { w // w ≠ w₀ }, (logEmbedding K) x w = -↑(mult w₀) * Real.log (w₀ ↑↑x)

Next tactic:
rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
      add_eq_zero_iff_eq_neg] at h
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · simp_rw [Real.log_pow] at h
    rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
      add_eq_zero_iff_eq_neg] at h
    

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : ∑ x_1 in erase univ w₀, ↑(mult x_1) * Real.log (x_1 ↑↑x) = -(↑(mult w₀) * Real.log (w₀ ↑↑x))
⊢ ∑ w : { w // w ≠ w₀ }, (logEmbedding K) x w = -↑(mult w₀) * Real.log (w₀ ↑↑x)

Next tactic:
convert h using 1
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · simp_rw [Real.log_pow] at h
    rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
      add_eq_zero_iff_eq_neg] at h
    convert h using 1
    · 

Proof state:
case h.e'_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : ∑ x_1 in erase univ w₀, ↑(mult x_1) * Real.log (x_1 ↑↑x) = -(↑(mult w₀) * Real.log (w₀ ↑↑x))
⊢ ∑ w : { w // w ≠ w₀ }, (logEmbedding K) x w = ∑ x_1 in erase univ w₀, ↑(mult x_1) * Real.log (x_1 ↑↑x)

Next tactic:
refine (sum_subtype _ (fun w => ?_) (fun w => (mult w) * (Real.log (w (x : K))))).symm
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · simp_rw [Real.log_pow] at h
    rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
      add_eq_zero_iff_eq_neg] at h
    convert h using 1
    · refine (sum_subtype _ (fun w => ?_) (fun w => (mult w) * (Real.log (w (x : K))))).symm
      

Proof state:
case h.e'_2
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : ∑ x_1 in erase univ w₀, ↑(mult x_1) * Real.log (x_1 ↑↑x) = -(↑(mult w₀) * Real.log (w₀ ↑↑x))
w : InfinitePlace K
⊢ w ∈ erase univ w₀ ↔ w ≠ w₀

Next tactic:
exact ⟨ne_of_mem_erase, fun h => mem_erase_of_ne_of_mem h (mem_univ w)⟩
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · simp_rw [Real.log_pow] at h
    rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
      add_eq_zero_iff_eq_neg] at h
    convert h using 1
    · refine (sum_subtype _ (fun w => ?_) (fun w => (mult w) * (Real.log (w (x : K))))).symm
      exact ⟨ne_of_mem_erase, fun h => mem_erase_of_ne_of_mem h (mem_univ w)⟩
    · 

Proof state:
case h.e'_3
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : ∑ x_1 in erase univ w₀, ↑(mult x_1) * Real.log (x_1 ↑↑x) = -(↑(mult w₀) * Real.log (w₀ ↑↑x))
⊢ -↑(mult w₀) * Real.log (w₀ ↑↑x) = -(↑(mult w₀) * Real.log (w₀ ↑↑x))

Next tactic:
norm_num
theorem sum_logEmbedding_component (x : (𝓞 K)ˣ) :
    ∑ w, logEmbedding K x w = - mult (w₀ : InfinitePlace K) * Real.log (w₀ (x : K)) := by
  have h := congr_arg Real.log (prod_eq_abs_norm (x : K))
  rw [show |(Algebra.norm ℚ) (x : K)| = 1 from isUnit_iff_norm.mp x.isUnit, Rat.cast_one,
    Real.log_one, Real.log_prod] at h
  · simp_rw [Real.log_pow] at h
    rw [← insert_erase (mem_univ w₀), sum_insert (not_mem_erase w₀ univ), add_comm,
      add_eq_zero_iff_eq_neg] at h
    convert h using 1
    · refine (sum_subtype _ (fun w => ?_) (fun w => (mult w) * (Real.log (w (x : K))))).symm
      exact ⟨ne_of_mem_erase, fun h => mem_erase_of_ne_of_mem h (mem_univ w)⟩
    · norm_num
  · 

Proof state:
case hf
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
h : Real.log (∏ w : InfinitePlace K, w ↑↑x ^ mult w) = 0
⊢ ∀ x_1 ∈ univ, x_1 ↑↑x ^ mult x_1 ≠ 0

Next tactic:
exact fun w _ => pow_ne_zero _ (AbsoluteValue.ne_zero _ (coe_ne_zero x))
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
⊢ ↑(mult w) * Real.log (w ↑↑x) = 0 ↔ w ↑↑x = 1

Next tactic:
rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
⊢ ¬w ↑↑x = -1

Next tactic:
linarith [(map_nonneg _ _ : 0 ≤ w x)]
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · linarith [(map_nonneg _ _ : 0 ≤ w x)]
  · 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
⊢ ¬w ↑↑x = 0

Next tactic:
simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · linarith [(map_nonneg _ _ : 0 ≤ w x)]
  · simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
  · 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
⊢ ¬↑(mult w) = 0

Next tactic:
refine (ne_of_gt ?_)
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · linarith [(map_nonneg _ _ : 0 ≤ w x)]
  · simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
  · refine (ne_of_gt ?_)
    

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
⊢ 0 < ↑(mult w)

Next tactic:
rw [mult]
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · linarith [(map_nonneg _ _ : 0 ≤ w x)]
  · simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
  · refine (ne_of_gt ?_)
    rw [mult]; 

Proof state:
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
⊢ 0 < ↑(if IsReal w then 1 else 2)

Next tactic:
split_ifs
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · linarith [(map_nonneg _ _ : 0 ≤ w x)]
  · simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
  · refine (ne_of_gt ?_)
    rw [mult]; split_ifs <;> 

Proof state:
case pos
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
h✝ : IsReal w
⊢ 0 < ↑1

Next tactic:
norm_num
theorem mult_log_place_eq_zero {x : (𝓞 K)ˣ} {w : InfinitePlace K} :
    mult w * Real.log (w x) = 0 ↔ w x = 1 := by
  rw [mul_eq_zero, or_iff_right, Real.log_eq_zero, or_iff_right, or_iff_left]
  · linarith [(map_nonneg _ _ : 0 ≤ w x)]
  · simp only [ne_eq, map_eq_zero, coe_ne_zero x, not_false_eq_true]
  · refine (ne_of_gt ?_)
    rw [mult]; split_ifs <;> 

Proof state:
case neg
K : Type u_1
inst✝¹ : Field K
inst✝ : NumberField K
x : (↥(𝓞 K))ˣ
w : InfinitePlace K
h✝ : ¬IsReal w
⊢ 0 < ↑2

Next tactic:
norm_num