Zulip Chat Archive

Stream: new members

Topic: set unions


Antoine Chambert-Loir (Nov 13 2021 at 02:11):

I am not particularly happy of having written these lines, in either version. Does anybody see how to shorten it ?

import data.set.basic
import data.set.lattice

variables ι α: Type*


lemma Union_union_distrib' {ι} {α} (s : ι  set α) (J₁ J₂ : set ι) :
  ( (j : (J₁  J₂)), s j) = ( (j : J₁), s j)  ( (j : J₂), s j) :=
begin

  apply set.ext, intro x,
  split,

  { intro hx,
    obtain j, hxj := set.mem_Union.1 hx,
    have z : j  J₁  j  J₂,
          { apply (set.mem_union j J₁ J₂).1,  exact subtype.mem j, },
    apply or.elim z,
    { intro hj, apply set.mem_union_left,
      apply set.mem_Union.2,
      use j, exact hj, exact hxj, },
    { intro hj, apply set.mem_union_right,
      apply set.mem_Union.2,
      use j, exact hj, exact hxj, },  },

  { intro hx,
    apply or.elim hx,
    { intro hx1, obtain j, hxj   := set.mem_Union.1 hx1,
      apply set.mem_Union.2, use j, apply set.mem_union_left,
      exact subtype.mem j, exact hxj, },
    { intro hx1, obtain j, hxj   := set.mem_Union.1 hx1,
      apply set.mem_Union.2, use j, apply set.mem_union_right,
      exact subtype.mem j, exact hxj, }, },
end


lemma Union_union_distrib'' {ι} {α} (s : ι  set α) (J₁ J₂ : set ι) :
  ( (j : (J₁  J₂)), s j) = ( (j : J₁), s j)  ( (j : J₂), s j) :=
begin
  apply set.subset.antisymm_iff.2 ,  split,

  apply set.Union_subset, intro i,
  have z : i  J₁  i  J₂,
          { apply (set.mem_union i J₁ J₂).1,  exact subtype.mem i, },
  apply or.elim z,
  { intro hi, apply set.subset_union_of_subset_left  ,
      apply set.subset_Union (set.restrict s J₁) i, hi⟩, },
  { intro hi, apply set.subset_union_of_subset_right  ,
      apply set.subset_Union (set.restrict s J₂) i, hi⟩, },


  apply set.union_subset,
  { apply set.Union_subset, intro i,
    exact set.subset_Union (set.restrict s (J₁  J₂))
      i, (set.mem_union i J₁ J₂).2 (or.intro_left _ (subtype.mem i))⟩, },
  { apply set.Union_subset, intro i,
    exact set.subset_Union (set.restrict s (J₁  J₂))
      i, (set.mem_union i J₁ J₂).2 (or.intro_right _ (subtype.mem i))⟩, },
end

Adam Topaz (Nov 13 2021 at 02:35):

Here it is golfed to a reasonable state:

import data.set.basic
import data.set.lattice

variables ι α: Type*

import data.set.basic
import data.set.lattice

variables ι α: Type*

lemma Union_union_distrib' {ι} {α} (s : ι  set α) (J₁ J₂ : set ι) :
  ( (j : (J₁  J₂)), s j) = ( (j : J₁), s j)  ( (j : J₂), s j) :=
begin
  ext x,
  split,
  { rintro S, ⟨⟨j, (hj|hj)⟩, rfl⟩, hx⟩,
    { exact or.inl _, ⟨⟨j, hj⟩, rfl⟩, hx },
    { exact or.inr _, ⟨⟨j, hj⟩, rfl⟩, hx } },
  { rintro (⟨_, ⟨⟨⟨j, hj⟩, rfl⟩, hx⟩⟩ | _, ⟨⟨⟨j, hj⟩, rfl⟩, hx⟩⟩),
    { exact _, ⟨⟨j, or.inl hj⟩, rfl⟩, hx },
    { exact _, ⟨⟨j, or.inr hj⟩, rfl⟩, hx } }
end

tactic#rintro is amazing!

Adam Topaz (Nov 13 2021 at 02:37):

Note also that explicitly denoting the coercions is not necessary.

Eric Wieser (Nov 13 2021 at 09:27):

Do we have docs#set.Union_subtype? If we had ⋃ i : s, f I = ⋃ i ∈ s, f i then you could just apply docs#set.Union_or after docs#set.mem_union

Eric Wieser (Nov 13 2021 at 09:32):

Ah, it's docs#set.bUnion_eq_Union in reverse

Sebastien Gouezel (Nov 13 2021 at 09:58):

What about

theorem set.bUnion_eq_Union' (s : set ι) (t : ι  set α) :
  ( x  s, t x) = ( x : s, t x) :=
supr_subtype'

lemma Union_union_distrib' {ι} {α} (s : ι  set α) (J₁ J₂ : set ι) :
  ( (j : (J₁  J₂)), s j) = ( (j : J₁), s j)  ( (j : J₂), s j) :=
by rw [ set.bUnion_eq_Union',  set.bUnion_eq_Union',  set.bUnion_eq_Union', set.bUnion_union]

But mainly, this indicates that what you are doing is not really idiomatic: instead of using Unions over subtypes, it is more usual to use a Union with the condition that the point belongs to a subset (called bUnion in our naming conventions). I.e., if you replace your lemma with

lemma Union_union_distrib' {ι} {α} (s : ι  set α) (J₁ J₂ : set ι) :
  ( (j  (J₁  J₂)), s j) = ( (j  J₁), s j)  ( (j  J₂), s j) :=

then this is just bUnion_union.


Last updated: Dec 20 2023 at 11:08 UTC