Zulip Chat Archive
Stream: mathlib4
Topic: push_neg doesn't simplify fully
Gareth Ma (Oct 27 2023 at 13:24):
In the lemma below, applying push_neg
twice changes the goal, whereas I would assume that push_neg
returns a canonical "pushed neg" form. Is my assumption false or is this a bug?
import Mathlib.Combinatorics.SimpleGraph.Hasse
import Mathlib.Combinatorics.SimpleGraph.Basic
import Mathlib.Data.PNat.Prime
open SimpleGraph
def divisibilityGraph : SimpleGraph ℕ where
Adj a b := (a ≠ b) ∧ ((a ∣ b) ∨ (b ∣ a))
symm _ _ h := ⟨h.left.symm, h.right.symm⟩
loopless a ha := ha.left $ refl a
example {p q : ℕ} (hp : p.Prime) (hq : q.Prime) : ¬ ⟦(p, q)⟧ ∈ divisibilityGraph.edgeSet := by
rw [mem_edgeSet, divisibilityGraph]
/- ⊢ ¬Adj (mk fun a b => a ≠ b ∧ (a ∣ b ∨ b ∣ a)) p q -/
push_neg
/- ⊢ ¬(p ≠ q ∧ (p ∣ q ∨ q ∣ p)) -/
push_neg
/- ⊢ p ≠ q → ¬p ∣ q ∧ ¬q ∣ p -/
sorry
Patrick Massot (Oct 27 2023 at 13:24):
This is definitely a bug.
Ruben Van de Velde (Oct 27 2023 at 13:26):
Hmm, I'm surprised push_neg
eliminates the Adj
at all
Gareth Ma (Oct 27 2023 at 13:29):
I assume that wrapping the tactic core with repeat
is not the correct fix, since this indicates something wrong with the algorithm?
Gareth Ma (Oct 27 2023 at 13:31):
Ruben Van de Velde said:
Hmm, I'm surprised
push_neg
eliminates theAdj
at all
I don't know how the tactic works, but the source code indicates it uses simp
to some degree, which can probably unfold the Adj
- indeed simp only
does unfold Adj
Patrick Massot (Oct 27 2023 at 13:33):
Unfolding Adj
is definitely not part of the spec. The Lean 3 implementation was not using simp
at all, but the Lean 4 port took a shortcut.
Kyle Miller (Oct 27 2023 at 19:05):
The existing simp configuration that push_neg
uses probably should be reviewed more carefully, but setting it not not unfold projections was enough for this example: #7989
Last updated: Dec 20 2023 at 11:08 UTC