Zulip Chat Archive

Stream: new members

Topic: ContMDiff puzzle


Dominic Steinitz (Aug 04 2025 at 12:51):

Why don't I need 2 rw terms (one for each occurrence) and I can't work out what Lean is telling me from the error message.

import Mathlib

open Function Set
open IsManifold Manifold

example : ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) = (๐“ก 1).prod (๐“ก 1) :=
 modelWithCornersSelf_prod

variable (f : EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1) โ†’
              EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))

example :
  ContMDiffOn ((๐“ก 1).prod (๐“ก 1))
              ((๐“ก 1).prod (๐“ก 1)) โŠค f
              {x | x.1 0 > 0 โˆจ x.1 0 < 0}
  โ†” ContMDiffOn ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
                ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) โŠค f
                {x | x.1 0 > 0 โˆจ x.1 0 < 0} := by
  constructor
  ยท intro h
    have h0 : ContMDiffOn ((๐“ก 1).prod (๐“ก 1)) ((๐“ก 1).prod (๐“ก 1)) โŠค f
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} := h
    have h1 : ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) = (๐“ก 1).prod (๐“ก 1) :=
      modelWithCornersSelf_prod
    rw [โ† h1] at h
    exact h
  ยท intro h
    have h0 : ContMDiffOn ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
                          ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) โŠค f
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} := h
    have h1 : ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) = (๐“ก 1).prod (๐“ก 1) :=
      modelWithCornersSelf_prod
    rw [h1] at h
    exact h

Dominic Steinitz (Aug 08 2025 at 16:16):

In case anyone is interested. I still don't know why my original attempt failed though.

import Mathlib

open Function Set
open IsManifold Manifold

example : ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) = (๐“ก 1).prod (๐“ก 1) :=
 modelWithCornersSelf_prod

variable (f : EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1) โ†’
              EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))

example  : ContMDiffOn ((๐“ก 1).prod (๐“ก 1))
              ((๐“ก 1).prod (๐“ก 1)) โŠค f
              {x | x.1 0 > 0 โˆจ x.1 0 < 0}
  โ†” ContMDiffOn ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
                ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) โŠค f
                {x | x.1 0 > 0 โˆจ x.1 0 < 0} := by
  have ha2b : ContMDiff
    ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    ((๐“ก 1).prod (๐“ก 1))
    โŠค
    (id : EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1) โ†’
          EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) := by
    rw [contMDiff_iff]
    constructor
    ยท exact continuous_id
    ยท intro x y
      exact contDiffOn_id

  have hb2a : ContMDiff
    ((๐“ก 1).prod (๐“ก 1))
    ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    โŠค
    (id : EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1) โ†’
          EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) := by
    rw [contMDiff_iff]
    constructor
    ยท exact continuous_id
    ยท intro x y
      exact contDiffOn_id
  constructor
  ยท intro h
    have h0 : ContMDiffOn ((๐“ก 1).prod (๐“ก 1)) ((๐“ก 1).prod (๐“ก 1)) โŠค f
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} := h
    have h1 : ContMDiffOn
              ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
              ((๐“ก 1).prod (๐“ก 1)) โŠค (f โˆ˜ id)
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} :=
               ContMDiffOn.comp h0
                (ContMDiffOn.mono (contMDiffOn_univ.mpr ha2b) (Set.subset_univ _)) (fun โฆƒaโฆ„ a โ†ฆ a)
    have h2 : ContMDiffOn
              ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
              ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) โŠค (id โˆ˜ f โˆ˜ id)
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} :=
      ContMDiffOn.comp (contMDiffOn_univ.mpr hb2a) h1 (Set.subset_univ _)
    exact h2
  ยท intro h
    have h0 : ContMDiffOn ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
                          ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) โŠค f
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} := h
    have h1 : ContMDiffOn
              ((๐“ก 1).prod (๐“ก 1))
              ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
              โŠค (f โˆ˜ id)
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} :=
               ContMDiffOn.comp h0
                (ContMDiffOn.mono (contMDiffOn_univ.mpr hb2a) (Set.subset_univ _)) (fun โฆƒaโฆ„ a โ†ฆ a)
    have h2 : ContMDiffOn
              ((๐“ก 1).prod (๐“ก 1))
              ((๐“ก 1).prod (๐“ก 1))
               โŠค (id โˆ˜ f โˆ˜ id)
              {x | x.1 0 > 0 โˆจ x.1 0 < 0} :=
      ContMDiffOn.comp (contMDiffOn_univ.mpr ha2b) h1 (Set.subset_univ _)
    exact h2

