Skip to content
This repository has been archived by the owner on Jul 24, 2024. It is now read-only.

[Merged by Bors] - refactor(data/set/finite): reorganize and put emphasis on fintype instances #14136

Closed
wants to merge 35 commits into from

Conversation

kmill
Copy link
Collaborator

@kmill kmill commented May 14, 2022

I went through data/set/finite and reorganized it by rough topic (and moved some lemmas to their proper homes; closes #11177). Two important parts of this module are (1) fintype instances for various set constructions and (2) ways to create set.finite terms. This change puts the module closer to following a design where the set.finite terms are created in a formulaic way from the fintype instances. One tool for this is a set.finite_of_fintype constructor, which lets typeclass inference do most of the work.

Included in this commit is changing set.infinite to be protected so that it does not conflict with infinite.


Open in Gitpod

@kmill kmill added the awaiting-author A reviewer has asked the author a question or requested changes label May 14, 2022
@kmill kmill added awaiting-review The author would like community review of the PR and removed awaiting-author A reviewer has asked the author a question or requested changes labels May 14, 2022
have h2 : ∀ l : {l : L // p ∈ l}, fintype.card {q // q ∈ l.1 ∧ q ≠ p} = order P L,
{ intro l,
rw [←fintype.card_congr (equiv.subtype_subtype_equiv_subtype_inter _ _),
fintype.card_subtype_compl, ←nat.card_eq_fintype_card],
any_goals { apply_instance },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly what happened here?

Copy link
Collaborator Author

@kmill kmill May 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is because I changed card_subtype_compl from

lemma fintype.card_subtype_compl [fintype α] {p : α → Prop} [decidable_pred p] :
  fintype.card {x // ¬ p x} = fintype.card α - fintype.card {x // p x} :=

to

lemma fintype.card_subtype_compl [fintype α]
  (p : α → Prop) [fintype {x // p x}] [fintype {x // ¬ p x}] :
  fintype.card {x // ¬ p x} = fintype.card α - fintype.card {x // p x} 

and the rewrite is somehow not able to find the third fintype instance. If you give it the predicate directly, then it works fine. In the commit I pushed, I modified it to give the predicate directly.

I'm not sure what the best thing to do here is, and I don't really understand what's causing the instance lookup failure... (Maybe it's ne vs not-equals in whatever p it infers?)

src/data/set/basic.lean Outdated Show resolved Hide resolved
Copy link
Collaborator

@b-mehta b-mehta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take it on trust that the lemmas in data/set/finite have moved and none have been lost, otherwise LGTM!

src/data/fintype/basic.lean Outdated Show resolved Hide resolved
Co-authored-by: Bhavik Mehta <[email protected]>
@kmill
Copy link
Collaborator Author

kmill commented May 22, 2022

@b-mehta Methodologically, I did copy/paste to put things into order, so nothing should be lost (and thankfully I haven't had to do a complicated merge so far). There's also a metaproof that nothing has gone missing: mathlib still compiles, and nobody adds anything to data/set/finite unless it's for something else!

@kmill
Copy link
Collaborator Author

kmill commented May 22, 2022

I had been planning on making set.finite protected, but I guess that can't be done for inductive definitions. It seems like having set.infinite be protected is better than not (since Lean can't disambiguate between infinite and set.infinite on its own), but it's unfortunate that there's this inconsistency between set.finite and set.infinite.

src/data/fintype/basic.lean Outdated Show resolved Hide resolved
[fintype s] [fintype t] : (s ∩ t).to_finset = s.to_finset ∩ t.to_finset :=
by { ext, simp }

lemma to_finset_union {α : Type*} [decidable_eq α] (s t : set α) [fintype (s ∪ t : set α)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reason for some of these to be simp and not others?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure, this is how they were, and I didn't want to see if mathlib would compile with them as simp lemmas.

exact m }
end
end
/-- A `fintype` structure on `insert a s` when inserting a new element. -/
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we reference fintype_insert in this docstring (and the next), and also vice-versa?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do that in a followup PR

fintype.card_of_subsingleton _
/-- Normally, `insert a s` for `finset` requires `[decidable_eq α]`, but we can use this weaker
assumption here. -/
instance fintype_insert' (a : α) (s : set α) [decidable $ a ∈ s] [fintype s] :
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having this instance as well as the previous seems a bit odd to me, but can we reference the other?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from the original fintype_insert, which derives decidable membership from decidable equality and chooses one of the two fintype instances based on that decision. The new fintype_insert just uses the finset insert, which makes it more like instances for other set operations -- having looked at the history, it looks like the reason for this is that the original set.finite was a custom inductive type that made no use of finset. I let the original fintype_insert hang around in this form since it might still be useful.

classical,
rw [fintype.card_of_subtype (set.to_finset pᶜ), set.to_finset_compl p, finset.card_compl,
fintype.card_of_subtype (set.to_finset p)];
intros; simp; refl
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we missing a simp lemma?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is code that had previously been through review, but I went ahead and fixed the non-terminal simp.

What's going on is that this proof is that p is not a set but the rewrites are using it as if it were one. In a quick test, set_of p doesn't fix it.

inductive finite (s : set α) : Prop
| intro : fintype s → finite

lemma finite_def {s : set α} : finite s ↔ nonempty (fintype s) := ⟨λ ⟨h⟩, ⟨h⟩, λ ⟨h⟩, ⟨h⟩⟩
/-- Constructor for `set.finite` with the `fintype` as an instance argument. -/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make intro be this with something like

inductive finite (s : set α) : Prop
| of_fintype [fintype s] : finite

Or is that annoying?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd found writing finite_def awkward that way, so I figured I'd leave it as Yury wrote it.

@jcommelin
Copy link
Member

Thanks 🎉

bors merge

@github-actions github-actions bot added ready-to-merge All that is left is for bors to build and merge this PR. (Remember you need to say `bors r+`.) and removed awaiting-review The author would like community review of the PR labels May 23, 2022
bors bot pushed a commit that referenced this pull request May 23, 2022
…tances (#14136)

I went through `data/set/finite` and reorganized it by rough topic (and moved some lemmas to their proper homes; closes #11177). Two important parts of this module are (1) `fintype` instances for various set constructions and (2) ways to create `set.finite` terms. This change puts the module closer to following a design where the `set.finite` terms are created in a formulaic way from the `fintype` instances. One tool for this is a `set.finite_of_fintype` constructor, which lets typeclass inference do most of the work.

Included in this commit is changing `set.infinite` to be protected so that it does not conflict with `infinite`.
@bors
Copy link

bors bot commented May 23, 2022

Pull request successfully merged into master.

Build succeeded:

@bors bors bot changed the title refactor(data/set/finite): reorganize and put emphasis on fintype instances [Merged by Bors] - refactor(data/set/finite): reorganize and put emphasis on fintype instances May 23, 2022
@bors bors bot closed this May 23, 2022
@bors bors bot deleted the kmill_set_finite branch May 23, 2022 14:09
kmill added a commit that referenced this pull request May 24, 2022
bors bot pushed a commit that referenced this pull request May 25, 2022
bors bot pushed a commit that referenced this pull request May 31, 2022
…4468)

This lemma was added in #11371 for the Lean version bump, since the more powerful congr lemmas revealed a bug in fintype instances that were finally corrected in #14136.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ready-to-merge All that is left is for bors to build and merge this PR. (Remember you need to say `bors r+`.)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

set.to_finset_* lemmas
5 participants