Zulip Chat Archive
Stream: new members
Topic: linarith
Joachim Breitner (Feb 20 2022 at 20:34):
Am I expecting too much from linarith? I am surprised this fails:
change w.to_list.length ≠ 0 at hlen0,
change w.to_list.length ≠ 1 at hlen1,
have hlen : w.to_list.length ≥ 2, by linarith,
Joachim Breitner (Feb 20 2022 at 20:35):
Here is a #mwe:
example (n : nat) (h0 : n ≠ 0) (n1 : n ≠ 1) : n > 1 := by linarith
Joachim Breitner (Feb 20 2022 at 20:36):
Ah, judging from the docs, linarith
isn’t actually for nat
Alex J. Best (Feb 20 2022 at 21:25):
You can use tactic#omega for this (but it's not allowed in mathlib anymore).
Mario Carneiro (Feb 21 2022 at 05:30):
linarith
doesn't know much about nat, but I feel like it should be able to do this one. Maybe it works if you add n >= 0
?
Mario Carneiro (Feb 21 2022 at 05:33):
example (n : nat) (h0 : n > 0) (n1 : n < 1) : n > 1 := by linarith -- ok
example (n : nat) (h0 : n > 0) (n1 : n > 1) : n > 1 := by linarith -- ok
example (n : nat) (h0 : n > 0) (n1 : n ≠ 1) : n > 1 := by linarith -- fail
It looks like the issue is that the transformation of a ≠ b
to a < b
or a > b
happens after the nat preprocessor. cc: @Rob Lewis
Rob Lewis (Feb 21 2022 at 15:19):
No, the split_ne
preprocessor isn't enabled by default (linarith
isn't an SMT solver, etc etc)
Rob Lewis (Feb 21 2022 at 15:19):
example (n : nat) (h0 : n > 0) (n1 : n ≠ 1) : n > 1 := by linarith {split_ne := tt}
Rob Lewis (Feb 21 2022 at 15:40):
@Joachim Breitner note that if you use this for your original goal, it's doing exactly the dumb thing you'd hope it wouldn't: it's running linarith
four times, once for every combination of cases. This is why split_ne
is disabled by default. Exponential blowup in the number of disequalities in the context.
Joachim Breitner (Feb 21 2022 at 15:40):
Thanks! Luckily, it seems I don’t even need this reasoning. Classical case of a pen-and-paper-proof making too strong assumptions, and I only need to handle 0 and positive separately.
Last updated: Dec 20 2023 at 11:08 UTC