Zulip Chat Archive

Stream: Is there code for X?

Topic: At least three elements


Joachim Breitner (Feb 21 2022 at 15:34):

What is the most natural way to express an assumption stating “A type X has at least three elements”?
Maybe simply card X > 2 (using the a coercion from nat to cardinal)?
In the proof I’ll need to use this to obtain an element that’s different from two given elements of the type.

I see there are similar lemmas cardinal.two_le_iff. Maybe I should add cardinal.three_le_iff

Johan Commelin (Feb 21 2022 at 15:35):

Is it a finite type?

Joachim Breitner (Feb 21 2022 at 15:35):

No, that would be too restrictive.

Johan Commelin (Feb 21 2022 at 15:35):

There is fintype.card and cardinal.mk. The two are different.

Yaël Dillies (Feb 21 2022 at 15:35):

This same condition came up in our work with Bhavik. I wish there was a very_nontrivial typeclass...

Johan Commelin (Feb 21 2022 at 15:36):

Would cardinal.three_le_iff generalize to exists_finset_card_of_blabla_foo_bar?

Johan Commelin (Feb 21 2022 at 15:37):

Where you somehow want to say that if you know m + n ≤ cardinal.mk X and s : finset X has s.card ≤ m then there is a t : finset X with n ≤ t.card and s.disjoint t?

Johan Commelin (Feb 21 2022 at 15:38):

With may some special casing for n = 1 and n = 2, where you don't get a t : finset X but some hands-on elements

Joachim Breitner (Feb 21 2022 at 15:38):

Looks reasonable, although pragmatically I think I still want the convenient tree_le_iff' lemma :-D

Yaël Dillies (Feb 21 2022 at 15:39):

docs#finset.card_eq_three

Kyle Miller (Feb 21 2022 at 19:27):

This seems somewhat compelling:

def card_ge (α : Type*) (n : ) : Prop :=  (s : finset α), s.card = n

especially given the lemma Yael mentioned.

Yaël Dillies (Feb 21 2022 at 19:27):

I was thinking the same, but as a class.

Kyle Miller (Feb 21 2022 at 19:29):

A reason I like this is that it's very "local": you don't need there to be any sort of object that's the cardinality of the whole type, you just need to present a finite set with a certain number of elements.

Kyle Miller (Feb 21 2022 at 19:30):

That seems like a reasonable class to have. Any reason not to have it be a class?

Yaël Dillies (Feb 21 2022 at 19:31):

Maybe it could be stated with cardinals.

Johan Commelin (Feb 21 2022 at 19:32):

I think 98% of the use cases will be for natural numbers

Johan Commelin (Feb 21 2022 at 19:32):

Should this then replace nontrivial?

Yaël Dillies (Feb 21 2022 at 19:33):

And nonempty? That sounds like a bootstrapping problem.

Kyle Miller (Feb 21 2022 at 19:44):

I'm not sure there are any theoretical problem to nonempty being in terms of card_ge, but that seems like more trouble than it's worth (the definitions of multiset and finset would have to find their way to core...)

It looks like nontrivial isn't that deep, so it seems replaceable (it could be an abbreviation)

Reid Barton (Feb 21 2022 at 19:45):

A class?? :scream_cat: Can someone who understands explain this to me?

Adam Topaz (Feb 21 2022 at 19:47):

nonempty (fin 3 ↪ α)

Kyle Miller (Feb 21 2022 at 19:49):

@Reid Barton Just some overengineering for the handful of cases that should probably ever appear: [card_ge α 1], [card_ge α 2], [card_ge α 3]. (Assuming the pre-existing cardinality classes should be unified.)

Adam Topaz (Feb 21 2022 at 19:52):

E.g.

import data.matrix.notation
import tactic

lemma foobar {α : Type*} (a b c : α)
  (h1 : a  b) (h2 : a  c) (h3 : b  c) : nonempty (fin 3  α) :=
⟨⟨![a,b,c], by { intros i j, fin_cases i; fin_cases j, tidy }⟩⟩

Adam Topaz (Feb 21 2022 at 20:03):

This has the benefit of being easily generalizable (to a point... the automation gets pretty slow)

import data.matrix.notation
import tactic

instance foobar {α : Type*} (a b c d : α) :
  a  b  a  c  a  d 
  b  c  b  d 
  c  d 
  nonempty (fin 4  α) := λ h1 h2 h3 h4 h5 h6,
⟨⟨![a,b,c,d], by { intros i j, fin_cases i; fin_cases j, tidy }⟩⟩

Reid Barton (Feb 21 2022 at 20:05):

@Kyle Miller I mean why not just make it a Prop. Wouldn't it make everyone happier?

Reid Barton (Feb 21 2022 at 20:05):

i.e., not a class

Mario Carneiro (Feb 21 2022 at 20:05):

I think the best way is to use list.nodup [a, b, c], which definitionally unfolds to something pretty close to what you want

Mario Carneiro (Feb 21 2022 at 20:06):

It's not too hard to massage an assumption like fintype.card X >= 3 into that


Last updated: Dec 20 2023 at 11:08 UTC