Zulip Chat Archive

Stream: general

Topic: cardinality of product of two sets


Huỳnh Trần Khanh (Mar 06 2025 at 13:22):

should this be included in mathlib? I license this code under Apache License 2.0 so anyone can further work on it and get it into mathlib

import Mathlib
lemma jwk {α β : Type} (a : Set α) (b : Set β) : (Set.prod a b).encard = a.encard * b.encard := by
  have eqt : { p : α × β // p.1  a  p.2  b }  (a) × (b) := by
    constructor
    pick_goal 3
    · rintro ⟨⟨m, n, o
      simp only at o
      exact ⟨⟨m, o.1, n, o.2⟩⟩
    pick_goal 3
    · rintro ⟨⟨m, q, n, w⟩⟩
      exact ⟨⟨m, n, q, w⟩⟩
    · rintro ⟨⟨m, n, o
      simp only
    · rintro ⟨⟨m, q, n, w⟩⟩
      simp only
  by_cases x: a.Infinite
  · rw [Set.encard_eq_top x]
    by_cases y: b = 
    · rw [y]; simp only [Set.encard_empty, mul_zero, Set.encard_eq_zero]
      ext ka
      simp only [Set.mem_empty_iff_false, iff_false]
      obtain m, n := ka
      intro wut
      rw [Set.prod, Set.mem_setOf] at wut
      simp only [Set.mem_empty_iff_false, and_false] at wut
    · have wk : b.encard  0 := by
        intro aj
        exact y (by exact Set.encard_eq_zero.mp aj)
      simp only [ne_eq, wk, not_false_eq_true, ENat.top_mul, Set.encard_eq_top_iff]
      rw [Set.infinite_coe_iff]
      simp only [Set.prod, Set.coe_setOf]
      rw [Equiv.infinite_iff eqt]
      simp only [infinite_prod]
      left
      constructor
      · exact Set.infinite_coe_iff.mpr x
      · exact Set.nonempty_iff_ne_empty'.mpr y
  have ty : a.Finite := by exact Set.not_infinite.mp x
  by_cases z : b.Infinite
  · by_cases t : a = 
    · rw [t]; simp only [Set.encard_empty, zero_mul, Set.encard_eq_zero]
      ext ka
      simp only [Set.mem_empty_iff_false, iff_false]
      obtain m, n := ka
      intro wut
      rw [Set.prod, Set.mem_setOf] at wut
      simp only [Set.mem_empty_iff_false, false_and] at wut
    · have wk : a.encard  0 := by
        intro aj
        exact t (by exact Set.encard_eq_zero.mp aj)
      have ue : b.encard =  := by exact Set.encard_eq_top_iff.mpr z
      simp only [ue, ne_eq, wk, not_false_eq_true, ENat.mul_top, Set.encard_eq_top_iff]
      rw [Set.infinite_coe_iff]
      simp only [Set.prod, Set.coe_setOf]
      rw [Equiv.infinite_iff eqt]
      simp only [infinite_prod]
      right
      constructor
      · exact Set.nonempty_iff_ne_empty'.mpr t
      · exact Set.infinite_coe_iff.mpr z
  · have tb : b.Finite := by exact Set.not_infinite.mp z
    rw [Set.Finite.encard_eq_coe_toFinset_card ty, Set.Finite.encard_eq_coe_toFinset_card tb]
    norm_cast
    rw [Finset.card_product]
    have ei : Finite (a.prod b) := by
      rw [Set.prod]
      simp only [Set.coe_setOf]
      rw [Equiv.finite_iff eqt]
      have jak : Finite a := by exact ty
      have yak : Finite b := tb
      apply Finite.instProd
    have di : (a.prod b).Finite := ei
    rw [Set.Finite.encard_eq_coe_toFinset_card di]
    norm_cast
    apply Finset.card_bijective id
    · exact Function.bijective_id
    · simp only [Set.Finite.mem_toFinset, id_eq, Finset.mem_product, Prod.forall]
      intros a1 b1
      simp only [Set.prod, Set.mem_setOf_eq]

Aaron Liu (Mar 06 2025 at 13:24):

You should not use Set.prod a b, but instead a ×ˢ b.

Aaron Liu (Mar 06 2025 at 13:36):

I golfed your proof

import Mathlib.Data.Finite.Prod
import Mathlib.Data.Set.Card

theorem Set.encard_prod {α β : Type*} (a : Set α) (b : Set β) :
    (a ×ˢ b).encard = a.encard * b.encard := by
  obtain rfl | hae := a.eq_empty_or_nonempty
  · simp
  obtain rfl | hbe := b.eq_empty_or_nonempty
  · simp
  obtain ha | ha := a.infinite_or_finite
  · rw [(ha.prod_left hbe).encard_eq, ha.encard_eq, ENat.top_mul hbe.encard_pos.ne']
  obtain hb | hb := b.infinite_or_finite
  · rw [(hb.prod_right hae).encard_eq, hb.encard_eq, ENat.mul_top hae.encard_pos.ne']
  rw [ha.encard_eq_coe_toFinset_card, hb.encard_eq_coe_toFinset_card]
  rw [(ha.prod hb).encard_eq_coe_toFinset_card,  ENat.coe_mul, ENat.coe_inj]
  rw [ ha.toFinset_prod hb, Finset.card_product]

Huỳnh Trần Khanh (Mar 06 2025 at 13:40):

thank you! could you also get it into mathlib please? I don't have write access and I know I'm not supposed to fork it

Aaron Liu (Mar 06 2025 at 13:44):

You can ask for access in #mathlib4 > github permission

Yury G. Kudryashov (Mar 06 2025 at 18:15):

This should follow from the general version in Cardinal

Huỳnh Trần Khanh (Mar 06 2025 at 18:18):

yeah I thought theorems in Cardinal could help but then it turns out to be nontrivial. also there are already theorems for bijection and addition for Set.encard and Set.ncard, I guess adding one more theorem for multiplication isn't redundant

Yury G. Kudryashov (Mar 06 2025 at 22:20):

import Mathlib.Data.Set.Card

@[simp]
theorem ENat.card_prod (α β : Type*) : ENat.card (α × β) = .card α * .card β := by
simp [ENat.card]

@[simp]
theorem Set.ncard_prod {α β : Type*} (s : Set α) (t : Set β) : (s ×ˢ t).encard = s.encard * t.encard := by
simp [Set.encard, ENat.card_congr (Equiv.Set.prod ..)]

Huỳnh Trần Khanh (Mar 07 2025 at 06:15):

I guess you are intentionally giving me a chance to make a pull request, so here it is https://github.com/leanprover-community/mathlib4/pull/22676

Huỳnh Trần Khanh (Mar 07 2025 at 06:16):

it's been several years since I last contributed to mathlib and the process is still largely the same


Last updated: May 02 2025 at 03:31 UTC