Zulip Chat Archive
Stream: maths
Topic: Type / Type* using cardinal
Antoine Chambert-Loir (Mar 24 2022 at 23:53):
The following function gives me the existence an element outside of the range of a function from fin n
provided the cardinal of the target type is greater than n
, but that only works when the target type is chosen as a Type
but not a Type*
.
import set_theory.cardinal
open_locale cardinal
lemma gimme_more {α : Type} (m : ℕ) (x : fin m → α) (hα : ↑m < #α) :
∃ (a : α), a ∉ set.range x :=
begin
suffices : ¬ (function.surjective x),
exact not_forall.mp this,
intro h,
apply (lt_iff_not_ge _ _).mp hα,
rw ← cardinal.mk_fin,
exact cardinal.mk_le_of_surjective h
end
lemma gimme_more' {α : Type*} (m : ℕ) (x : fin m → α) (hα : ↑m < #α) :
∃ (a : α), a ∉ set.range x :=
begin
suffices : ¬ (function.surjective x),
exact not_forall.mp this,
intro h,
apply (lt_iff_not_ge _ _).mp hα,
rw ← cardinal.mk_fin,
exact cardinal.mk_le_of_surjective h
end
(For some time, I was OK with setting alpha as a Type
, but later one, Lean complained that I should use set_like.coe_mem
with a Type ?
as a target, but not just a Type
…)
Eric Rodriguez (Mar 25 2022 at 00:27):
note that fin n
is in Type
, causing you the issue... try docs#cardinal.lift_mk_of_fin
Antoine Chambert-Loir (Mar 25 2022 at 07:59):
There is a typo in the name of your function, I'm browsing the library to find the correct one.
Aside : why isn't fin n
in Type 0
?
Kevin Buzzard (Mar 25 2022 at 08:00):
It is?
Kevin Buzzard (Mar 25 2022 at 08:01):
Try #check (fin 37 : Type 0)
. I'd be surprised if it failed
Antoine Chambert-Loir (Mar 25 2022 at 08:04):
It doesn't fails but returns fin 37 : Type
.
Filippo A. E. Nuccio (Mar 25 2022 at 08:09):
But I thought that Type=Type 0
, no?
Antoine Chambert-Loir (Mar 25 2022 at 08:09):
Oh! I had presumed the opposite, namely that Type
wouldn't refer to a specific universe.
Filippo A. E. Nuccio (Mar 25 2022 at 08:14):
Well, I am certainly not an expert, but reading Ch. 7 of "Theorem proving in Lean", you can see that they start by saying
We have seen that Lean’s formal foundation includes basic types,
Prop
,Type 0
,Type 1
,Type 2
, ..., and allows ...
I think that " the types of an unspecified universe" should not really exist.
Adam Topaz (Mar 25 2022 at 08:21):
Type
and Type 0
are indeed the same
Adam Topaz (Mar 25 2022 at 08:22):
And they're the same as Sort 1
, while Prop
is Sort 0
.
Adam Topaz (Mar 25 2022 at 08:26):
Generally if we want to make a statement that's polymorphic over all type universes, we would use Type*
or Type u
after naming a universe variable. If we want to be polymorphic over all Type universes and also Prop, we use Sort*
or Sort u
Adam Topaz (Mar 25 2022 at 08:28):
When you have concrete types such as fin 37
, , etc., they will usually be in Type
(equiv. Type 0
).
Antoine Chambert-Loir (Mar 25 2022 at 09:30):
The question for me seems to transform a surjectiveh :fin m -> t
(with m : nat
and t : Type u
) to a surjective map from a variant of fin m
which also belongs to Type u
.
Antoine Chambert-Loir (Mar 25 2022 at 10:15):
This is a proof of gimme_more'
, but I found it horrible to write! There must be some better way…
import set_theory.cardinal
import control.ulift
open_locale cardinal
lemma gimme_more {α : Type} (m : ℕ) (x : fin m → α) (hα : ↑m < #α) :
∃ (a : α), a ∉ set.range x :=
begin
apply not_forall.mp,
change ¬ (function.surjective x),
intro h,
apply (lt_iff_not_ge _ _).mp hα,
rw ← cardinal.mk_fin,
exact cardinal.mk_le_of_surjective h
end
lemma gimme_more' {α : Type*} (m : ℕ) (x : fin m → α) (hα : ↑m < #α) :
∃ (a : α), a ∉ set.range x :=
begin
apply not_forall.mp,
-- change ¬ (function.surjective x),
intro h,
apply (lt_iff_not_ge _ _).mp hα,
-- rw ge_iff_le,
have h' : function.surjective (ulift.map x),
{ intro a, obtain ⟨i, hi⟩ := h a.down, use i,
rw [ulift.map_up, hi, ulift.up_down] },
let z := cardinal.mk_le_of_surjective h',
simp only [cardinal.mk_ulift, cardinal.mk_fintype,
fintype.card_ulift, fintype.card_fin] at z,
rw cardinal.lift_id at z,
exact z,
end
Antoine Chambert-Loir (Mar 25 2022 at 10:16):
Maybe one needs ulift_injective_of_injective
and ulift_surjective_of_surjective
…
Antoine Chambert-Loir (Mar 25 2022 at 11:15):
Should I PR these two lemmas ?
import tactic
import control.ulift
namespace ulift
universes u v
variables {α : Type u} {β : Type v}
lemma surjective_of_surjective (f : α → β) (hf : function.surjective f) :
function.surjective (ulift.map f) :=
begin
intro b, obtain ⟨a, ha⟩ := hf b.down, use a,
rw [ulift.map_up, ha, ulift.up_down]
end
lemma injective_of_bijective (f : α → β) (hf : function.injective f) :
function.injective (ulift.map f) :=
begin
intros a a',
rw [← (ulift.up_down a), ← (ulift.up_down a')],
simp only [ulift.map_up, ulift.ext_iff, ulift.down_up],
intro h, exact hf h,
end
end ulift
Eric Rodriguez (Mar 25 2022 at 11:16):
You may find using equiv.ulift
easier
Antoine Chambert-Loir (Mar 25 2022 at 12:22):
Indeed ! The following is much nicer, but I needed to add two “rfl-lemmas” which I don't know how to invoke otherwise.
lemma comp_ulift_eq_ulift_comp {f : α → β} : f ∘ equiv.ulift = equiv.ulift ∘ (ulift.map f) := rfl
lemma comp_ulift_eq_ulift_comp' {f : α → β} :
(ulift.map f) ∘ equiv.ulift.symm = equiv.ulift.symm ∘ f := rfl
lemma surjective_iff_surjective {f : α → β} :
function.surjective f ↔
function.surjective (ulift.map f) :=
by rw [← equiv.comp_surjective, ← comp_ulift_eq_ulift_comp', equiv.surjective_comp]
Eric Rodriguez (Mar 25 2022 at 12:27):
I thought this was a bit easier:
lemma gimme_more' {α : Type*} (m : ℕ) (x : fin m → α) (hα : ↑m < #α) :
∃ (a : α), a ∉ set.range x :=
begin
suffices : ¬ (function.surjective x),
exact not_forall.mp this,
intro h,
apply (lt_iff_not_ge _ _).mp hα,
rw [←cardinal.lift_mk_fin, ←cardinal.mk_ulift],
refine cardinal.mk_le_of_surjective (show function.surjective (x ∘ equiv.ulift), from _),
rwa equiv.surjective_comp,
end
Eric Rodriguez (Mar 25 2022 at 12:28):
or for those last two lines even exact cardinal.mk_le_of_surjective ((equiv.ulift.surjective_comp x).mpr h)
Antoine Chambert-Loir (Mar 25 2022 at 12:32):
At least, it doesn't require to add some external lemmas. (Which I find structurally interesting to have, anyway…)
Antoine Chambert-Loir (Mar 25 2022 at 12:33):
One question about my proof : Is there another way than adding “rfl-lemmas” to rewrite a term to semething else? What is the canonical way to do it in Lean/mathlib ?
Antoine Chambert-Loir (Mar 25 2022 at 12:33):
(In my case, look at comp_ulift_eq_ulift_comp
)
Eric Rodriguez (Mar 25 2022 at 12:39):
I think comp_ulift_eq_ulift_comp
is a bit of a weird lemma, as the end result is you're ulifting to another separate universe (look at pp.universes
- you have <4> universe variables there)
Antoine Chambert-Loir (Mar 25 2022 at 13:10):
Isn't it normal ? I am not sure I understand completely how to interpret what VSCode writes, but equiv.ulift
hides its arguments and before unification takes place, one cannot guess which universes should be there.
Eric Rodriguez (Mar 25 2022 at 13:53):
I think this ulifts twice, is what I'm saying; why would you need two free universe params instead of just one?
Eric Wieser (Mar 27 2022 at 13:39):
It's probably best to write all the universes explicitly for this type of lemma
Eric Wieser (Mar 27 2022 at 13:39):
To make it clear what you intended
Antoine Chambert-Loir (Mar 28 2022 at 06:43):
I just experimented with
-- with universe
lemma comp_ulift_eq_ulift_comp' {f : α → β} :
equiv.ulift.{w v} ∘ (ulift.map.{u v w} f) =
f ∘ equiv.ulift.{w u} := rfl
that involves only 3 universes. However, it makes the proof of ulift.surjective_iff_surjective
etc. break down.
Eric Wieser (Mar 28 2022 at 13:34):
So what's the four-universe version that lean is inferring?
Eric Wieser (Mar 28 2022 at 13:35):
(and what universes are α
and β
in there?)
Antoine Chambert-Loir (Mar 28 2022 at 17:23):
universes u v
variables {α : Type u} {β : Type v}
set_option pp.universes true
lemma comp_ulift_eq_ulift_comp {f : α → β} : equiv.ulift ∘ (ulift.map f) = f ∘ equiv.ulift := rfl
/-
comp_ulift_eq_ulift_comp.{u_1 u_2 u_3 u_4} :
⇑equiv.ulift.{u_4 u_2} ∘ ulift.map.{u_1 u_2 u_3 u_4} ?M_3 = ?M_3 ∘ ⇑equiv.ulift.{u_3 u_1}
-/
Floris van Doorn (Mar 28 2022 at 20:32):
That seems like the right version to me, but writing explicit universe levels might still be useful for future readers.
Btw, the type of ulift.map
is
protected def {u v u_1 u_2} ulift.map : Π {α : Type u} {β : Type v}, (α → β) → ulift.{u_1 u} α → ulift.{u_2 v} β
Last updated: Dec 20 2023 at 11:08 UTC