New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Card lemmas #509
Card lemmas #509
Conversation
@@ -624,13 +624,17 @@ Proof. | |||
by apply: (iffP idP) => [/eqP/mem_card1[x inA]|[x /eq_card1/eqP//]]; exists x. | |||
Qed. | |||
|
|||
Lemma fintype_le1P : reflect (forall x, all_equal_to x) (#|T| <= 1). | |||
Lemma card_le1_eqP A : |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In thought I did that one when I added fintype_le1P
tomorrow. 😆 I will double check tomorrow, if I forgot to push something.
mathcomp/ssreflect/finset.v
Outdated
@@ -824,6 +824,16 @@ rewrite eq_sym eqn_leq card_gt0 => /andP[/set0Pn[x Ax] leA1]. | |||
by exists x; apply/eqP; rewrite eq_sym eqEcard sub1set Ax cards1 leA1. | |||
Qed. | |||
|
|||
Lemma cards2P A : reflect (exists x y : T, x != y /\ A = [set x;y]) (#|A| == 2). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice one to have indeed, I think there is a lot of refactoring to do with all the card_*
lemma you added, through enum
(which is uniq
which size is the cardinal of the considered set). Indeed, I think card_eqP
would be almost a one liner and card_geqP
, and cards2P
is a simple twice case analysis (the main step being something like case: (enum A) (enum_uniq A) (size_enum A) => [|x [|y []]//; exists x; exists y
).
I also think it would be nice to have le/lt variants and pred
variants.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow. There is no card_eqP
(yet) and indeed I'm not sure that would be useful, since enum A
has already good lemma support. And card_geqP
is about encapsulating the picking of a subsequence of enum A
, if one only has a lower bound.
Admittedly, using the _gt?P
lemmas to prove cards2P
may be overkill.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is an elaboration of what I had in mind:
Lemma set_enum A : [set x | x \in enum A] = A.
Proof. by apply/setP => x; rewrite inE mem_enum. Qed.
Variant cards_eq_spec A : seq T -> {set T} -> nat -> Type :=
| CardEq (s : seq T) & uniq s : cards_eq_spec A s [set x | x \in s] (size s).
Lemma cards_eqP A : cards_eq_spec A (enum A) A #|A|.
Proof.
by move: (enum A) (cardE A) (set_enum A) (enum_uniq A) => s -> <-; constructor.
Qed.
Lemma cards1P A : reflect (exists x, A = [set x]) (#|A| == 1).
Proof.
apply: (iffP idP) => [|[x ->]]; last by rewrite cards1.
by have [[|x []]// _] := cards_eqP; exists x; apply/setP => y; rewrite !inE.
Qed.
Lemma cards2P A : reflect (exists x y : T, x != y /\ A = [set x; y]) (#|A| == 2).
Proof.
apply: (iffP idP) => [|[x] [y] [xy ->]]; last by rewrite cards2 xy.
have [[|x [|y []]]//=] := cards_eqP; rewrite !inE andbT => neq_xy.
by exists x, y; split=> //; apply/setP => z; rewrite !inE.
Qed.
and something like this for fintype...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And
card_geqP
is about encapsulating the picking of a subsequence ofenum A
, if one only has a lower bound.
Indeed, I missed that...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, for {set _}
what you propose is indeed more general and more direct than what I had proposed. However, I'm not sure it transfers all that well to predicates: due to the lack of extensionality, one cannot pull the [set x | x \in enum A]
trick. One could instead generate s =i A
as an assumption, but I'm not sure this view would be all that useful.
The same goes for lower bounds, albeit for a different reason: there one doesn't even want to replace the original predicate/set.
I tried to incorporate the feedback from @CohenCyril , and I found two more lemmas |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, except for minor proof style or spacing issues.
I made many code suggestions to point them out with a suggest fix, which I did not test
I wasn't sure about this, because the line already had 82 characters, now it gained another 6. And yes, I want a linter, too. 😄 |
Oh ok, I should really checkout locally. |
Well, running a |
It used to be, this is outrageous 😉 |
Co-authored-by: Cyril Cohen <CohenCyril@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeay, LGTM now!
Motivation for this change
Additional lemmas about cardinalities of predicates and sets. Mainly picking
n
distinct elements for an a predicate withn <= #|A|
.Things done/to do
CHANGELOG_UNRELEASED.md
added corresponding documentation in the headersAutomatic note to reviewers
Read this Checklist and make sure there is a milestone.