Zulip Chat Archive

Stream: maths

Topic: Error with rewrite


Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 13:56):

Hi everyone.

I have the following theorem:

theorem abs_conv_implies_summable {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  [CompleteSpace X] (f: β„• β†’ X): conv_abs_serie 𝕂 f β†’ Summable f := by
    intro fconvabs
    apply abssum_implies_sum 𝕂
    rw [cauchyabssum_iff_abssummable, cauchysum_normed ℝ]
    rw [convabsserie_iff_cauchyabsserie, cauchy_serie_normed ℝ] at fconvabs
    intro Ξ΅ Ξ΅pos
    rcases fconvabs Ξ΅ Ξ΅pos with ⟨nβ‚€, eq⟩
    use Finset.Icc 0 nβ‚€
    intro F Fneint
    simp only [Real.norm_of_nonneg (Finset.sum_nonneg (fun i x ↦ norm_nonneg (f i)))] at *
    by_cases h: F.Nonempty
    Β· calc
        βˆ‘ i ∈ F, β€–f iβ€– ≀ βˆ‘ i ∈ Finset.Ioc nβ‚€ (Finset.max' F h), β€–f iβ€– := by
          apply Finset.sum_le_sum_of_subset_of_nonneg
          Β· intro n ninF
            rw [Finset.mem_Ioc]
            constructor
            Β· by_contra! nlenβ‚€
              have: n ∈ Finset.Icc 0 nβ‚€ ∩ F := by
                rw [Finset.mem_inter, Finset.mem_Icc]
                exact And.intro (And.intro (Nat.zero_le n) nlenβ‚€) ninF
              sorry
            Β· exact Finset.le_max' F n ninF
          Β· intro i _ _
            exact norm_nonneg (f i)
        _ < Ξ΅ := by
          have: nβ‚€ < F.max' h := by
            have: F.max' h βˆ‰ Finset.Icc 0 nβ‚€ := by
              by_contra h'
              have : F.max' h ∈ Finset.Icc 0 nβ‚€ ∩ F := by
                exact Finset.mem_inter_of_mem h' (Finset.max'_mem F h)
              sorry
            rw [Finset.mem_Icc] at this
            push_neg at this
            exact this (zero_le (F.max' h))
          exact eq nβ‚€ (F.max' h) (le_refl nβ‚€) (le_of_lt this)
    Β· rw [Finset.not_nonempty_iff_eq_empty] at h
      rw [h, Finset.sum_empty]
      exact Ξ΅pos

If it is important to know the details of the definitions I'm using I can provide more detail, but the point is the following.

The sorry in the proof can be sustituted by rw [Fneint] at this followed by the tactic contradiction. However, when doing it I get the following error:

image.png

However, at the point of the proof showed in the next image

image.png

I have some assumptions and If I put them all as the assumptions for a new theorem, the exact same proof but changing the sorry as I've said before works:

lemma aux {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  [CompleteSpace X] {f: β„• β†’ X} {F: Finset β„•} {nβ‚€: β„•} {Ξ΅: ℝ} (Ξ΅pos: 0 < Ξ΅)
  (eq: βˆ€ (n m : β„•), nβ‚€ ≀ n β†’ n ≀ m β†’ βˆ‘ i ∈ Finset.Ioc n m, β€–f iβ€– < Ξ΅)
  (Fneint: Finset.Icc 0 nβ‚€ ∩ F = βˆ…):  βˆ‘ i ∈ F, β€–f iβ€– < Ξ΅ := by
    by_cases h: F.Nonempty
    Β· calc
        βˆ‘ i ∈ F, β€–f iβ€– ≀ βˆ‘ i ∈ Finset.Ioc nβ‚€ (Finset.max' F h), β€–f iβ€– := by
          apply Finset.sum_le_sum_of_subset_of_nonneg
          Β· intro n ninF
            rw [Finset.mem_Ioc]
            constructor
            Β· by_contra! nlenβ‚€
              have: n ∈ Finset.Icc 0 nβ‚€ ∩ F := by
                rw [Finset.mem_inter, Finset.mem_Icc]
                exact And.intro (And.intro (Nat.zero_le n) nlenβ‚€) ninF
              rw [Fneint] at this
              contradiction
            Β· exact Finset.le_max' F n ninF
          Β· intro i _ _
            exact norm_nonneg (f i)
        _ < Ξ΅ := by
          have: nβ‚€ < F.max' h := by
            have: F.max' h βˆ‰ Finset.Icc 0 nβ‚€ := by
              by_contra h'
              have : F.max' h ∈ Finset.Icc 0 nβ‚€ ∩ F := by
                exact Finset.mem_inter_of_mem h' (Finset.max'_mem F h)
              rw [Fneint] at this
              contradiction
            rw [Finset.mem_Icc] at this
            push_neg at this
            exact this (zero_le (F.max' h))
          exact eq nβ‚€ (F.max' h) (le_refl nβ‚€) (le_of_lt this)
    Β· rw [Finset.not_nonempty_iff_eq_empty] at h
      rw [h, Finset.sum_empty]
      exact Ξ΅pos

What's happening here? How can I end my proof?

Thanks in advance for any help.

Kevin Buzzard (Dec 03 2024 at 17:00):

Nobody can run your code without extra effort, because you didn't make a #mwe . Can you make that effort yourself? In other words, can you edit your original post adding all imports/opens etc so that someone can just click on the "view in Lean 4 playground" link and it will just work? Right now we just get a sea of errors.

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 18:17):

Of course, sorry. Here it is:

mwe.lean

I didn't include it because I thought it was a "silly error" and, as you can see, there was a lot to include.

Anyway, this is the GitHub link to the project if it is useful:

https://github.com/Eparoh/Functional_Analysis

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 18:19):

By the way, I've included the .lean file because the link to the Lean 4 Web was too long, how can I shorten it?

Ruben Van de Velde (Dec 03 2024 at 19:08):

Please post it between backticks, not as an attachment

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 19:48):

Ruben Van de Velde ha dicho:

Please post it between backticks, not as an attachment

Could you please provide an example of how I should post it? I'll edit it then, but I'm not sure how to do it.

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 19:54):

Because the link is so long it does not fit in one post

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 19:57):

I've managed to shorten it, but I don't know if it is a valid way to post it:

https://dub.sh/iidUiCl

Ruben Van de Velde (Dec 03 2024 at 19:59):

import Mathlib

example : True := trivial

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 20:00):

But it is a long code. I'll change all non-relevant proofs with sorry and I'll post it that way

Esteban MartΓ­nez VaΓ±Γ³ (Dec 03 2024 at 20:11):

Okay, I've shorten it that way. Let's see if now it is okay:

import Mathlib.Analysis.RCLike.Basic
import Mathlib.Topology.Instances.Real
import Mathlib.Topology.UniformSpace.Cauchy
import Mathlib.Topology.Algebra.InfiniteSum.Defs

noncomputable section

open Set Filter Topology Classical Function

class DirectedSet (D: Type*) extends Preorder D, Inhabited D, IsDirected D (fun d d' ↦ d ≀ d')

instance LinearOrder.instDirectedSet {X : Type*} [LinearOrder X] [Inhabited X] : DirectedSet X where
  directed := by
    intro d e
    use max d e
    exact And.intro (le_max_left d e) (le_max_right d e)

instance DirectedSet.instFiniteSubsets {X: Type*}: DirectedSet (Finset X) where
  default := βˆ…
  directed := by
    intro E F
    use E βˆͺ F
    constructor
    Β· exact Finset.subset_union_left
    Β· exact Finset.subset_union_right

def Limit {X D: Type*} [TopologicalSpace X] [DirectedSet D] (s : D β†’ X) (x: X) : Prop :=
  βˆ€ U ∈ nhds x, βˆƒ (dβ‚€ : D), βˆ€ (d : D), dβ‚€ ≀ d β†’ s d ∈ U

def conv_serie_to {X: Type*} [AddCommMonoid X] [TopologicalSpace X] (f: β„• β†’ X) (x: X): Prop :=
   Limit (fun (N: β„•) ↦ βˆ‘ n ≀ N, f n) x

def conv_abs_serie_to {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
   (f: β„• β†’ X) (t: ℝ) : Prop :=
      conv_serie_to (fun (n: β„•) ↦ β€–f nβ€–) t

def conv_abs_serie {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  (f: β„• β†’ X) : Prop :=
   βˆƒ (t: ℝ), conv_abs_serie_to 𝕂 f t

def HasSumNet {I X: Type*} [AddCommMonoid X] [TopologicalSpace X] (f: I β†’ X) (x: X): Prop :=
   Limit (fun (E: Finset I) ↦ βˆ‘ e ∈ E, f e) x

def HasAbsSum {I X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
   (f: I β†’ X) (t: ℝ): Prop := HasSumNet (fun (i: I) ↦ β€–f iβ€–) t

def AbsSummable {I X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
   (f: I β†’ X): Prop := βˆƒ (t: ℝ), HasAbsSum 𝕂 f t

def CauchyNet {X D: Type*} [DirectedSet D] [UniformSpace X] (s: D β†’ X): Prop :=
   βˆ€ U ∈ uniformity X, βˆƒ (dβ‚€: D), βˆ€ (d e: D), (dβ‚€ ≀ d β†’ dβ‚€ ≀ e β†’ (s d, s e) ∈ U)

def CauchySumNet {I X: Type*} [AddCommMonoid X] [UniformSpace X] (f: I β†’ X): Prop :=
   CauchyNet (fun (E: Finset I) ↦ βˆ‘ e ∈ E, f e)

def CauchySerie {X: Type*} [AddCommMonoid X] [UniformSpace X] (f: β„• β†’ X): Prop :=
   CauchyNet (fun (N: β„•) ↦ βˆ‘ n ≀ N, f n)

theorem cauchyabssum_iff_abssummable {I X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  (f: I β†’ X) [CompleteSpace X]: AbsSummable 𝕂 f ↔ CauchySumNet (fun (i: I) ↦ β€–f iβ€–) := by
    sorry

theorem cauchysum_normed {I X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  (f: I β†’ X):
  CauchySumNet f ↔ βˆ€ Ξ΅, 0 < Ξ΅ β†’ (βˆƒ (Fβ‚€: Finset I), βˆ€ (F: Finset I), (Fβ‚€ ∩ F = βˆ… β†’ β€–βˆ‘ i ∈ F, f iβ€– < Ξ΅)) := by
    sorry

theorem cauchy_serie_normed {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  (f: β„• β†’ X):
  CauchySerie f ↔ βˆ€ Ξ΅, 0 < Ξ΅ β†’ (βˆƒ (nβ‚€: β„•), βˆ€ (n m: β„•), (nβ‚€ ≀ n β†’ n ≀ m β†’ β€–(βˆ‘ i ∈ Finset.Ioc n m, f i)β€– < Ξ΅)) := by
    sorry

theorem abssum_implies_sum {I X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  [CompleteSpace X] (f: I β†’ X): AbsSummable 𝕂 f β†’ Summable f := by
    sorry

theorem convabsserie_iff_cauchyabsserie {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  [CompleteSpace X] (f: β„• β†’ X): conv_abs_serie 𝕂 f ↔ CauchySerie (fun (n: β„•) ↦ β€–f nβ€–) := by
    sorry

theorem abs_conv_implies_summable {X: Type*} [SeminormedAddCommGroup X] (𝕂: Type*) [RCLike 𝕂] [NormedSpace 𝕂 X]
  [CompleteSpace X] (f: β„• β†’ X): conv_abs_serie 𝕂 f β†’ Summable f := by
    intro fconvabs
    apply abssum_implies_sum 𝕂
    rw [cauchyabssum_iff_abssummable, cauchysum_normed ℝ]
    rw [convabsserie_iff_cauchyabsserie, cauchy_serie_normed ℝ] at fconvabs
    intro Ξ΅ Ξ΅pos
    rcases fconvabs Ξ΅ Ξ΅pos with ⟨nβ‚€, eq⟩
    use Finset.Icc 0 nβ‚€
    intro F Fneint
    simp only [Real.norm_of_nonneg (Finset.sum_nonneg (fun i x ↦ norm_nonneg (f i)))] at *
    by_cases h: F.Nonempty
    Β· calc
        βˆ‘ i ∈ F, β€–f iβ€– ≀ βˆ‘ i ∈ Finset.Ioc nβ‚€ (Finset.max' F h), β€–f iβ€– := by
          apply Finset.sum_le_sum_of_subset_of_nonneg
          Β· intro n ninF
            rw [Finset.mem_Ioc]
            constructor
            Β· by_contra! nlenβ‚€
              have: n ∈ Finset.Icc 0 nβ‚€ ∩ F := by
                rw [Finset.mem_inter, Finset.mem_Icc]
                exact And.intro (And.intro (Nat.zero_le n) nlenβ‚€) ninF
              sorry
            Β· exact Finset.le_max' F n ninF
          Β· intro i _ _
            exact norm_nonneg (f i)
        _ < Ξ΅ := by
          have: nβ‚€ < F.max' h := by
            have: F.max' h βˆ‰ Finset.Icc 0 nβ‚€ := by
              by_contra h'
              have : F.max' h ∈ Finset.Icc 0 nβ‚€ ∩ F := by
                exact Finset.mem_inter_of_mem h' (Finset.max'_mem F h)
              sorry
            rw [Finset.mem_Icc] at this
            push_neg at this
            exact this (zero_le (F.max' h))
          exact eq nβ‚€ (F.max' h) (le_refl nβ‚€) (le_of_lt this)
    Β· rw [Finset.not_nonempty_iff_eq_empty] at h
      rw [h, Finset.sum_empty]
      exact Ξ΅pos

Etienne Marion (Dec 03 2024 at 20:28):

The issue is with open Classical at the top of the file. The problem is that this will automatically provide instances for things like "the intersection of finite sets exists" but the instance will then clash when the type actually has this instance defined (typically the intersection of Finset Nat has a different instance) so that the intersection you want to rewrite with does not come from the same instance as the one you want to rewrite. I noticed this by writing

have : Finset.Icc 0 nβ‚€ ∩ F = βˆ… := Fneint

because the error prints the instance used.

The solution to this problem is simply to remove open Classical (I was advised personally to never write this). Once you do this you get errors. To solve them there are two possibilities: if the statement you write works well and the error only comes in the proof, you can use the tactic classical anywhere you want before the error and it will work. If the statement itself does not work, then you have to add an assumption in the theorem. Typically in your case the theorem cauchysum_normed creates an error because Lean does not know how to synthesize Inter (Finset I) you can solve this by adding [DecidableEq I] to your hypotheses. This is not an issue because when you want to apply cauchysum_normed somewhere you can just use classical before and you won't need to provide the instance.

Esteban MartΓ­nez VaΓ±Γ³ (Dec 04 2024 at 06:59):

I see. Thank you!

I'll try then to avoid using open Classical, but then I have some other problems.

Without opening it, how can I make the following definition work?

import Mathlib.Topology.Instances.Real

noncomputable section

class DirectedSet (D: Type*) extends Preorder D, Inhabited D, IsDirected D (fun d d' ↦ d ≀ d')

def default' (D: Type*) [DirectedSet D] := @Inhabited.default D DirectedSet.toInhabited

def seqfromnet {X D: Type*} [PseudoMetricSpace X] [DirectedSet D] (t: D β†’ X) (s: β„• β†’ ℝ): β„• β†’ D
  | 0 => if h: βˆƒ dβ‚€, (βˆ€ (d e : D), dβ‚€ ≀ d β†’ dβ‚€ ≀ e β†’ dist (t d) (t e) < s 0) then Classical.choose h else default' D
  | n + 1 => if h: βˆƒ (dβ‚€: D), ((seqfromnet t s n) ≀ dβ‚€ ∧ ((βˆ€ (d e : D), dβ‚€ ≀ d β†’ dβ‚€ ≀ e β†’ dist (t d) (t e) < s (n + 1)))) then Classical.choose h else default' D

And also, what does exactly the tactic classical do? It is like opening Classical and all its related theorems, but only for the proof?

Esteban MartΓ­nez VaΓ±Γ³ (Dec 04 2024 at 07:21):

I've seen that I can make a section for the definition and put there the open Classical, but is there a better option?

Etienne Marion (Dec 04 2024 at 09:33):

You can do this for example:

import Mathlib.Topology.Instances.Real

noncomputable section

class DirectedSet (D: Type*) extends Preorder D, Inhabited D, IsDirected D (fun d d' ↦ d ≀ d')

def default' (D: Type*) [DirectedSet D] := @Inhabited.default D DirectedSet.toInhabited

def seqfromnet {X D: Type*} [PseudoMetricSpace X] [DirectedSet D] (t: D β†’ X) (s: β„• β†’ ℝ): β„• β†’ D := fun k ↦ by
  classical
  exact match k with
  | 0 => if h: βˆƒ dβ‚€, (βˆ€ (d e : D), dβ‚€ ≀ d β†’ dβ‚€ ≀ e β†’ dist (t d) (t e) < s 0) then Classical.choose h else default' D
  | n + 1 => if h: βˆƒ (dβ‚€: D), ((seqfromnet t s n) ≀ dβ‚€ ∧ ((βˆ€ (d e : D), dβ‚€ ≀ d β†’ dβ‚€ ≀ e β†’ dist (t d) (t e) < s (n + 1)))) then Classical.choose h else default' D

Usually you don't want to use tactics in a definition but here it's not a problem because the only tactic used to build the object is exact so it should work in exactly the same way. I do not know if there is a better option.

Esteban MartΓ­nez VaΓ±Γ³ (Dec 04 2024 at 10:43):

Okay, that works. Thanks!

Etienne Marion ha dicho:

Usually you don't want to use tactics in a definition but here it's not a problem because the only tactic used to build the object is exact so it should work in exactly the same way. I do not know if there is a better option.

I see. I'll take it into account.

Kim Morrison (Dec 04 2024 at 23:29):

I would be inclined to just write open Classical in before the def.

Note also you don't need default' at all. Just write default instead of default' D.

Esteban MartΓ­nez VaΓ±Γ³ (Dec 05 2024 at 07:51):

Kim Morrison ha dicho:

I would be inclined to just write open Classical in before the def.

I'll also take it into consideration :+1:

Kim Morrison ha dicho:

Note also you don't need default' at all. Just write default instead of default' D.

You are right. In some context I got some errors and that's why I introduce the theorem default' and I've used it since then without thinking about it.


Last updated: May 02 2025 at 03:31 UTC