Aaron Liu (Aug 08 2025 at 16:19):

Dominic Steinitz said:

Why don't I need 2 rw terms (one for each occurrence)

That's just how rw works: it rewrites all occurrences

Aaron Liu (Aug 08 2025 at 16:20):

if you don't want it to rewrite all occurrences you can specify which occurrences you want with (occs := [1, 2, 5]) (or specify the ones you don't want with (occs := .neg [3, 4, 6]))

Dominic Steinitz (Aug 08 2025 at 16:23):

I have an example here (not an MWE)

rw [Set.image_pair, Set.image_pair]

if I remove the second rw then my proof fails.

So now I am confused.

Aaron Liu (Aug 08 2025 at 16:26):

That's because you're rewriting with different arguments

Aaron Liu (Aug 08 2025 at 16:26):

rw will only rewrite with one set of arguments at a time

Aaron Liu (Aug 08 2025 at 16:28):

so if you rw [add_zero, add_zero, add_zero] on
1 + 0 + 0 = 0 + (1 + 0) + 0 will transform the goal into
1 + 0 = 0 + (1 + 0) + 0, and then
1 = 0 + 1 + 0, and then
1 = 0 + 1

Aaron Liu (Aug 08 2025 at 16:30):

see how it rewrites all the occurrences with one instantiation at a time

Aaron Liu (Aug 08 2025 at 16:30):

so first it rewrites all the 1 + 0 + 0 into 1 + 0, and then it rewrites all the 1 + 0 into 1, and then it rewrites all the 0 + 1 + 0 into 0 + 1

Michael Rothgang (Aug 08 2025 at 16:36):

To re-state what Aaron said: rw searches for the first match of the pattern, and then rewrites this as often as it can. nth_rw <n> only rewrites the n-th occurrence. simp_rw is more like "rw all the occurrences of all the patterns" (but not quite, it uses simp internally, i.e. operates differently).

Dominic Steinitz (Aug 08 2025 at 17:08):

That's great - thanks for the explanation :smiley:

The rw does succeed but the re-written term then gives a difficult to understand error message.

type mismatch
  h
has type
  @ContMDiffOn โ„ DenselyNormedField.toNontriviallyNormedField (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    Prod.normedAddCommGroup Prod.normedSpace (ModelProd (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1)))
    (instTopologicalSpaceModelProd (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1)))
    ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    instTopologicalSpaceProd
    (prodChartedSpace (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1))
      (EuclideanSpace โ„ (Fin 1)))
    (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) Prod.normedAddCommGroup Prod.normedSpace
    (ModelProd (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1)))
    (instTopologicalSpaceModelProd (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1)))
    ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    instTopologicalSpaceProd
    (prodChartedSpace (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1))
      (EuclideanSpace โ„ (Fin 1)))
    โŠค f {x | x.1 0 > 0 โˆจ x.1 0 < 0} : Prop
but is expected to have type
  @ContMDiffOn โ„ DenselyNormedField.toNontriviallyNormedField (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    Prod.normedAddCommGroup Prod.normedSpace (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    PseudoMetricSpace.toUniformSpace.toTopologicalSpace ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) instTopologicalSpaceProd
    (chartedSpaceSelf (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)))
    (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) Prod.normedAddCommGroup Prod.normedSpace
    (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) PseudoMetricSpace.toUniformSpace.toTopologicalSpace
    ๐“˜(โ„, EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1)) (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))
    instTopologicalSpaceProd (chartedSpaceSelf (EuclideanSpace โ„ (Fin 1) ร— EuclideanSpace โ„ (Fin 1))) โŠค f
    {x | x.1 0 > 0 โˆจ x.1 0 < 0} : Prop

Dominic Steinitz (Aug 08 2025 at 17:10):

I vaguely understand it - I guess there is some sort of type class machinery lurking in the background which means you can't rewrite things that are equal.

Dominic Steinitz (Aug 08 2025 at 17:11):

And I do have a way of doing what I want to do (and which seems entirely reasonable to do) so I am happy to leave it as one of the world's great unresolved mysteries.


Last updated: Dec 20 2025 at 21:32 UTC