Zulip Chat Archive

Stream: mathlib4

Topic: Finset sum notation


Kenny Lau (Oct 04 2025 at 19:47):

This might be a less used feature (at least to me), but the summtation (and also product) notations actually support more kinds of syntax:

import Mathlib

variable {s : Finset }

#check  i  s with i + 3 = 5, i * i
-- ∑ i ∈ s with i + 3 = 5, i * i : ℕ

set_option pp.notation false in
#check  i  s with i + 3 = 5, i * i
-- (Finset.filter (fun i => Eq (HAdd.hAdd i 3) 5) s).sum fun i => HMul.hMul i i : Nat

#check  i  s with h : i + 3 = 5, i * i
-- ∑ i ∈ s, if h : i + 3 = 5 then i * i else 0 : ℕ

Are these behaviours good enough? I personally have the following concerns:

  1. with and with h : produce very different results syntactically, the former uses Finset.filter and the latter is dite.
  2. The with h : fails the pretty-printer round-trip (but on the other hand if we just print every sum-dite epxression using with h : then it might also produce some false-positives

Kenny Lau (Oct 04 2025 at 19:49):

cc @Damiano Testa

Ruben Van de Velde (Oct 04 2025 at 19:49):

I think this is @Yaël Dillies's baby

Kenny Lau (Oct 04 2025 at 19:51):

aha, the with h : is #11563 which was merged last month

Kenny Lau (Oct 04 2025 at 19:51):

delab for with is #22048

Bhavik Mehta (Oct 04 2025 at 23:46):

Yeah, the first issue is something I mentioned a few times in #11563, I'd very much like to see that changed.

Bhavik Mehta (Oct 04 2025 at 23:47):

Perhaps that's easy enough to just change though?

Bhavik Mehta (Oct 04 2025 at 23:48):

There's also a bug with the delaborator for with, it doesn't give the correct spacing, I think this is still an issue?

Kenny Lau (Oct 04 2025 at 23:48):

Bhavik Mehta said:

There's also a bug with the delaborator for with, it doesn't give the correct spacing, I think this is still an issue?

I just fixed this in #30194 (merged)

Bhavik Mehta (Oct 04 2025 at 23:48):

Just spotted that too, thanks!!

Kenny Lau (Oct 04 2025 at 23:48):

Bhavik Mehta said:

the first issue

but then one question is also whether that's actually fine, since filter seems preferrable, and then h : is impossible without dite

Bhavik Mehta (Oct 04 2025 at 23:50):

Oh no, I think we should use ite in the first case. As well as being consistent, I think this is actually the more convenient thing to expand to. For instance, when commuting sums, it's usually easier to push everything into an ite and into the inner-most point in a sum

Kenny Lau (Oct 04 2025 at 23:50):

well one issue with ite is the "else 0" that it produces, maybe

Bhavik Mehta (Oct 04 2025 at 23:50):

I don't think that's an issue. In fact I think that's a good thing :)

Kenny Lau (Oct 04 2025 at 23:51):

well if you add two of them you might get 0 + 0

Bhavik Mehta (Oct 04 2025 at 23:52):

Sure, that just means we need to change a lemma's proof slightly, that's not really an issue. Essentially my proposed change is to make docs#Finset.sum_filter use notation on the rhs not lhs. And as I say, I think this is more convenient in practice as a choice.

Yaël Dillies (Oct 05 2025 at 02:57):

The big issue with Bhavik's idea, ie the reason it is taking so long to implement, is that it makes docs#Finset.sum_ite useless as a simp lemma (even locally)

Yaël Dillies (Oct 05 2025 at 03:01):

I still don't know how to solve the problem of splitting up a sum according to a property. Would a simproc checking whether the right side of the ite is zero not loop still?

Yaël Dillies (Oct 05 2025 at 03:02):

The matter is further complicated by the fact that docs#ite_not is a simp lemma, and one can also note that the new with h : notation is unsuited for use in docs#Finset.expect

Yury G. Kudryashov (Oct 05 2025 at 05:22):

Why not use a sum over (s.filter p).attach?

Yury G. Kudryashov (Oct 05 2025 at 05:23):

(I didn't think a lot about this, so probably it's a bad idea for an obvious reason)

Yaël Dillies (Oct 05 2025 at 07:04):

This is precisely what I had originally in #11563 before Bhavik got his way with the if h : ... then ... else ... spelling

Yaël Dillies (Oct 05 2025 at 07:06):

The main issue with the attach spelling is that it is quite weird to obtain the h from it

Bhavik Mehta (Oct 05 2025 at 14:13):

The attach versions are almost always far more annoying than useful, in part because obtaining h is awkward, but also because it leads very easily to DTT hell, particularly when modifying s or p as part of a rewrite sequence (which is a very common operation to do). I think we should have the lemmas saying that the ite sum is equal to the attach sum, but I think it's fairly clear that the ite version is by far the most useful in practice.

Bhavik Mehta (Oct 05 2025 at 14:15):

Yaël Dillies said:

The big issue with Bhavik's idea, ie the reason it is taking so long to implement, is that it makes docs#Finset.sum_ite useless as a simp lemma (even locally)

This isn't a simp lemma already, and throughout mathlib it's only used in simp twice, so I don't think this is a big issue.

Bhavik Mehta (Oct 05 2025 at 14:20):

Yaël Dillies said:

I still don't know how to solve the problem of splitting up a sum according to a property. Would a simproc checking whether the right side of the ite is zero not loop still?

What exactly is "the problem" here? The choice of notation has no impact here, we can rewrite in exactly the same way before or after these changes.

Kenny Lau (Oct 05 2025 at 14:22):

the problem is "loop"ing i think

Kenny Lau (Oct 05 2025 at 14:22):

if you have the wrong lemma to split a sum

Bhavik Mehta (Oct 05 2025 at 14:25):

That's already an issue! Again, the lemma statements aren't changing, we're just having more convenient and consistent notation for it

Kenny Lau (Oct 05 2025 at 14:26):

well we're debating here about the correct simp-NF forms, and that has an impact on what the statements look like

Bhavik Mehta (Oct 05 2025 at 14:28):

Why do you think the simp-NF forms are changing?

Kenny Lau (Oct 05 2025 at 14:29):

actually I would like to retract some of my statements, I don't think "splitting a sum on cases" should be a simp lemma, mainly because there's no way to infer the condition

Kenny Lau (Oct 05 2025 at 14:30):

so I assume we're talking about a statement of the form:

  • sum of f(x) = sum of f(x) for P(x) + sum of f(x) for not P(x)

Kenny Lau (Oct 05 2025 at 14:30):

if our chosen representation for "sum of f(x) for P(x)" changes, then the statement also changes

Kenny Lau (Oct 05 2025 at 14:31):

by representation I mean something like:

  • sum over filter
  • sum over attached
  • sum ite

Yaël Dillies (Oct 05 2025 at 14:39):

Kenny Lau said:

so I assume we're talking about a statement of the form:

  • sum of f(x) = sum of f(x) for P(x) + sum of f(x) for not P(x)

No, that's not what I am talking about. I am instead thinking of the statement ∑ i ∈ s, if p i then f i else g i = ∑ i ∈ s with p i, f i + ∑ i ∈ s with ¬ p i, g i

Kenny Lau (Oct 05 2025 at 14:39):

aha

Kenny Lau (Oct 05 2025 at 14:39):

yeah that also applies, we also need to stop it from looping

Yaël Dillies (Oct 05 2025 at 14:41):

There are two things going on here:

  • Under Bhavik's proposal, this lemma would loop.
  • Under Bhavik's proposal, the simp normal form of ∑ i ∈ s with ¬ p i, g i is ∑ i ∈ s, if p i then 0 else g i, ie simp would remove notation

Bhavik Mehta (Oct 05 2025 at 14:41):

I think this just shouldn't be a simp-lemma! It's already barely used as such: it's not tagged simp currently, and it's used locally as a simp lemma only twice in mathlib.

Yaël Dillies (Oct 05 2025 at 14:42):

I never said that! It's clearly a sort of distributivity lemma. But equally I don't think it should be banned from being used in simp

Bhavik Mehta (Oct 05 2025 at 14:44):

Perhaps, but I think the concern of "this particular lemma makes notation go away if I put it in simp" is quite a bit smaller than the consistency and convenience of the notation here.

Kenny Lau (Oct 05 2025 at 14:45):

well, we can just have without...

Yaël Dillies (Oct 05 2025 at 14:46):

That's actually not such a bad idea!


Last updated: Dec 20 2025 at 21:32 UTC