Zulip Chat Archive
Stream: new members
Topic: set questions
Joseph O (Apr 28 2022 at 23:54):
Is there a function to get all the subsets of a set? I am trying to prove that something has more subsets than elements in the set
Kyle Miller (Apr 29 2022 at 00:00):
It's got special notation if you want to use it: 𝒫 s
Joseph O (Apr 29 2022 at 00:10):
Oh nice
Joseph O (Apr 29 2022 at 00:13):
How could I construct a goal saying that the number of subsets is greater than the number of elements in the set.
Joseph O (Apr 29 2022 at 00:14):
Also, how could I denote a set with infinite elements. I am trying to construct the proof for there is no biggest infinity, but I am a bit confused about how to construct the proof statement
Arthur Paulino (Apr 29 2022 at 00:19):
Joseph O said:
I am trying to construct the proof for there is no biggest infinity
Are you aiming at aleph numbers?
Probably #xy, but I think you want to prove something along the lines of "given a set of any size, there exists an even bigger set"
Arthur Paulino (Apr 29 2022 at 00:20):
(Of course that's a guess, but I think you need to be more precise about what you mean by "no biggest infinity")
Joseph O (Apr 29 2022 at 00:25):
In reply to this post, that's pretty much exactly what I want to do
Joseph O (Apr 29 2022 at 00:26):
And yes, the aleph numbers seem like I want
Joseph O (Apr 29 2022 at 00:27):
Does lean have lemmas and functions for the aleph numbers?
Kyle Miller (Apr 29 2022 at 00:28):
docs#cardinal.aleph (I searched for "aleph" in the search box)
Kyle Miller (Apr 29 2022 at 00:30):
Are you wanting to work with sets specifically, or are types ok? When X
is a type, set X
is the type of all subsets of X
. docs#cardinal.mk gives the cardinality of a type.
Kyle Miller (Apr 29 2022 at 00:31):
Every element of set X
can be coerced to be a type, and you can get the cardinality of that, so it's fine working sets, but I just thought I'd ask.
Arthur Paulino (Apr 29 2022 at 00:35):
Yeah, the questions I asked weren't very good, sorry. I intended to pose them as somewhat contrasting goals, meaning that you probably don't want to involve aleph numbers in your proof. Although that's the concept that comes to my mind when one talks about "bigger/smaller infinitiy"
Joseph O (Apr 29 2022 at 00:46):
Kyle Miller said:
Are you wanting to work with sets specifically, or are types ok? When
X
is a type,set X
is the type of all subsets ofX
. docs#cardinal.mk gives the cardinality of a type.
Why doesnt cardinal.mk
return a number?
Joseph O (Apr 29 2022 at 00:47):
Like I dont really get this image.png
Joseph O (Apr 29 2022 at 00:49):
Im blindly putting things together but this is sorta what I want (this currently has a type error)
theorem no_largest_inf {α : Type} (inf : (set α)) : 𝒫 inf ≥ cardinal.mk inf := sorry
Joseph O (Apr 29 2022 at 01:00):
How do I make this actually work?
Arthur Paulino (Apr 29 2022 at 01:03):
You won't find many results about ≥
or >
in mathlib. The API is built with <
and ≤
instead
If you want to prove that, for any set s
, the cardinality of s
is less than or equal to the cardinality of the power-set of s
, you don't need to talk about infinite sets
Joseph O (Apr 29 2022 at 01:10):
But the whole point is it being with infinite sets
Joseph O (Apr 29 2022 at 01:33):
how does this look?
theorem no_largest_inf {α : Type} (inf : (set α)) : cardinal.mk inf ≤ cardinal.mk (𝒫 inf) :=
begin
sorry,
end
Arthur Paulino (Apr 29 2022 at 01:37):
Just pasting it with the import that works on my pc:
import set_theory.cardinal
theorem no_largest_inf {α : Type} (inf : (set α)) : cardinal.mk inf ≤ cardinal.mk (𝒫 inf) :=
begin
sorry,
end
Notice that you calling the set inf
doesn't make it infinite
Joseph O (Apr 29 2022 at 01:37):
Yeah I was thinking that. Does this mean I have to use aleph numbers?
Arthur Paulino (Apr 29 2022 at 01:38):
No I think you still need to formulate your problem better, mathematically
Joseph O (Apr 29 2022 at 01:42):
Ok this is what I am trying to prove: Take an infinity containing a set of something; I can create a larger infinity by making an infinity that contains the subsets of the smaller infinity (oh god that was terrible, I doubt its very mathematical)
Arthur Paulino (Apr 29 2022 at 01:48):
Do you have a link to a precise statement of this result? Maybe in some introductory material on set theory, a Wikipedia page or something like that
Joseph O (Apr 29 2022 at 01:50):
Im essentially trying to prove Cantor's theorem
Joseph O (Apr 29 2022 at 01:51):
https://en.wikipedia.org/wiki/Cantor's_theorem
Joseph O (Apr 29 2022 at 01:51):
Every set is smaller than its power set
Arthur Paulino (Apr 29 2022 at 01:53):
Then you've stated the theorem properly already
Joseph O (Apr 29 2022 at 01:54):
But it works for infinite sets?
Arthur Paulino (Apr 29 2022 at 01:55):
Notice that the theorem stated as you did is actually more general than if you wanted to talk about infinite sets, specifically
Joseph O (Apr 29 2022 at 01:56):
Maybe I could prove this theorem, and then use it for infinite sets?
Joseph O (Apr 29 2022 at 01:57):
Should I rename it to cantors_theorem
, or set_lt_powerset
Joseph O (Apr 29 2022 at 01:58):
As for no naming conflicts
Joseph O (Apr 29 2022 at 01:59):
Hmm there doesnt seem to be a cantor_theorem
Jireh Loreaux (Apr 29 2022 at 02:22):
docs#function.cantor_surjective
Jireh Loreaux (Apr 29 2022 at 02:23):
This is the Cantor theorem you are referring to.
Jireh Loreaux (Apr 29 2022 at 02:23):
Of course, there are a variety of ways to phrase it. You could take this theorem and translate it into the language of cardinality.
Joseph O (Apr 29 2022 at 02:24):
I guess I will try and attempt it myself.
Joseph O (Apr 29 2022 at 02:25):
But why is it called cantor_surjective?
Jireh Loreaux (Apr 29 2022 at 02:28):
Click the link. It says there are no surjective functions from a set to it's power set (although it is phrased in terms of types: no surjective function from a type to the type of sets of that type)
Jireh Loreaux (Apr 29 2022 at 02:30):
Notice that docs#function.cantor_injective is also a variation of the Cantor theorem. We can't call them all cantor_theorem because that would be a naming conflict.
Jireh Loreaux (Apr 29 2022 at 02:34):
There's also docs#cardinal.cantor' which is specifically about cardinal numbers.
Kyle Miller (Apr 29 2022 at 02:41):
Going off topic, I just wanted to mention the Lawvere fixed-point theorem, which I think is pretty neat. cantor_surjective
is an easy corollary of it. (Though the theorem is more interesting in other Cartesian closed categories where the exponential object isn't just α → β
, since due to cardinality there's not much you can do with this version except prove contradictions.)
theorem lawvere {α β : Sort*} (ϕ : α → (α → β)) (hϕ : function.surjective ϕ)
(f : β → β) : ∃ s, f s = s :=
begin
let q : α → β := λ a, f (ϕ a a),
obtain ⟨p, hp⟩ := hϕ q,
use ϕ p p,
calc f (ϕ p p) = q p : rfl
... = ϕ p p : by rw hp
end
theorem cantor_surjective' {α : Type*} (ϕ : α → (α → Prop)) : ¬ function.surjective ϕ :=
begin
intro hϕ,
-- get the fixed point of logical negation!
simpa using lawvere ϕ hϕ (λ p, ¬ p),
end
-- recall that `set α` is defined to be `α → Prop`
theorem cantor_surjective {α : Type*} (ϕ : α → set α) : ¬ function.surjective ϕ :=
cantor_surjective' ϕ
Eric Wieser (Apr 29 2022 at 09:25):
Joseph O said:
how does this look?
Here's an easy proof of that in terms of docs#cardinal.cantor
The key trick here is discovering docs#equiv.set.powerset, which I found with library_search
. I made a PR with an expansion of #(𝒫 s)
in #13786
Joseph O (Apr 29 2022 at 11:08):
The version of the proof I learned had to do with surjective functions, so I might try and prove the first.
Joseph O (Apr 29 2022 at 11:45):
Jireh Loreaux said:
This is the Cantor theorem you are referring to.
Not exact actually. That is cantor’s diagonal argument. I am trying to prove the one saying every set is smaller than its powerset
Eric Wieser (Apr 29 2022 at 11:45):
Yes, but that proof is much better stated in terms of α
and set α
than it is in terms of ↥S
and ↥(𝒫 S)
Eric Wieser (Apr 29 2022 at 11:46):
An important skill when using Lean is to know when the math word "set" means set α
, and when it means Type u
Joseph O (Apr 29 2022 at 11:50):
So if I have type a
, set a
is all the subsets?
Riccardo Brasca (Apr 29 2022 at 11:53):
set a
is the type of sets whose elements have type a
. There is so such a thing as "subset of a type", there are sets (whose elements must have the same type) and subsets of sets.
Riccardo Brasca (Apr 29 2022 at 11:53):
(there are subtypes)
Riccardo Brasca (Apr 29 2022 at 11:54):
https://leanprover-community.github.io/theories/sets.html
Joseph O (Apr 29 2022 at 12:05):
Do they work the same way?
Joseph O (Apr 29 2022 at 12:08):
It actually seems like it,
Joseph O (Apr 29 2022 at 12:13):
Eric Wieser said:
Joseph O said:
how does this look?
Here's an easy proof of that in terms of docs#cardinal.cantor
The key trick here is discovering docs#equiv.set.powerset, which I found with
library_search
. I made a PR with an expansion of#(𝒫 s)
in #13786
How does that prove that a set is smaller than its powerset. I guess that makes sense, because of the a < 2 ^ a
Riccardo Brasca (Apr 29 2022 at 12:17):
I think that first of all you should decide how to state this in type theory. Your mathematical statement is that # s < # (𝒫 s)
for any set s
. I think that the equivalent in type theory is # α < # (set α)
, for α : Type u
, but if you prefer you can state it for sets, it's just the the library for cardinals it is written for cardinals of types (of course if you have a set you also have a type, so at the end it doesn't matter, but you have to choose how to state your result).
Joseph O (Apr 29 2022 at 12:21):
Hmm for some reason my lean cant find #
, isnt it imported from set_theory.cardinal.basic
?
Eric Wieser (Apr 29 2022 at 12:22):
open_locale cardinal
Eric Wieser (Apr 29 2022 at 12:22):
It's notation for docs#cardinal.mk
Joseph O (Apr 29 2022 at 12:22):
What does that do?
Eric Wieser (Apr 29 2022 at 12:22):
Eric Wieser said:
open_locale cardinal
It runs all the commands in the locale, which are the commands that turn on the notation
Joseph O (Apr 29 2022 at 12:23):
Got it.
Mauricio Collares (Apr 29 2022 at 12:26):
Joseph O said:
Jireh Loreaux said:
This is the Cantor theorem you are referring to.
Not exact actually. That is cantor’s diagonal argument. I am trying to prove the one saying every set is smaller than its powerset
Cantor's proof that every set is smaller than its powerset is also a diagonal argument. You can check that docs#function.cantor_surjective is not about being non-enumerable.
Mauricio Collares (Apr 29 2022 at 12:28):
https://en.wikipedia.org/wiki/Cantor%27s_diagonal_argument#General_sets
Joseph O (Apr 29 2022 at 12:48):
Aha you are right it is the diagonal argument. My original goal was essentially: If we have an infinite set, the set containing the subsets of the infinite set, essentially the powerset is larger. Using surjectivity I believe, but we didn't use a diagonal argument.
Joseph O (Apr 29 2022 at 12:52):
So this is what I want to prove
theorem cantor_theorem {α : Type} (f : α → (set α)): ¬function.surjective f :=
begin
sorry,
end
Joseph O (Apr 29 2022 at 12:56):
(deleted)
Riccardo Brasca (Apr 29 2022 at 12:58):
First of all write down an extremely detailed mathematical proof. With pen and paper, not in Lean
Joseph O (Apr 29 2022 at 13:03):
Riccardo Brasca said:
Besides this link, is there a nice guide in sets that would tell me how to represent
Yaël Dillies (Apr 29 2022 at 13:05):
set B := {x | x ∉ range f}
Johan Commelin (Apr 29 2022 at 13:06):
@Joseph O Is A
a set
or a Type
?
Joseph O (Apr 29 2022 at 13:14):
Its a Type
Johan Commelin (Apr 29 2022 at 13:15):
Ok, then range f
is indeed what you want. Otherwise there is f '' A
.
Joseph O (Apr 29 2022 at 13:15):
How does it represent the range f(A)
?
Joseph O (Apr 29 2022 at 13:16):
does it infer the A
?
Joseph O (Apr 29 2022 at 13:16):
Yaël Dillies said:
set B := {x | x ∉ range f}
Also, how is that valid, as I never declared an x
Joseph O (Apr 29 2022 at 13:17):
Aha, looking on the side, it seems that it is infered B: set (set α) := {x : set α | x ∉ range f}
Yaël Dillies (Apr 29 2022 at 13:19):
f : α → set α
is enough for Lean to infer that range f : set (set α)
, which is enough to infer that x : set α
, which is enough to infer that B : set (set α)
.
Kevin Buzzard (Apr 29 2022 at 13:20):
Unification is cool :-)
Joseph O (Apr 29 2022 at 13:22):
wow
Joseph O (Apr 29 2022 at 13:23):
how come when i do have ξ : α,
I get two goals?
Joseph O (Apr 29 2022 at 13:24):
MWE:
import init.data.set
import set_theory.cardinal.basic
open set
open nat
open_locale cardinal
theorem cantor_theorem {α : Type} (f : α → (set α)): ¬function.surjective f :=
begin
set B := {x | x ∉ range f},
have ξ : α,
end
Eric Wieser (Apr 29 2022 at 13:25):
Your first goal is the value of ξ
Eric Wieser (Apr 29 2022 at 13:26):
Your second goal is the original goal you started with
Joseph O (Apr 29 2022 at 13:26):
Why? Im trying to do this part of the proof image.png
Yaël Dillies (Apr 29 2022 at 13:27):
Imagine α = empty
. Then you cannot do have ξ : α,
out of thin air.
Eric Wieser (Apr 29 2022 at 13:28):
Joseph O said:
Why?
have h : p,
means "create a new goal with target p
, and put h : p
in the existing goal.
Joseph O said:
Im trying to do this part of the proof image.png
This isn't a proof, this is a statement. The previous or following sentence will say why such an ξ exists, and you have to translate that sentence to lean too
Kevin Buzzard (Apr 29 2022 at 13:28):
"there exists xi such that..." is not have xi
, it's have h : \exists \xi, <property that xi has>
Joseph O (Apr 29 2022 at 13:33):
So I did by_contradiction
, which assumes f
is surjective, which means there exists ∃ ξ, ξ ∈ α
by_contradiction,
have h : ∃ ξ, ξ ∈ α
but it is failing to satisfy some sort of type class instance
Eric Wieser (Apr 29 2022 at 13:34):
ξ ∈ α
is nonsense
Eric Wieser (Apr 29 2022 at 13:35):
It would be like writing (n : ℕ) (hn : n ∈ ℕ)
Joseph O (Apr 29 2022 at 13:35):
Is it already inferred?
Eric Wieser (Apr 29 2022 at 13:35):
I think have ξ : α,
was the correct thing to write here
Eric Wieser (Apr 29 2022 at 13:36):
Joseph O said:
Is it already inferred?
No, it's just meaningless. ∈
is defined on sets, α
is a type
Eric Wieser (Apr 29 2022 at 13:36):
If you insist on writing the ∈
symbol, you can write ξ ∈ (set.univ : set α)
, i.e. "ξ
is in the set consisting of all possible values of α
".
Eric Wieser (Apr 29 2022 at 13:37):
This is of course useless, because by definition everything is in set.univ
.
Joseph O (Apr 29 2022 at 13:39):
Hmm but then that keeps making two goals. How would you represent this in lean?
Eric Wieser (Apr 29 2022 at 13:40):
Yes, it's making two goals because you have to tell lean why ξ : α
exists
Joseph O (Apr 29 2022 at 13:40):
It exists if f
is surjective
Eric Wieser (Apr 29 2022 at 13:40):
Great, you need to work out how to tell lean that
Joseph O (Apr 29 2022 at 13:41):
I would think with exact
?
Eric Wieser (Apr 29 2022 at 13:41):
Joseph O said:
It exists if
f
is surjective
What's the maths proof?
Joseph O (Apr 29 2022 at 13:42):
Eric Wieser (Apr 29 2022 at 13:42):
Because as hand-waved, your statement is false. id : empty -> empty
is surjective (docs#function.surjective_id), but there is no element of empty
Eric Wieser (Apr 29 2022 at 13:42):
(double dollars $$
for latex in Zulip - please do this instead of using an image)
Ruben Van de Velde (Apr 29 2022 at 13:42):
https://en.wikipedia.org/wiki/Cantor%27s_theorem#Proof ?
Joseph O (Apr 29 2022 at 13:44):
Suppose to the contrary that is surjective. Then there exists such that .
Joseph O (Apr 29 2022 at 13:44):
I suppose this with by_contradiction
Eric Wieser (Apr 29 2022 at 13:45):
That proof has missed the (trivial) step between the .
and the "Then", which lean wants you to spell out
Eric Wieser (Apr 29 2022 at 13:45):
Perhaps rw function.surjective at h
will help you see what's going on?
Ruben Van de Velde (Apr 29 2022 at 13:47):
Joseph O said:
Riccardo Brasca said:
Besides this link, is there a nice guide in sets that would tell me how to represent
Btw, this is not the B from the wikipedia proof
Joseph O (Apr 29 2022 at 13:48):
Oh wait it should have been f(x)
Ruben Van de Velde (Apr 29 2022 at 13:48):
Which is
set B := {x : α | x ∉ f x},
Joseph O (Apr 29 2022 at 13:48):
That makes sense
Joseph O (Apr 29 2022 at 13:50):
Eric Wieser said:
Perhaps
rw function.surjective at h
will help you see what's going on?
It seems like ξ
doesn't nessacerily have to exist
Eric Wieser (Apr 29 2022 at 13:50):
What's your goal state look like after that rewrite?
Joseph O (Apr 29 2022 at 13:51):
α: Type
f: α → set α
B: set α := {x : α | x ∉ f x}
h: ∀ (b : set α), ∃ (a : α), f a = b
⊢ false
Joseph O (Apr 29 2022 at 13:51):
(this is without xi)
Eric Wieser (Apr 29 2022 at 13:51):
Your h
says that for every b
, there exists an a
Eric Wieser (Apr 29 2022 at 13:51):
So if you're following the proof you pasted above, you want to set b = B
, right?
Eric Wieser (Apr 29 2022 at 13:52):
Do you remember how to do that?
Joseph O (Apr 29 2022 at 13:53):
Do I use the have
tactic?
Eric Wieser (Apr 29 2022 at 13:54):
Sure, that's as good a way as any
Eric Wieser (Apr 29 2022 at 13:54):
In fact, if you start with have : ∃ (a : α), f a = B,
, then library_search
will remind you how to prove that (if you don't already know)
Joseph O (Apr 29 2022 at 13:57):
i did this:
set B := {x : α | x ∉ f x},
by_contradiction,
have : ∃ (a : α), f a = B,
{
exact h B,
},
it seemed to work
Joseph O (Apr 29 2022 at 13:59):
for the second goal, the proof statement was
α: Type
f: α → set α
B: set α := {x : α | x ∉ f x}
h: function.surjective f
this: ∃ (ξ : α), f ξ = B
⊢ false
Joseph O (Apr 29 2022 at 14:00):
And in the Wikipedia, the next this is said was
But by construction, .
Joseph O (Apr 29 2022 at 14:00):
(deleted)
Joseph O (Apr 29 2022 at 14:01):
(deleted)
Joseph O (Apr 29 2022 at 14:05):
How can I destruct this
to bring ξ
into scope?
Joseph O (Apr 29 2022 at 14:08):
Or How can I just bring it into scope in general
Damiano Testa (Apr 29 2022 at 14:09):
I think that cases this
will do what you want. Likely, rcases? this
will give you a helpful Try this: ...
that might also be closer that what you really want!
Joseph O (Apr 29 2022 at 14:10):
thanks
Joseph O (Apr 29 2022 at 14:11):
nvm
Joseph O (Apr 29 2022 at 17:36):
What do you think of this proof?
theorem cantor_surjective {α : Type} (f : α → (set α)) :
¬function.surjective f :=
begin
set B := {x : α | x ∉ f x},
by_contradiction,
have : ∃ (ξ : α), f ξ = B,
{ exact h B, },
{ rcases this with ⟨ξ, _⟩,
have : ξ ∈ B ↔ ξ ∉ f(ξ),
{ exact mem_set_of, },
{ rw this_h at this,
exact not_p_iff_not_p _ this, } }
end
is it ok?
Joseph O (Apr 29 2022 at 17:37):
It definitely doesn't compete with mathlib's proof
Arthur Paulino (Apr 29 2022 at 17:50):
If it translates your reasoning well then it's definitely a good achievement. The proofs that go to mathlib are highly golfed and sometimes hard to grasp
Riccardo Brasca (Apr 29 2022 at 17:51):
A nice aspect of formalization is that if Lean says "goals accomplished" then the proof is OK :)
It's never too late to golf a proof, but at the beginning I wouldn't bother too much
Joseph O (Apr 29 2022 at 17:52):
Yeah I am still very new to lean
Joseph O (Apr 29 2022 at 17:58):
can someone explain how this proof works?
theorem mk_le_of_injective {α : Type} {β : Type} {f : α → β}
(hf : function.injective f) :
#α ≤ #β := ⟨⟨f, hf⟩⟩
Riccardo Brasca (Apr 29 2022 at 18:00):
This works because # α ≤ # β
means by definition that there f : α → β
injective.
Joseph O (Apr 29 2022 at 18:00):
oh but what about the nested structures. Frankly I'm confused
Joseph O (Apr 29 2022 at 18:01):
oh its bc of this, right?
image.png
Arthur Paulino (Apr 29 2022 at 18:02):
It's better if you post code so we don't have to lose sight of everything else to see what you're posting
Joseph O (Apr 29 2022 at 18:02):
Well thats just from mathlib
Arthur Paulino (Apr 29 2022 at 18:03):
Still, opening an image grays out everything else on Zulip :(
Riccardo Brasca (Apr 29 2022 at 18:04):
The first ⟨...⟩
takes care of nonempty
. You can go in tactic mode (bewteen begin
and end
) and see what refine ⟨_⟩
does.
Joseph O (Apr 29 2022 at 18:07):
refine ⟨_⟩
makes the goal intof
is injective or smth, but then the last structure.... I'm still so confused
Riccardo Brasca (Apr 29 2022 at 18:08):
Basically, to prove that something is nonempty you can exhibit an element. But if you look at the precise definition of docs#nonempty you see that it is a structure, with only one constructor. This looks complicated, but in practice you have to write the element you've found inside ⟨ ⟩
. You can also write refine nonempty.intro _
.
Riccardo Brasca (Apr 29 2022 at 18:08):
Now the goal is α ↪ β
, so you have to produce an element of this type.
Riccardo Brasca (Apr 29 2022 at 18:10):
If you look at the definition of docs#function.embedding, you see that to produce an embedding you have to produce two things: a function and a proof that this function is injective.
Riccardo Brasca (Apr 29 2022 at 18:10):
⟨_, _⟩
allows you to give these elements once at a time.
Riccardo Brasca (Apr 29 2022 at 18:11):
Try refine ⟨_, _⟩
, you'll have two goals. The first will be a function, and you can close it with exact f
.
Riccardo Brasca (Apr 29 2022 at 18:11):
Then you have to prove that the f
you gave is injective, and this is hf
.
Riccardo Brasca (Apr 29 2022 at 18:12):
⟨⟨f, hf⟩⟩
is just a way to compress all this stuff.
Riccardo Brasca (Apr 29 2022 at 18:13):
But really, mathlib proofs are not easy to read, don't spend too much time on them. You will get there anyway at some point.
Riccardo Brasca (Apr 29 2022 at 18:14):
Especially proofs that are mathematically irrelevant, like this one (there is literally nothing to prove) are highly compressed, using only term mode.
Arthur Paulino (Apr 29 2022 at 18:17):
If your proof is accepted and is not unnecessarily long or slow, then it's fine. We trust on Lean's kernel
Joseph O (Apr 29 2022 at 19:42):
Riccardo Brasca said:
Basically, to prove that something is nonempty you can exhibit an element. But if you look at the precise definition of docs#nonempty you see that it is a structure, with only one constructor. This looks complicated, but in practice you have to write the element you've found inside
⟨ ⟩
. You can also writerefine nonempty.intro _
.
But what are we saying is nonempty
Joseph O (Apr 29 2022 at 19:42):
a or b?
Eric Wieser (Apr 29 2022 at 19:45):
We're saying the type α ↪ β
is nonempty
Joseph O (Apr 29 2022 at 19:46):
And why does it produce a type of function.embedding?
Joseph O (Apr 29 2022 at 19:46):
Where did that come from
Riccardo Brasca (Apr 29 2022 at 20:03):
To prove that α ↪ β
is nonempty you need to find an element of type α ↪ β
.
Riccardo Brasca (Apr 29 2022 at 20:06):
If x : α ↪ β
is such an element, then exact nonempty.intro x
is a proof of nonempty α ↪ β
. This can be shortened to exact ⟨x⟩
, or ⟨x⟩
in term mode.
Riccardo Brasca (Apr 29 2022 at 20:09):
Lean is asking to prove nonempty (α ↪ β)
because this is the definition of #α ≤ #β
.
Riccardo Brasca (Apr 29 2022 at 20:10):
(the literal definition of docs#cardinal.has_le is more complicated because #α
is defined on equivalence classes of types, so one has to check that this definition makes sense)
Riccardo Brasca (Apr 29 2022 at 20:12):
But again, I think you are focusing too much on the Lean code instead of the actual math. What is your definition of #α ≤ #β
(feel free to think that α
and β
are sets, forgetting about type theory)?
Joseph O (Apr 29 2022 at 23:20):
Actually I get it now. Thanks for your help!
Joseph O (Apr 29 2022 at 23:35):
I find that this proof makes the most sense for a beginner
theorem mk_le_of_injective {α β : Type} {f : α → β}
(hf : function.injective f) :
#α ≤ #β :=
begin
refine nonempty.intro _,
refine ⟨_, _⟩,
exact f,
apply hf,
end
Joseph O (Apr 29 2022 at 23:35):
Like me
Kyle Miller (Apr 30 2022 at 00:12):
If you don't want to figure out the names of your constructors (like nonempty.intro
), you can use tactic#fsplit
theorem mk_le_of_injective {α β : Type} {f : α → β}
(hf : function.injective f) :
#α ≤ #β :=
begin
fsplit,
fsplit,
exact f,
exact hf,
end
It creates a new goal for each argument that the constructor needs. (fsplit
is like tactic#split but makes sure that the goals are in a useful order. split
can be backwards.)
Kyle Miller (Apr 30 2022 at 00:14):
Or, if you don't want to prove it since you know it's just a bunch of splits and exacts, there's tactic#tidy, which tries to make progress using some basic tactics.
theorem mk_le_of_injective {α β : Type} {f : α → β}
(hf : function.injective f) :
#α ≤ #β :=
begin
tidy,
end
Joseph O (Apr 30 2022 at 00:16):
Oh wow thanks
Kyle Miller (Apr 30 2022 at 00:16):
Here's a fun one:
theorem mk_le_of_injective {α β : Type} {f : α → β}
(hf : function.injective f) :
#α ≤ #β :=
begin
repeat { fsplit <|> assumption }
end
Kyle Miller (Apr 30 2022 at 00:16):
That means "repeatedly try doing fsplit
or assumption
until one of them fails".
Joseph O (Apr 30 2022 at 00:16):
:astonished:
Joseph O (Apr 30 2022 at 00:17):
will assumption
always work?
Joseph O (Apr 30 2022 at 00:17):
Which do you reccomend to a begginer
Kyle Miller (Apr 30 2022 at 00:17):
It's for doing exact foo
when foo
is one of the hypotheses.
Kyle Miller (Apr 30 2022 at 00:18):
but you don't have to specify the hypothesis.
Kyle Miller (Apr 30 2022 at 00:18):
theorem mk_le_of_injective {α β : Type} {f : α → β}
(hf : function.injective f) :
#α ≤ #β :=
begin
fsplit,
fsplit,
assumption,
assumption,
end
Arthur Paulino (Apr 30 2022 at 00:19):
If you want to know what tidy
did, you can use tidy?
and it will be shown as a (clickable) Try this: ⋯
snippet in the infoview
Kyle Miller (Apr 30 2022 at 00:25):
I don't have a recommendation about assumption
vs exact
. I use both :shrug:
What assumption
essentially does is try doing exact
for each hypothesis one at a time until one succeeds. (To be completely accurate: it looks for a hypothesis where exact
should succeed and does exact
with it.)
Patrick Johnson (Apr 30 2022 at 04:20):
assumption
is better in repeated segments of the proof where parameters may vary (for example ; assumption
or repeat { assumption }
), but I would say that exact
is generally better, because it's faster. Consider the following example where assumption
fails, but exact
works:
example {n : ℕ} (h₁ : n = 0 + 10 ^ 5) (h₂ : n = 10 ^ 5) : n = 10 ^ 5 :=
begin
assumption, -- fails
exact h₂, -- works
end
Kyle Miller (Apr 30 2022 at 16:02):
Huh, even with none
transparency assumption
would fail here.
namespace tactic
/-- `find_same_type t es` tries to find in es an expression with type definitionally equal to t -/
meta def find_same_type' (tr : transparency) : expr → list expr → tactic expr
| e [] := failed
| e (H :: Hs) :=
do t ← infer_type H,
(unify e t tr >> return H) <|> find_same_type' e Hs
meta def find_assumption' (tr : transparency) (e : expr) : tactic expr :=
do ctx ← local_context, find_same_type' tr e ctx
meta def assumption'' : tactic unit :=
do { ctx ← local_context,
t ← target,
H ← find_same_type' transparency.none t ctx,
exact H }
<|> fail "assumption tactic failed"
meta def interactive.assumption'' := tactic.assumption
end tactic
example {n : ℕ} (h₁ : n = 0 + 10 ^ 5) (h₂ : n = 10 ^ 5) : n = 10 ^ 5 :=
begin
assumption'', -- fails
-- deep recursion was detected at 'expression equality test'
end
I wonder if that's a bug in unify
or if this is unavoidable?
Patrick Johnson (Apr 30 2022 at 17:29):
Kyle Miller said:
meta def interactive.assumption'' := tactic.assumption
Do you see it? :)
Kyle Miller (Apr 30 2022 at 17:47):
I better configure myself to use semireducible transparency
Last updated: Dec 20 2023 at 11:08 UTC