Zulip Chat Archive

Stream: new members

Topic: Inverse image and cast to subsets


Michael Rothgang (Sep 22 2023 at 11:41):

I'm stuck trying to prove a statement about preimages, involving casting of subsets. Mathematically, roughly my problem is: if sts\subset t are subsets of XX and I'm given an element xtx\in t, how can I, in Lean, obtain xx as an element of ss? Find a MWE below. (I guess solving one direction might already help for the other one.)

import Mathlib.Topology.Basic
open Topology

lemma minimized {X Y Z: Type*} [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z]
    {f : Y  Z} {g : X  Y} {t: Set X} {u: Set Y}
    {x : X} (ht: t  𝓝 x) (hu: u  𝓝 (g x)) : True /- dummy statement -/ := by
  -- idea: shrink u to g(t); more precisely: restrict g to the preimage of u under g':=g∣t.
  let g' := t.restrict g
  let t' : Set X := (g' ⁻¹' u)
  -- The following is mathematically easy; I'm wrestling with filling the sorries.
  have h₁ : t' = t  g ⁻¹' u := by
    apply Iff.mpr (Set.Subset.antisymm_iff)
    constructor
    · intro x hx
      constructor
      · exact Set.coe_subset hx
      · -- goal: x ∈ g ⁻¹' u
        -- informal argument: as x ∈ t', we can apply g' (and land in u by definition), so g'(x)=g(x) ∈ u
        -- my first step: present x is an element of t
        have : x  t := by sorry -- apply Set.mem_coe_of_mem hx, somehow?
        -- now I'm stuck
        sorry
    · rintro x ht, hgu
      -- goal: x ∈ t'
      -- informal argument: as x ∈ t, we can write g(x)=g'(x); the rhs lies in u, so x ∈ g⁻¹(u) also
      sorry
  trivial

Alex J. Best (Sep 22 2023 at 11:57):

Instead of thinking about your problem I just hit it with a hammer and it worked :wink:

import Mathlib.Topology.Basic
open Topology

lemma minimized {X Y Z: Type*} [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z]
    {f : Y  Z} {g : X  Y} {t: Set X} {u: Set Y}
    {x : X} (ht: t  𝓝 x) (hu: u  𝓝 (g x)) : True /- dummy statement -/ := by
  -- idea: shrink u to g(t); more precisely: restrict g to the preimage of u under g':=g∣t.
  let g' := t.restrict g
  set t' : Set X := (g' ⁻¹' u) with ht'
  -- The following is mathematically easy; I'm wrestling with filling the sorries.
  have h₁ : t' = t  g ⁻¹' u := by
    rw [ht']
    ext1 y
    simp [Lean.Internal.coeM]
    aesop

  trivial

Alex J. Best (Sep 22 2023 at 11:58):

I've seen this Lean.Internal.coeM thing showing up before and it probably shouldn't show up in mathematical proofs, but it seems to be unavoidable now :confused:

Ruben Van de Velde (Sep 22 2023 at 11:59):

Yeah, I was worried about that coeM too, so I avoided it:

import Mathlib.Topology.Basic
open Topology

lemma minimized {X Y Z: Type*} [TopologicalSpace X] [TopologicalSpace Y] [TopologicalSpace Z]
    {f : Y  Z} {g : X  Y} {t: Set X} {u: Set Y}
    {x : X} (ht: t  𝓝 x) (hu: u  𝓝 (g x)) : True /- dummy statement -/ := by
  -- idea: shrink u to g(t); more precisely: restrict g to the preimage of u under g':=g∣t.
  let g' := t.restrict g
  let t'' := (g' ⁻¹' u)
  let t' : Set X := { (x : X) | x  t'' }
  -- The following is mathematically easy; I'm wrestling with filling the sorries.
  have h₁ : t' = t  g ⁻¹' u := by
    apply Iff.mpr (Set.Subset.antisymm_iff)
    constructor
    · intro x hx
      simp at hx
      obtain x, ha1, ha2, rfl := hx
      constructor
      · assumption
      · -- goal: x ∈ g ⁻¹' u
        -- informal argument: as x ∈ t', we can apply g' (and land in u by definition), so g'(x)=g(x) ∈ u
        -- my first step: present x is an element of t
        -- now I'm stuck
        simp [ha1]
    · rintro x ht, hgu
      -- goal: x ∈ t'
      -- informal argument: as x ∈ t, we can write g(x)=g'(x); the rhs lies in u, so x ∈ g⁻¹(u) also
      simp at hgu
      simp
      use x
  trivial

Michael Rothgang (Sep 22 2023 at 12:13):

Wow, thanks a lot for the quick responses, both of you!

Michael Rothgang (Sep 22 2023 at 12:15):

I didn't know about set (or ext1) before.
And I'm glad to have an aesop-free argument in case I need one (the aesop output is not nice).

Jireh Loreaux (Sep 22 2023 at 17:59):

docs#Lean.Internal.coeM is just the coercion between monadic types induced by a coercion between their underlying types. It's not a problem that we see it, just a bit annoying. We need to find a good place to add the @[coe] attribute to this declaration. This is in core, but the attribute isn't declared until Std.

Jireh Loreaux (Sep 22 2023 at 17:59):

In your case, Set is the monad.

Jireh Loreaux (Sep 22 2023 at 18:02):

For example, if t : Set X, then there is a coercion (↑) : ↥t → X (this is Subtype.val), and then Lean.Interal.coeM is the coercion (↑) : Set ↥t → Set X, but it doesn't get the because it doesn't have the @[coe] attribute.

Alex J. Best (Sep 23 2023 at 00:35):

Jireh Loreaux said:

docs#Lean.Internal.coeM is just the coercion between monadic types induced by a coercion between their underlying types. It's not a problem that we see it, just a bit annoying. We need to find a good place to add the @[coe] attribute to this declaration. This is in core, but the attribute isn't declared until Std.

I'm not sure Jireh, the docstring of Lean.Internal.coeM quite clearly says "Helper definition used by the elaborator. It is not meant to be used directly by users." which makes me worry that something is not quite working as intended here

Jireh Loreaux (Sep 23 2023 at 00:56):

I think that docstring still agrees with what I said. The user should never write down this function, it should only exist as the result of other coercions.

Alex J. Best (Sep 23 2023 at 01:25):

I'm still unconvinced, it's tagged as @[coe_decl] which says, "auxiliary definition used to implement coercion (unfolded during elaboration" but I've not yet finished debugging why the unfolding is not working in this case

Alex J. Best (Sep 24 2023 at 18:25):

With https://github.com/alexjbest/lean4/tree/patch-4

import Mathlib.Data.Set.Functor
example {A : Type} {B : Set A} {C : Set B} : (C : Set A) = B := by
  sorry

gives a goal

(do
    let a  C
    pure a) =
  B

instead of Internal.coeM C = B, one advantage of this is that dsimp now results in something sensible ⋃ (i : ↑B) (_ : i ∈ C), {↑i} = B

Anatole Dedecker (Sep 24 2023 at 20:09):

I agree that this is cleaner. I really think we shouldn't train users to see names such as Internal.something as things that should be used in everyday proofs. Am I right that there was no coercion form Set A to Set B given a coercion from A to B in Lean3? Is there any risk of such a coercion causing diamonds somewhere?

Yaël Dillies (Sep 24 2023 at 20:24):

There was no such coercion, no. I don't think such a coercion will cause a diamond, unless we also introduce the Coe A B → Coe (Set B) (Set A) instance given by the preimage, in which case they'll conflict when A = B.


Last updated: Dec 20 2023 at 11:08 UTC