Zulip Chat Archive
Stream: mathlib4
Topic: Strange push_neg behaviour
Sophie Morel (May 29 2023 at 19:37):
I've been having some trouble recently with push_neg
(and hence also contrapose!
) in Lean4. I was always able to fix my proofs by using more targeted rewrite
s with lemmas like not_exists
etc, but I'm wondering if there is a better way to fix the problem. Here is a MWE:
import Mathlib.Tactic
import Mathlib.Init.Algebra.Order
variable {α : Type _}
example (r : LinearOrder α) (s : Preorder α) (a b : α) : ¬(s.lt a b → r.lt a b) := by
push_neg -- now the goal is s.lt a b ∧ s.le b a !
/- Error message:
application type mismatch
id
(Eq.trans (Mathlib.Tactic.PushNeg.not_implies_eq (a < b) (a < b))
(congrArg (And (a < b)) (Mathlib.Tactic.PushNeg.not_lt_eq a b)))
argument has type
(¬(a < b → a < b)) = (a < b ∧ b ≤ a)
but function has type
(¬(a < b → a < b)) = (a < b ∧ b ≤ a) → (¬(a < b → a < b)) = (a < b ∧ b ≤ a)
-/
So push_neg
changed the goal into something that is not equivalent, but it also generated an error so I didn't end up writing a wrong proof. (It did stump me for quite a while before I realized what was going on, because in my original example the push_neg
was hidden in a contrapose!
in the middle of a long proof, and the error message told me that the problem was at the beginning of the statement.)
Does anybody know what is going on here ?
Yury G. Kudryashov (May 29 2023 at 19:47):
push_neg
is a mathlib
tactic, so I moved the thread here.
Yury G. Kudryashov (May 29 2023 at 19:47):
Probably, push_neg
doesn't work well when you have two *Order
instances that don't agree with each other.
Kyle Miller (May 29 2023 at 19:47):
push_neg
knows about LT.lt
and so on and it synthesizes some LinearOrder
instances to make some conversions. It's not expecting that you have overlapping instances like this. Do you mean to have a separate Preorder
? This comes from the LinearOrder
.
variable [LinearOrder α]
#synth Preorder α
Sophie Morel (May 29 2023 at 19:48):
Unfortunately I'm proving stuff about the set of (total) preorders on a type, so I don't really have a choice...
Yury G. Kudryashov (May 29 2023 at 19:49):
push_neg
can try to unify LT.lt
from generated LinearOrder
with the one it sees.
Sophie Morel (May 29 2023 at 19:49):
(In fact, in my original proof I had at least four different orders floating around.)
Yury G. Kudryashov (May 29 2023 at 19:50):
@Frédéric Dupuis fixed one bug in this code some time ago (push_neg
tried to apply not_lt
on a partial order)
Sophie Morel (May 29 2023 at 19:50):
Yury G. Kudryashov said:
push_neg
can try to unifyLT.lt
from generatedLinearOrder
with the one it sees.
Is there any way for me to tell push_neg
not to do that ? At this point I have to avoid it in a lot of proofs.
Yury G. Kudryashov (May 29 2023 at 19:52):
There is a way: open the source code in Mathlib/Tactic/PushNeg.lean
and fix it.
Kyle Miller (May 29 2023 at 19:52):
I'm looking into it right now
Yury G. Kudryashov (May 29 2023 at 19:52):
Unfortunately, I'm not good enough with Lean 4 meta programming to do it.
Sophie Morel (May 29 2023 at 19:53):
Yury G. Kudryashov said:
There is a way: open the source code in
Mathlib/Tactic/PushNeg.lean
and fix it.
Okay, or I could juste use rw
! :grinning_face_with_smiling_eyes:
Sophie Morel (May 29 2023 at 19:53):
My knowledge of Lean4 metaprogramming is nil...
Sophie Morel (May 29 2023 at 19:53):
Kyle Miller said:
I'm looking into it right now
Thanks Kyle !
Kyle Miller (May 29 2023 at 20:43):
@Sophie Morel It still needs to pass CI, but here's a fix: mathlib4#4478
Sophie Morel (May 29 2023 at 20:49):
Wow !
Last updated: Dec 20 2023 at 11:08 UTC