Zulip Chat Archive
Stream: general
Topic: n ≠ 0 vs 0 < n
Johan Commelin (Jun 27 2020 at 17:14):
Do we have a convention on whether we assume n ≠ 0
or 0 < n
in statements (for n : nat
)? Should we have a linter for this?
Floris van Doorn (Jun 27 2020 at 17:16):
I would also like to standardize this and similar things (like n ≠ 0
vs 0 < n
in ennreal
or n ≠ \top
vs n < \top
in ennreal
).
Chris Hughes (Jun 27 2020 at 17:17):
The convention is 0 < n
but I would prefer n ne 0
Floris van Doorn (Jun 27 2020 at 17:18):
My vote would be to use inequalities as default: they are more easily usable. For example n ≠ 0
and n \le m
doesn't immediately give m ≠ 0
, but replace ne 0
by inequalities and it's one step.
(inequalities are sometimes 1 step longer to prove, but I think "immediate usability" is more useful).
Floris van Doorn (Jun 27 2020 at 17:19):
Why would you prefer \ne
, @Chris Hughes?
Chris Hughes (Jun 27 2020 at 17:23):
It's usually easier to prove ne 0
, assume h : n = 0, simp * at *
works quite a lot. It's also more consistent with types other than nat
, where a nonzero assumption is more common than positivity, so it's easier to prove a casted nat is nonzero if you already have n ne 0
Chris Hughes (Jun 27 2020 at 17:27):
example (n m : ℕ) (hn : n ≠ 0) (hm : n ≤ m) : m ≠ 0 := λ h, by simp * at *
Chris Hughes (Jun 27 2020 at 17:29):
I think assumptions like a * b \ne 0
are more common ways to prove nonzero-ness than transitivity of le
or lt
Johan Commelin (Jun 27 2020 at 17:43):
Before writing this post I was also intuitively leaning towards ≠
... I think unconsciously for reasons similar to the ones that Chris has listed.
Floris van Doorn (Jun 27 2020 at 17:47):
Ok, that's fair. I'm fine with switching to "not equal" as default.
Johan Commelin (Jun 27 2020 at 18:07):
@Floris van Doorn How hard is it to write a linter for this?
Floris van Doorn (Jun 27 2020 at 18:12):
It's not hard.
So the linter complains whenever you have an assumption of the form 0 < _
in nat
. That's easy. I think we want to allow other cases, like an iff
containing 0 < _
?
Johan Commelin (Jun 27 2020 at 18:13):
I don't know if we want that...
Johan Commelin (Jun 27 2020 at 18:14):
I think that apart from some cases that we explicitly nolint
, we should strive to then keep 0 < _
out of assumptions, and conclusions.
Floris van Doorn (Jun 27 2020 at 18:19):
ok, it's also easy to check for any occurrence of 0 < _
in nat
.
Floris van Doorn (Jun 27 2020 at 18:19):
Let's first get to a consensus though, few people have chimed in so far.
Johan Commelin (Jun 27 2020 at 18:21):
Let's ping some people with opinions: @Mario Carneiro @Patrick Massot @Sebastien Gouezel @Simon Hudon @Gabriel Ebner
Johan Commelin (Jun 27 2020 at 18:21):
@Kenny Lau @Scott Morrison @Kevin Buzzard @Reid Barton
Johan Commelin (Jun 27 2020 at 18:22):
Lol... I could almost as well have just used @maintainers
:face_palm:
Kenny Lau (Jun 27 2020 at 18:22):
first let's remove all the n > 0
instances in core
Kenny Lau (Jun 27 2020 at 18:24):
For n ≠ 0
, like this message (you can like both).
Kenny Lau (Jun 27 2020 at 18:24):
For 0 < n
, like this message (you can like both).
Kevin Buzzard (Jun 27 2020 at 19:18):
I love that ne is a function: you can just apply it when you're showing simple term mode stuff to mathematicians or explaining definitional equality. The more ne
the better
Reid Barton (Jun 27 2020 at 19:45):
I don't see much point in a lint rule because it will be unavoidable to use both anyways.
Reid Barton (Jun 27 2020 at 20:03):
I'd rather just write whatever is more natural/convenient locally, which I guess is the status quo.
Scott Morrison (Jun 28 2020 at 00:17):
A lint rule seems excessive, except for the fact that it would be really nice to be much more consistent/principled about this choice, and from experience it may take a linting rule to push us to achieve this. :-)
Yaël Dillies (Aug 31 2021 at 06:44):
I'm about to change some occurrences of n ≠ 0
as hypotheses to 0 < n
(where n : ℕ
) eg in data.multiset.erase_dup
. Is everybody fine with that?
Johan Commelin (Aug 31 2021 at 07:07):
If the diff has a net negative size, then I would find it hard to object.
Floris van Doorn (Aug 31 2021 at 07:10):
There was a 10-to-1 vote in favor of n ≠ 0
compared to 0 < n
earlier in this thread, so I think not everybody is fine with that.
Johan Commelin (Aug 31 2021 at 07:11):
Good point. I've just changed my vote to no vote
Sebastien Gouezel (Aug 31 2021 at 07:13):
The convention we have settled on in ennreal
(with respect to top) is that in assumptions we should favor a \ne top
, and in conclusions we should favor a < top
. The reason being that it is very easy to go from the strict inequality to non-equality, so if you have strict inequality in the context it is trivial to apply a lemma using non-equality.
Yaël Dillies (Aug 31 2021 at 07:14):
Well, I'm mostly removing some nat.pos_of_ne_zero hn
where hn : n ≠ 0
. So it does sound like I'm going in the right direction.
Yaël Dillies (Aug 31 2021 at 07:14):
Also, the style guide indicates that 0 < n
is the favored form.
Yaël Dillies (Aug 31 2021 at 07:45):
To be fair, if everything was using n ≠ 0
this wouldn't happen.
Johan Commelin (Aug 31 2021 at 07:54):
Would it be evil to have
section
variables {α : Type*}
lemma ne.bot_lt [order_bot α] {a : α} (h : a ≠ ⊥) : ⊥ < a :=
bot_lt_iff_ne_bot.mpr h
lemma ne.bot_lt' [order_bot α] {a : α} (h : ⊥ ≠ a) : ⊥ < a :=
h.symm.bot_lt
lemma ne.lt_top [order_top α] {a : α} (h : a ≠ ⊤) : a < ⊤ :=
lt_top_iff_ne_top.mpr h
lemma ne.lt_top' [order_top α] {a : α} (h : ⊤ ≠ a) : a < ⊤ :=
h.symm.lt_top
end
Sebastien Gouezel (Aug 31 2021 at 08:06):
It wouldn't be evil at all, but it would still be longer to type than h.ne
to go from h : a < top
to a \ne top
(or h.ne'
for the other non-equality) :-)
Johan Commelin (Aug 31 2021 at 08:08):
Completely agreed. So I think your rule of thumb "inputs use \ne
, outputs use <
" is a very good one. But we will still need to move from \ne
to <
occasionaly.
Sebastien Gouezel (Aug 31 2021 at 08:09):
Does everyone agree that I update the style guide to mention this rule of thumb?
Yaël Dillies (Aug 31 2021 at 09:09):
I would first see how often n ≠ 0
and 0 < n
are used, because in my experience I encountered 0 < n
much more.
Eric Rodriguez (Aug 31 2021 at 09:20):
I've seen both, and I've made an active effort to write an API that uses n ≠ 0
as inputs and 0 < n
as outputs as much as possible
Ruben Van de Velde (Aug 31 2021 at 10:00):
The question isn't so much what exists now, but what's most useful going forward. There seemed to be a fair amount of support for ne in hypotheses upthread, at least.
Johan Commelin (Aug 31 2021 at 11:53):
#8935 has the dot-notation lemmas from above
Sebastien Gouezel (Aug 31 2021 at 12:08):
I have updated the style guide, see the paragraph Normal forms
at the end of https://github.com/leanprover-community/leanprover-community.github.io/blob/newsite/templates/contribute/style.md#normal-forms
Last updated: Dec 20 2023 at 11:08 UTC