Zulip Chat Archive

Stream: Is there code for X?

Topic: Lemmas about nat / list / finset


Patrick Johnson (May 18 2022 at 04:47):

Here are some statements that I proved as helper lemmas in some of my other projects. Please let me know which lemmas of them (if any) I should PR to mathlib. Note that some of them trivially follow from what is already in mathlib, but are useful for rewriting.

Statements

Eric Wieser (May 18 2022 at 07:09):

Have you library_search'd all of them to no avail?

Kyle Miller (May 18 2022 at 07:40):

I think it would be helpful to take small chunks of thematically related lemmas (say 5-ish) and repost them to help focus discussion -- you have a lot of lemmas to take in all at once! (Having thematic chunks for PRs would be helpful for review too.)

Kyle Miller (May 18 2022 at 07:43):

The set.finite -> fintype definition is docs#set.finite.fintype

noncomputable def fintype_subtype_of_set_finite {α : Type*} {P : α  Prop}
  (h : {x : α | P x}.finite) : fintype {x : α // P x} := h.fintype

Kyle Miller (May 18 2022 at 07:48):

For the set.finite lemmas, they should generally be made by defining some fintype instances (or just definitions) and then making use of them. For example, once #14136 is merged,

instance {d : } : fintype {a :  | |a|  d} := sorry

lemma abs_le_finite {d : } : {a :  | |a|  d}.finite := set.finite_of_fintype _

(And at this point, you probably don't need the lemma since {a : ℤ | |a| ≤ d}.finite_of_fintype would likely suffice.)

Floris van Doorn (May 18 2022 at 07:51):

I see a couple things already in mathlib: docs#function.iterate_add_apply and docs#list.take_append_drop

Patrick Johnson (May 18 2022 at 08:15):

Ok, removed statements for which library_search found a result. Also, removed set.finite lemmas (I will refactor them later).
I'll try to make PRs as small as possible, yes.

nat

list

finset

set

function

Patrick Johnson (May 18 2022 at 08:18):

Floris van Doorn said:

I see a couple things already in mathlib: docs#function.iterate_add_apply and docs#list.take_append_drop

I know about function.iterate_add_apply, but my version has flipped addition operands. I often find myself using rw add_comm before rw function.iterate_add_apply, so maybe we should have the other version too for rewriting?

Eric Wieser (May 18 2022 at 08:26):

nat.exists_mul looks kind of silly; what's the point in having an existential of the form ∃ (a b : ℕ), f x = a ∧ g y = b ∧ p a b vs the lemma just being p (f x) (g y)?

Mario Carneiro (May 18 2022 at 14:08):

list.length_dedup_le is covered by dedup_sublist and sublist_length_le

Mario Carneiro (May 18 2022 at 14:10):

same for list.length_dedup_append_le - I would want that to be presented as (l1 ++ l2).dedup <+ l1.dedup ++ l2.dedup

Mario Carneiro (May 18 2022 at 14:12):

list.length_dedup_append_le should be (x :: l).dedup.length = l.dedup.length or possibly (x :: l).dedup = l.dedup if the order of dedup works out

Mario Carneiro (May 18 2022 at 14:12):

list.length_dedup_lt_of_dup is an iff

Mario Carneiro (May 18 2022 at 14:16):

list.length_dedup_lt_of_dup looks too specific to be a general purpose lemma, unless that sum was a definition

Mario Carneiro (May 18 2022 at 14:17):

list.length_dedup_lt_of_dup can be stated without the sum

Mario Carneiro (May 18 2022 at 14:19):

list.sum_union_eq_sum is more flexible if the lhs uses s instead of l.to_finset ∪ s with an assumption that l \sub s. Also the rhs is l.length given the previous lemma

Mario Carneiro (May 18 2022 at 14:21):

another way to get to list.length_le_length_of_count_le_count is to map the two lists to multisets, since the hypothesis is saying that multiset.mk l1 <= multiset.mk l2 and this implies the length fact

Mario Carneiro (May 18 2022 at 14:23):

list.count_map_eq_length_filter should be stated in terms of countp. In fact this theorem generalizes to countp on both sides, which would be list.countp_map

Mario Carneiro (May 18 2022 at 14:25):

list.diff_map_subset should be upgraded to sublist if true (not 100% sure)

Mario Carneiro (May 18 2022 at 14:27):

list.length_lt_length_snoc₂ seems unnecessary, it's just two applications of the previous lemma

Mario Carneiro (May 18 2022 at 14:28):

finset.card_insert_erase_eq is just theorems about insert and erase stuck together + pred_succ

Mario Carneiro (May 18 2022 at 14:30):

set.exists_infinite_of_forall_exi: I'm pretty sure there is a way to write those hypotheses as just infinite α

Mario Carneiro (May 18 2022 at 14:32):

it might also be better to generalize β to a finset

Mario Carneiro (May 18 2022 at 14:35):

set.exists_infinite_of_forall_exists_nat is just the specialization of the previous lemma, it does not seem necessary

Mario Carneiro (May 18 2022 at 14:43):

function.iterate_mul_eq_of_eq and function.iterate_add_mul_eq_of_add_eq seem to be encouraging the wrong kind of buildup of the expression. I would instead say that f^[d * m] = (f^[d])^[m], and if f x = x then f^[n] x = x. For function.iterate_add_mul_eq_of_add_eq you can rewrite (f^[n + d]) x to (f^[d]) ((f^[n]) x) and then it's just the same as the other one

Mario Carneiro (May 18 2022 at 14:44):

nat.exists_ge_of_set_inf is an iff (with the n quantifier in the right place)

Patrick Johnson (May 25 2022 at 00:06):

Sorry for the late response. I was busy last week.

list.length_dedup_append_le should be (x :: l).dedup.length = l.dedup.length or possibly (x :: l).dedup = l.dedup if the order of dedup works out

I guess you mean length_dedup_cons_le_of_mem instead? I think it can also be stated as dedup_cons_eq_self_iff_mem, because it's an iff.

list.length_dedup_lt_of_dup is an iff

Then length_dedup_lt_of_dup is just list.dedup_eq_self, so I guess it's redundant.

list.length_dedup_lt_of_dup looks too specific to be a general purpose lemma, unless that sum was a definition
list.length_dedup_lt_of_dup can be stated without the sum

Copy-paste artifact? Which lemmas are you referring to?

nat.exists_mul looks kind of silly; what's the point in having an existential of the form ∃ (a b : ℕ), f x = a ∧ g y = b ∧ p a b vs the lemma just being p (f x) (g y)?

I personally find it handy for rewriting, because I often use generalize after obtain ... := nat.div_add_mod _ so that the proof state looks cleaner. But I understand it's probably not suitable for mathlib.

Patrick Johnson (May 25 2022 at 00:06):

I will open one PR at a time. Here is the PR for list.nodup_iff: #14371


Last updated: Dec 20 2023 at 11:08 UTC