Zulip Chat Archive

Stream: mathlib4

Topic: simp can prove it


Reid Barton (Jan 01 2023 at 19:10):

Did the "simp can prove it" linter not exist in mathlib 3?

Eric Wieser (Jan 01 2023 at 19:12):

It existed in a weaker form in mathlib3 for things tagged @[simp]

Eric Wieser (Jan 01 2023 at 19:12):

"simp can prove it" isn't a sufficient condition to make a simp lemma unecessary

Reid Barton (Jan 01 2023 at 19:14):

Then why is there a linter for that in mathlib4?

Eric Wieser (Jan 01 2023 at 19:14):

Maybe simp is clever enough that it now is sufficient?

Eric Wieser (Jan 01 2023 at 19:15):

The case I had in mind is docs#submodule.coe_zero vs docs#submodule.coe_eq_zero

Eric Wieser (Jan 01 2023 at 19:16):

Simp can obviously prove the former with the latter

Eric Wieser (Jan 01 2023 at 19:18):

But the former is needed to simplify f ↑0 = f 0, unless simp now knows to use coe_eq_zero.mpr rfl

Reid Barton (Jan 01 2023 at 19:26):

OK, I will just assume that whatever the linter says is correct

Reid Barton (Jan 01 2023 at 19:26):

and that it might differ from lean 3 for no reason

Reid Barton (Jan 04 2023 at 15:25):

It seems like the Lean 3 linter doesn't always work correctly, e.g., simp can prove list.reverse_singleton (and there is no nolints.txt entry for it)

Reid Barton (Jan 04 2023 at 16:22):

I also wonder about the wisdom of this linter in general? e.g. it fails on

@[simp] theorem indexOf_nil (a : α) : indexOf a [] = 0 := rfl

with the message

#check @List.indexOf_nil /- simp can prove this:
  by simp only [List.find?, List.not_mem_nil, not_false_iff, List.indexOf_of_not_mem, List.length_nil]

But isn't it better to do 1 simp step than 5?

Chris Hughes (Jan 04 2023 at 16:22):

I came across an interesting false positive for this linter today. simp can prove the lemma x + x = x in Algebra.Tropical.Basic but only by rewriting it using the lemma x + y = x ↔ x ≤ y, so the lemma is still required to prove f (x + x) = f x for example.

Reid Barton (Jan 04 2023 at 16:23):

btw, when the proof is rfl, doesn't @[simp] also affect the behavior of dsimp? But dsimp can't prove it

Reid Barton (Jan 04 2023 at 16:24):

I mean I guess it could be the case that all 5 of those lemmas are definitional equalities, but say they aren't

Johan Commelin (Jan 04 2023 at 16:26):

I guess that's good evidence that the "simp can prove it" linter should be less strictly enforced. At least in its current state.

Reid Barton (Jan 04 2023 at 16:28):

As I mentioned to Johan earlier, it's also nice from a modularity perspective to be able to declare that e.g. indexOf_nil should be proven by simp, and not have to delete the attribute and rely on it being proven by a jenga tower of 5 other simp lemmas

Reid Barton (Jan 04 2023 at 16:30):

At the moment I'm going through Data.List.Basic and leaving a commented-out -- @[simp] to lemmas affected by this, since I'm not convinced that just removing the attribute is sensible

Reid Barton (Jan 04 2023 at 16:30):

Of course we could also nolint these.

Sebastien Gouezel (Jan 04 2023 at 16:39):

Suppose that you put the simp attribute on indexOf_nil. In concrete situations where this lemma could be used by simp, will it fire or will the other lemmas (that were used to prove indexOf_nil) fire before? In the latter situation, there is indeed no use for the simp attribute on indexOf_nil, because it will never be used.

Yaël Dillies (Jan 04 2023 at 16:40):

In that specific case, dsimp justifies tagging indexOf_nil already.

Heather Macbeth (Jan 04 2023 at 16:40):

Reid Barton said:

As I mentioned to Johan earlier, it's also nice from a modularity perspective to be able to declare that e.g. indexOf_nil should be proven by simp, and not have to delete the attribute and rely on it being proven by a jenga tower of 5 other simp lemmas

Maybe we can make a new attribute simp_can_prove_it, change the simp on these lemmas to simp_can_prove_it, and have a linter which verifies that simp can prove them!

Yaël Dillies (Jan 04 2023 at 16:41):

In general, it would be good if the simp nf linter was checking whether a refl lemma tagged with simp can be proved by dsimp, instead of merely by simp.

Yaël Dillies (Jan 04 2023 at 16:42):

That would remove a bunch of nolints from mathlib.

Johan Commelin (Jan 04 2023 at 16:42):

/me votes for simpCanProveItThankYouVeryMuch

Yaël Dillies (Jan 04 2023 at 16:43):

Ah, but maybe the linter can't access the information of whether a declaration is tagged with the _refl_ attribute (or whichever one we use in mathlib)

Yaël Dillies (Jan 04 2023 at 16:44):

This lack of attribute inspection is a real problem :frown:

Johan Commelin (Jan 04 2023 at 16:46):

But it can find all decls tagged with a given attribute, right? That's all you need in this case.

Reid Barton (Jan 04 2023 at 16:46):

Yaël Dillies said:

