Zulip Chat Archive

Stream: lean4

Topic: Unused linter with `by_cases`


Yury G. Kudryashov (Dec 26 2023 at 19:49):

Here is an #mwe:

import Mathlib

lemma bycases_unused (n : ) : n = 1  1 + 2 = 3 := by
  by_cases hn : n = 1
  · rw [hn]; intro; rfl
  · intro; rfl

#lint

reports no errors. AFAIR, we had a linter in mathlib3 that checked for this kind of "unused". Is it hard to reimplement in Lean 4?

Yury G. Kudryashov (Dec 26 2023 at 19:50):

I tried both with by_cases (generates if .. then .. else ..) and cases eq_or_ne n 0 (generates Or.casesOn)

Yury G. Kudryashov (Dec 26 2023 at 19:51):

I recently found an unneeded by_cases in a longer proof in Mathlib, this :up: is a minimized version.

Mario Carneiro (Dec 26 2023 at 19:57):

(PSA: please don't use import Mathlib in MWEs)

Yury G. Kudryashov (Dec 26 2023 at 19:59):

  1. That's not what #mwe says.
  2. I used import Mathlib intentionally to be sure that I run all Mathlib linters.

Mario Carneiro (Dec 26 2023 at 20:01):

"mathlib linters" aren't defined in mathlib anymore, they are in Std now

Mario Carneiro (Dec 26 2023 at 20:01):

in particular the one you are talking about here is in std

Mario Carneiro (Dec 26 2023 at 20:02):

the reason for the issue is that you did the case split before the intro, so it's not just an unused variable

Mario Carneiro (Dec 26 2023 at 20:02):

with

theorem bycases_unused (n : ) : n = 1  1 + 2 = 3 := by
  intro h
  by_cases hn : n = 1
  · rw [hn] at h
  · rfl

the linter does trigger

Mario Carneiro (Dec 26 2023 at 20:03):

I would expect the lean 3 linter to have the same behavior here

Yury G. Kudryashov (Dec 26 2023 at 20:04):

The actual proof was more like

lemma comm2 (m : Nat) : 2 * m = m * 2 := by
  by_cases hm : m = 0
  · rw [hm]; rfl
  · apply Nat.mul_comm

Yury G. Kudryashov (Dec 26 2023 at 20:05):

I'll test mathlib linter now.

Mario Carneiro (Dec 26 2023 at 20:06):

that doesn't have an unused variable

Yury G. Kudryashov (Dec 26 2023 at 20:10):

Indeed, Lean 3 doesn't catch it too. Can we catch this (may be, not on the fly, if it takes time)?

Mario Carneiro (Dec 26 2023 at 20:11):

sure but what are you looking for

Yury G. Kudryashov (Dec 26 2023 at 20:12):

One of the branches of by_cases ignores the assumption, thus we can drop the by_cases.

Yury G. Kudryashov (Dec 26 2023 at 20:13):

And similarly for cases (though this can be more tricky)

Yury G. Kudryashov (Dec 26 2023 at 20:18):

A related request: report unused have := something, not only have h := something.

Yury G. Kudryashov (Dec 26 2023 at 20:27):

I'm cleaning up some have _ := now.

Eric Rodriguez (Dec 26 2023 at 21:33):

If this is turned into an em with rcases (not cases, that's got a bug open) the linter will trigger. Not that I think we should get rid of by_cases

Yury G. Kudryashov (Dec 26 2023 at 21:34):

Indeed, rcases eq_or_ne m 0 with rfl | hm triggers the linter.

Yury G. Kudryashov (Dec 26 2023 at 21:35):

Or do you mean something else?

Eric Rodriguez (Dec 26 2023 at 21:37):

Yes, I do mean that!


Last updated: May 02 2025 at 03:31 UTC