Zulip Chat Archive

Stream: new members

Topic: A set of integers "same" as a set of reals


Tony Ma (Dec 05 2024 at 12:52):

I have been told that LEAN treats Z\mathbb{Z} and R\mathbb{R} as different types (if I made the correct phrase). Therefore, Z\mathbb{Z} is not regarded as a subset of R\mathbb{R}, but casting are often required instead. However, I wonder what could I do in order to prove something like this:

have h : {x : ℝ | ∃ n : ℤ, x = n}.encard = {n : ℤ | True}.encard := by sorry

or this:

have g : {x : ℝ| -2 ≤ x ∧ x ≤ 2}.ncard = {x : ℤ| -2 ≤ x ∧ x ≤ 2}.ncard := by sorry

Any help would be appreciated!

Riccardo Brasca (Dec 05 2024 at 13:18):

You can just build a bijection between the two sets.

Riccardo Brasca (Dec 05 2024 at 13:31):

For example, for the first one

import Mathlib

def φ : {n : ℤ | True} → {x : ℝ | ∃ n : ℤ, x = n} := fun n ↦ ⟨n.1, n, rfl⟩

example : {x : ℝ | ∃ n : ℤ, x = n}.encard = {n : ℤ | True}.encard := by
  refine (Set.encard_congr (Equiv.ofBijective φ ⟨fun a b hab ↦ ?_, fun ⟨a, b, h⟩ ↦
    ⟨⟨b, trivial⟩, ?_⟩⟩)).symm
  · simp [φ] at hab
    exact SetCoe.ext hab
  · exact SetCoe.ext h.symm

Tony Ma (Dec 06 2024 at 00:27):

@Riccardo Brasca Thank you! But what does ⟨n.1, n, rfl⟩ means? (Especially, what does n.1 means?) And what if I wanted to create a bijection in reverse way (i.e. function of real numbers to integers)?

Daniel Weber (Dec 06 2024 at 04:18):

The second one isn't true - the first set is infinite, while the second has 5 members

Matt Diamond (Dec 06 2024 at 04:48):

@Tony Ma Here's an example of a bijection in the reverse way (from Real Integers to Integers, using types/subtypes instead of sets):

import Mathlib

open Function Cardinal

-- The subtype of Real Integers
def RealInt : Type := { r : ℝ // r ∈ Set.range Int.cast }

noncomputable
def real_to_int (x : RealInt) : ℤ := x.property.choose

lemma real_to_int_spec (x : RealInt) : Int.cast (real_to_int x) = x.val := x.property.choose_spec

lemma real_to_int_inj : Injective real_to_int :=
by
  intro a b h
  replace h := congrArg (Int.cast (R := ℝ)) h
  simpa [real_to_int_spec, Subtype.val_inj] using h

lemma real_to_int_surj : Surjective real_to_int :=
by
  intro x
  use ⟨Int.cast x, Set.mem_range_self _⟩
  simp [real_to_int]

lemma real_to_int_bij : Bijective real_to_int :=
⟨real_to_int_inj, real_to_int_surj⟩

noncomputable
def RealInt_equiv_Int : RealInt ≃ ℤ :=
Equiv.ofBijective real_to_int real_to_int_bij

-- Real Integers have the same cardinality as the Integers
example : #RealInt = #ℤ := RealInt_equiv_Int.cardinal_eq

Ruben Van de Velde (Dec 06 2024 at 06:39):

For n a value of type {n : ℤ | True} (coerced to a type), n.1 is the underlying value of type ℤ

Tony Ma (Dec 06 2024 at 09:10):

Matt Diamond 发言道:

Tony Ma Here's an example of a bijection in the reverse way (from Real Integers to Integers, using types/subtypes instead of sets):

import Mathlib

open Function Cardinal

-- The subtype of Real Integers
def RealInt : Type := { r : ℝ // r ∈ Set.range Int.cast }

noncomputable
def real_to_int (x : RealInt) : ℤ := x.property.choose

lemma real_to_int_spec (x : RealInt) : Int.cast (real_to_int x) = x.val := x.property.choose_spec

lemma real_to_int_inj : Injective real_to_int :=
by
  intro a b h
  replace h := congrArg (Int.cast (R := ℝ)) h
  simpa [real_to_int_spec, Subtype.val_inj] using h

lemma real_to_int_surj : Surjective real_to_int :=
by
  intro x
  use ⟨Int.cast x, Set.mem_range_self _⟩
  simp [real_to_int]

lemma real_to_int_bij : Bijective real_to_int :=
⟨real_to_int_inj, real_to_int_surj⟩

noncomputable
def RealInt_equiv_Int : RealInt ≃ ℤ :=
Equiv.ofBijective real_to_int real_to_int_bij

-- Real Integers have the same cardinality as the Integers
example : #RealInt = #ℤ := RealInt_equiv_Int.cardinal_eq

Thank you!


Last updated: Feb 28 2026 at 14:05 UTC