Zulip Chat Archive

Stream: new members

Topic: coercion not being read properly in tactic state


Bashar Hamade (Jun 29 2025 at 00:31):

Hello, I am trying to prove that if spectral radius less than 1 , then gelfand formula is also less than 1 , as I need to use this later for a bigger proof.
I found issues as the tactic state did not seem to understand the coercion . My code is :

def spectral_radius_less_than_one3 [NormedRing A] [NormedAlgebra  A] (a : A) : Prop :=
  spectralRadius  a < 1

theorem what_the_flop [NormedRing A] [NormedAlgebra  A] (a : A) :
    Filter.limsup (fun n => a ^ n‖₊ ^ (1 / n)) Filter.atTop < 1 
    Filter.limsup (fun n => ↑‖a ^ n‖₊ ^ (1 / n)) Filter.atTop < 1 := by
  have h : (fun n => a ^ n‖₊ ^ (1 / n)) = (fun n => ↑‖a ^ n‖₊ ^ (1 / n)) := by
    ext n
    simp only [ one_div]

  rw [h]


theorem gelfand_le_one_when_spectral_radius_le_one
    [NormedRing A] [NormedAlgebra  A] [CompleteSpace A] (a : A) :
    spectral_radius_less_than_one3 a 
    Filter.limsup (fun (n : ) => a ^ n‖₊ ^ (1 / n)) Filter.atTop < 1 := by
  intro h_spectral
  unfold spectral_radius_less_than_one3 at h_spectral
  -- Get the Gelfand formula inequality
  have h_gelfand := spectrum.limsup_pow_nnnorm_pow_one_div_le_spectralRadius a
  -- Now use the fact that the limsup is ≤ spectral radius < 1
  convert lt_of_le_of_lt h_gelfand h_spectral using 1
  -- This tells convert to unify at level 1, which should handle the coercions
  have h_eq : (fun (n : ) => a ^ n‖₊ ^ (1 / n)) = (fun (n : ) => ↑‖a ^ n‖₊ ^ (1 / n)) := by
    ext n
    rfl

  sorry

sometimes the '↑' is not being read in the tactic state, for example in h_eq,which makes me not able to rewrite it. Also if I start the proof as proving : Filter.limsup (fun (n : ℕ) => ↑‖a ^ n‖₊ ^ (1 / ↑n)) Filter.atTop < 1 , it displays the goal in my tactic state without the coercion.
what am I missing to complete this (seemingly basic) proof?

Aaron Liu (Jun 29 2025 at 00:37):

The reason that there's no coercion in the tactic state is that there's actually no coercion there, it's not a bug in the display or anything. If you want to have a coercion then instead of writing in the I find that just specifying the type you want to coerce into with a type ascription usually works better. So in this case that would mean writing (‖a ^ n‖₊ : ENNReal) instead of ↑‖a ^ n‖₊ and (1 / n : ℝ) instead of 1 / ↑n.

Aaron Liu (Jun 29 2025 at 00:37):

The reason that there's no coercion is that Lean finds the identity coercion (coerce from α to α by doing nothing) as an acceptable solution for filling in your coercions.

Bashar Hamade (Jun 29 2025 at 00:40):

so my goal state right before 'sorry' is :
Filter.limsup (fun n => ‖a ^ n‖₊ ^ (1 / n)) Filter.atTop < 1 ↔ Filter.limsup (fun n => ↑‖a ^ n‖₊ ^ (1 / ↑n)) Filter.atTop < 1

shouldn't lean then be able to deduce the equivalence ? because it does not do that . Although it automatically does the coercion after I have h_eq

Aaron Liu (Jun 29 2025 at 00:40):

I don't see why these are equivalent. In fact, I have a strong suspicion that they are actually not equivalent.

Bashar Hamade (Jun 29 2025 at 00:43):

oh ok , issue is fixed..I am working with coercion for the first time and did not seem to grasp the full image.Thank you


Last updated: Dec 20 2025 at 21:32 UTC