feat(data/[fin]set): add some more basic properties of (finite) sets#905
feat(data/[fin]set): add some more basic properties of (finite) sets#905fpvandoorn wants to merge 1 commit intoleanprover-community:masterfrom
Conversation
| @[simp] lemma coe_sdiff (s₁ s₂ : finset α) : ↑(s₁ \ s₂) = (↑s₁ \ ↑s₂ : set α) := | ||
| set.ext $ λ _, mem_sdiff | ||
|
|
||
| lemma to_set_sdiff (s t : finset α) : (s \ t).to_set = s.to_set \ t.to_set := |
There was a problem hiding this comment.
About finset-simp lemmas: I don't see a simp lemma rewriting s.to_set to (↑s : set _) or the other way around, so I'm not sure what the "canonical form" of this function is. If it's ↑s, then this simp lemma is superfluous (I don't know if that is a problem at all).
There was a problem hiding this comment.
@digama0 Is there a general mathlib preference here?
There was a problem hiding this comment.
I've never heard of s.to_set before this (and I wrote it). It's definitely written ↑s everywhere.
| lemma compl_empty_iff {s : set α} : -s = ∅ ↔ s = univ := | ||
| by { split, intro h, rw [←compl_compl s, h, compl_empty], intro h, rw [h, compl_univ] } | ||
|
|
||
| lemma compl_univ_iff {s : set α} : -s = ∅ ↔ s = univ := |
There was a problem hiding this comment.
This one is identical to the previous one. Which is not what you intended... I guess
There was a problem hiding this comment.
He probably meant -s = empty iff s = univ. I think both of these should be @[simp]
There was a problem hiding this comment.
The name suggests: -s = univ ↔ s = ∅
There was a problem hiding this comment.
oops, copy-paste without actually changing the statement. Yes, Johannes wrote the statement I had in mind.
| lemma compl_univ_iff {s : set α} : -s = ∅ ↔ s = univ := | ||
| by { split, intro h, rw [←compl_compl s, h, compl_empty], intro h, rw [h, compl_univ] } | ||
|
|
||
| lemma nonempty_compl {s : set α} : s ≠ univ ↔ nonempty (-s : set α) := |
There was a problem hiding this comment.
Given the name, I would expect the sides of the iff to be swapped.
| set.range (@subtype.val _ p) = {x | p x} := | ||
| by rw ← set.image_univ; simp [-set.image_univ, val_image] | ||
|
|
||
| lemma range_val (s : set α) : range (subtype.val : s → α) = s := |
avigad
left a comment
There was a problem hiding this comment.
The PR looks good, but I'd like a bit of discussion on the nonempty question, because it will come up a lot in proofs.
|
|
||
| @[simp] lemma coe_empty : ↑(∅ : finset α) = (∅ : set α) := rfl | ||
|
|
||
| lemma coe_nonempty_iff_ne_empty (s : finset α) : nonempty (↑s : set α) ↔ s ≠ ∅ := |
There was a problem hiding this comment.
Here is a general question: should the library favor nonempty (↑s : set α) or s ≠ ∅? The library should be consistent about using one or the other to state theorems. The second seems more natural and useful to me. If we go with that, then this should be a simplifier rule. If we go the other way, we should probably simplify the second to the first.
Either way, this lemma should be named nonempty_iff_ne_empty or nonempty_coe_iff_ne_empty. With the current name, it will be very hard to find using tab completion.
@ChrisHughes24 @jcommelin @johoelzl I am curious to hear your thoughts on this.
There was a problem hiding this comment.
I think the second looks nicer. Otoh, nonempty is a class, which might allow the type class system to take care of some proof obligations.
There was a problem hiding this comment.
The second looks more natural, but is less useful in practice. I noticed that in my proofs I preferred the nonempty, because I can immediately extract an element from that with cases. But I'm ok with using s ≠ ∅ as default since that is mathematically more accepted.
I used this name to be consistent with set.coe_nonempty_iff_ne_empty in set.basic. I would personally also name it nonempty_iff_ne_empty.
There was a problem hiding this comment.
The ability to uses cases with nonempty is compelling to me, so I am happy to make that the canonical idiom if nobody objects. In that case, we should try (at least over time) to state theorems that way, and also in set.
But I really do think it is better to have the name start with nonempty, also for the one in set.
There was a problem hiding this comment.
The general mathlib preference is for the s ≠ ∅ idiom, although I can see the advantage of an inductive predicate so that you can use cases directly. It's still not that much better since you have to case twice; the additional coercion in the middle makes it less desirable since that makes it internally more complicated. I agree that we should use ne_empty and nonempty consistently to mean s ≠ ∅ and nonempty s respectively, though.
There was a problem hiding this comment.
Also, I think nonempty s reads quite naturally. I can't imagine many mathematicians stumbling over that... (-;
|
|
||
| @[simp] lemma diff_self {s : set α} : s \ s = ∅ := ext $ by simp | ||
|
|
||
| lemma mem_diff_singleton_empty {s : set α} {t : set (set α)} : |
There was a problem hiding this comment.
Do we really need this? This is essentially just a combination of mem_diff and mem_singleton_iff.
There was a problem hiding this comment.
I don't know. I definitely wanted it for my specific use-case, since I needed it multiple (10?) times. But maybe mathlib is not the place for "combined" facts like this. I will remove it.
There was a problem hiding this comment.
If you needed it 10 times, I think it's legit to keep it. In my eyes >80% of formalisation libraries consist of little lemmas that are "essentially just a combination"... (not being sarcastic).
There was a problem hiding this comment.
I would suggest generalizing to s \in t \ {a} <-> s \in t /\ s != a, assuming the situation with ne_zero vs nonempty is resolved.
| lemma finite.coe_to_finset {α} {s : set α} (h : finite s) : ↑h.to_finset = s := | ||
| by { ext, apply mem_to_finset } | ||
|
|
||
| lemma exists_finset_of_finite {s : set α} (h : finite s) : ∃(s' : finset α), s'.to_set = s := |
There was a problem hiding this comment.
this should use coercion instead of to_set
| λ x xs y ys h, H _ _ (hp x xs y ys h) | ||
|
|
||
| /- Disjoint sets and pairwise disjoint collections of sets -/ | ||
| lemma disjoint_of_subset {s t s' t' : set α} (hst : s ∩ t = ∅) (hs : s' ⊆ s) (ht : t' ⊆ t) : |
There was a problem hiding this comment.
There is already a definition of disjoint (and pairwise disjoint) in data.set.lattice, which is preferred over this one. Could you move / merge these lemmas?
|
Superseded by #948 |
Part 2: (fin)sets
TO CONTRIBUTORS:
Make sure you have:
If this PR is related to a discussion on Zulip, please include a link in the discussion.
For reviewers: code review check list