Zulip Chat Archive

Stream: Is there code for X?

Topic: Sum over characteristic function


Michael Stoll (Sep 11 2022 at 19:59):

How can I prove a statement like the following without having to contort myself too much?

example (n : ) :  (j : fin n.succ), ite (j = 0) 0 1 = n :=
begin
  change  (j : fin n.succ), id (ite (j = 0) 0 1) = n,
  rw [finset.sum_apply_ite],
  simp [finset.filter_ne'],
end

By "contort", I mean introducing the explicit identity function in the first step, which appears to be necessary for the rewrite.

Damiano Testa (Sep 11 2022 at 20:04):

Would using something like refine (finset.sum_ite_apply _ _).trans _ work?

You may need to give some arguments to finset..., or a different number of underscores... (I'm on mobile)

Damiano Testa (Sep 11 2022 at 20:07):

The point being that refine would match via defeq, while rewrite via syntactic equivalence. If you manage to apply/refine the right shape, you can get away with looser matching.

Michael Stoll (Sep 11 2022 at 20:08):

refine (finset.sum_apply_ite 0 1 id).trans _, can indeed replace the first two lines of the proof.
Whether one considers it to be less of a contortion, is perhaps a matter of taste :smile:

Michael Stoll (Sep 11 2022 at 20:08):

(And without specifying id, it does not work, so the problem persists.)

Damiano Testa (Sep 11 2022 at 20:10):

You probably can also replace the underscore with (by simp [...]), remove begin, end and refine, make it a one-liner and be happy with it! :upside_down:

Damiano Testa (Sep 11 2022 at 20:11):

Also, replacing the rw by the refine will probably create a shorter proof term.

Michael Stoll (Sep 11 2022 at 20:16):

In my application, I actually have ... < n + 1 instead of ... = n, so that .trans does not work.

Damiano Testa (Sep 11 2022 at 20:22):

Would (...).le.trans_lt work instead? This is getting worse and worse, I realize...

Damiano Testa (Sep 11 2022 at 20:23):

I'm probably convincing you that the show ... id ... was not so bad, after all, given how the proof could have looked.

Damiano Testa (Sep 11 2022 at 20:27):

At some point, a calc proof would be better. One advantage of calc is that it allows you to lock in the proper defeq you are aiming for and then you can simply provide the correct lemma to fill it in.

Michael Stoll (Sep 11 2022 at 20:27):

OK, I have found a simpler version of docs#finset.sum_apply_ite that works directly (docs#finset.sum_ite).

Michael Stoll (Sep 11 2022 at 20:28):

Which solves the problem (and tells me I should go to bed...).

Michael Stoll (Sep 11 2022 at 20:34):

Right now, I'm stuck on the trivial-looking example (n : ℕ) : 1 - n = 1 → n = 0...
What I have is

example (n : ) (h : 1 - n = 1) : n = 0 :=
begin
  rcases @eq_zero_or_pos _ _ n with (rfl | hp),
  { refl, },
  { rw [nat.sub_eq_zero_of_le (nat.one_le_of_lt hp)] at h,
    exfalso, exact zero_ne_one h, }
end

which looks unnecessarily complicated.

Damiano Testa (Sep 11 2022 at 20:37):

Does docs#nat.lt_of_sub_eq_succ help?

Damiano Testa (Sep 11 2022 at 20:38):

(beginning with a lemma that converts the = 0 to < 1?)

Damiano Testa (Sep 11 2022 at 20:39):

docs#nat.lt_one_iff

Michael Stoll (Sep 11 2022 at 20:42):

:= nat.lt_one_iff.mp (nat.lt_of_sub_eq_succ h). Thanks.

Michael Stoll (Sep 11 2022 at 20:42):

I just tend not to think of succ when looking for lemmas....

Damiano Testa (Sep 11 2022 at 20:44):

I find navigating nat lemmas very tricky.

Damiano Testa (Sep 11 2022 at 20:46):

One guiding principle that I find useful, is that strict inequality is much stronger than , due to truncated subtraction. So, if I can, I try to get < to do most of the work.

Kevin Buzzard (Sep 11 2022 at 20:47):

lemma nat.sub_eq_self (a b : ) : a - b = a  a = 0  b = 0 := ...

would be a nice addition to mathlib.

Damiano Testa (Sep 11 2022 at 20:48):

Indeed, I found the lemma above hoping that nat.sub_eq_ would autocomplete to self!

Kevin Buzzard (Sep 11 2022 at 20:48):

import tactic

lemma nat.sub_eq_self (a b : ) : a - b = a  a = 0  b = 0 := by omega

Kevin Buzzard (Sep 11 2022 at 20:48):

omega is a really cool tactic for all this stuff, it's such a shame that it's banned

Eric Rodriguez (Sep 11 2022 at 20:49):

does docs#finset.sum_ite not work?

Yakov Pechersky (Sep 11 2022 at 20:50):

import algebra.big_operators.basic
open_locale big_operators

example (n : ) :  (j : fin n.succ), ite (j = 0) 0 1 = n :=
by simp [finset.sum_ite, finset.filter_ne']

Yakov Pechersky (Sep 11 2022 at 20:51):

n here is a red herring:

example {α : Type*} [decidable_eq α] (x : α) (s : finset α) (hx : x  s) :
   j in s, ite (j = x) 0 1 = s.card - 1 :=
by { simp [finset.sum_ite, finset.filter_ne', hx] }

Michael Stoll (Sep 11 2022 at 20:54):

Eric Rodriguez said:

does docs#finset.sum_ite not work?

See above.

Eric Rodriguez (Sep 11 2022 at 20:54):

seems I need some rest too :)

Yakov Pechersky (Sep 11 2022 at 20:58):

example (n : ) (h : 1 - n = 1) : n = 0 :=
by cases n; simp [*] at *

Yaël Dillies (Sep 11 2022 at 21:54):

You should use docs#finset.sum_boole

Michael Stoll (Sep 12 2022 at 10:06):

True, but one has to find it first...

Michael Stoll (Sep 12 2022 at 15:09):

...and the name does not exactly help here. The statement does not involve booleans. Something involving ite and perhaps zero and one would be much more helpful in finding it.

Yaël Dillies (Sep 12 2022 at 15:11):

Agreed, but I could not come up with a better name.

Yakov Pechersky (Sep 12 2022 at 16:12):

indicator or single maybe? fun i, ite (i = x) 1 0 = fun i, ite (i != x) 0 1 = pi.single x 1

Andrew Yang (Sep 12 2022 at 16:17):

By the way, why does it require a non_assoc_semiring? Is add_monoid not enough?

Damiano Testa (Sep 12 2022 at 16:36):

I guess it is the presence of 0 and 1.

Eric Rodriguez (Sep 12 2022 at 16:41):

add_monoid_with_one is probably enough, now that that exists

Kevin Buzzard (Sep 12 2022 at 23:10):

You should also have its multiplicative counterpart, monoid_with_e


Last updated: Dec 20 2023 at 11:08 UTC