In that specific case, dsimp justifies tagging indexOf_nil already.

And even if this was not the case, there is a declarative purpose even if there is no functional effect (lots of stuff we do is useless, after all).

Yaël Dillies (Jan 04 2023 at 16:46):

Very profound. I must review my life choices.

Reid Barton (Jan 04 2023 at 16:47):

Done for now; there are 4 more linter errors (the weird ones involving simp lemmas not simplifying themselves, and the private simp lemma one).

Johan Commelin (Jan 04 2023 at 16:48):

Are the "not simplifying themselves" cases due to timeouts? Or some other reason?

Reid Barton (Jan 04 2023 at 16:50):

I don't think that was the reason. They looked sort of complicated

Reid Barton (Jan 04 2023 at 16:50):

one had an argument with a default value involving a tactic and stuff

Eric Wieser (Jan 04 2023 at 17:12):

Chris Hughes said:

I came across an interesting false positive for this linter today. simp can prove the lemma x + x = x in Algebra.Tropical.Basic but only by rewriting it using the lemma x + y = x ↔ x ≤ y, so the lemma is still required to prove f (x + x) = f x for example.

The mathlib 3 linter is written in a way that allows this; it instead asks simp to simplify the LHS of the relation, and only complains if the result is the RHS. Crucially, it doesn't give the lemma the LHS and RHS at the same time, which is necessary for your example

Reid Barton (Jan 04 2023 at 17:22):

Oh I think this probably explains some of the other cases I found where "simp could prove it" in Lean 4 but not Lean 3.

Johan Commelin (Jan 04 2023 at 20:28):

Have people been throwing away @[simp] too often during the port, because of this linter nagging?

Gabriel Ebner (Jan 04 2023 at 21:17):

Chris Hughes said:

I came across an interesting false positive for this linter today. simp can prove the lemma x + x = x in Algebra.Tropical.Basic but only by rewriting it using the lemma x + y = x ↔ x ≤ y, so the lemma is still required to prove f (x + x) = f x for example.

This is not at all what's happening here.

#check @add_self /- simp can prove this:
  by simp only [le_refl, Tropical.add_eq_left] -/

And add_eq_left is the conditional simp lemma x ≤ y → x + y = x. The le_refl is only used to discharge the hypothesis. So this will also work in f (x + x).

Gabriel Ebner (Jan 04 2023 at 21:18):

Eric Wieser said:

Chris Hughes said:

I came across an interesting false positive for this linter today. simp can prove the lemma x + x = x in Algebra.Tropical.Basic but only by rewriting it using the lemma x + y = x ↔ x ≤ y, so the lemma is still required to prove f (x + x) = f x for example.

The mathlib 3 linter is written in a way that allows this; it instead asks simp to simplify the LHS of the relation, and only complains if the result is the RHS. Crucially, it doesn't give the lemma the LHS and RHS at the same time, which is necessary for your example

The mathlib 4 linter too. (Well technically it's the std4 linter now. :shrug:)

Chris Hughes (Jan 05 2023 at 11:57):

Gabriel Ebner said:

Chris Hughes said:

I came across an interesting false positive for this linter today. simp can prove the lemma x + x = x in Algebra.Tropical.Basic but only by rewriting it using the lemma x + y = x ↔ x ≤ y, so the lemma is still required to prove f (x + x) = f x for example.

This is not at all what's happening here.

#check @add_self /- simp can prove this:
  by simp only [le_refl, Tropical.add_eq_left] -/

And add_eq_left is the conditional simp lemma x ≤ y → x + y = x. The le_refl is only used to discharge the hypothesis. So this will also work in f (x + x).

I've seen a lot where simp proves it with these conditional lemmas. Is there any significant performance penalty to using a lot of these conditional lemmas to prove things instead of unconditional lemmas?

Kevin Buzzard (Jan 05 2023 at 17:27):

This also comes up in mathlib4#1307 -- "simp can prove this" linter errors in lemmas which are tagged simp in mathlib3 and either the mathlib3 linter missed them or some unfolding is being done more eagerly. What are we doing here? Just removing the @[simp] tag and blundering on?

Heather Macbeth (Jan 05 2023 at 17:31):

:ping_pong:
Heather Macbeth said:

Maybe we can make a new attribute simp_can_prove_it, change the simp on these lemmas to simp_can_prove_it, and have a linter which verifies that simp can prove them!

This idea was kind of a joke but it might also be useful; it would serve a similar purpose to assert_not_exists.

Heather Macbeth (Jan 05 2023 at 17:32):

For now, I think we should at least add a porting note. But it shouldn't be hard to invent a dummy attribute simp_can_prove_it and replace bad simp tags with that, even if we don't immediately write any meta code associated to the new attribute.

Johan Commelin (Jan 05 2023 at 17:36):

@Kevin Buzzard At the very least, please leave a trace: -- @[simp] -- Porting note: simp can prove this.

Johan Commelin (Jan 05 2023 at 17:37):

But typically, it seems that you should investigate why simp can suddenly prove this. In Data.List.Basic it was often because of a quasi-dubious simp lemma in Std.

Kevin Buzzard (Jan 05 2023 at 17:53):

Right -- that was what I suggested in the PR.


Last updated: Dec 20 2023 at 11:08 UTC