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):
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