Zulip Chat Archive
Stream: mathlib4
Topic: ring_nf failing to fully normalize
David Renshaw (Feb 06 2023 at 23:20):
import Mathlib.Tactic.Ring
theorem foo (x : ℤ) (h₀ : x^2 - (x - 1) * x = 5) : x = 5 := by
ring_nf at h₀
-- I expect h₀ to be `x = 5` now, but instead it is `x ^ 2 - (-x + x ^ 2) = 5`.
sorry
David Renshaw (Feb 08 2023 at 20:57):
A more minimal example:
import Mathlib.Tactic.Ring
theorem foo (x : ℤ) (h₀ : x - x + x = 0) : x = 0 := by
ring_nf at h₀
-- I expect h₀ to be `x = 0` now, but instead it is `0 + x = 0`.
sorry
David Renshaw (Feb 08 2023 at 22:50):
@Mario Carneiro can you explain the purpose of this guard !va.isAtom
line?
https://github.com/leanprover-community/mathlib4/blob/c16c0c414d4ea87bd10716ffd38b93d9d66aa215/Mathlib/Tactic/Ring/RingNF.lean#L97
When I comment it out, the unexpected behavior goes away.
Mario Carneiro (Feb 08 2023 at 22:55):
It is to prevent ring from doing useless rewrites all over the place
David Renshaw (Feb 08 2023 at 22:55):
but it's looking at the output of the rewrite, right?
Mario Carneiro (Feb 08 2023 at 22:56):
yes, it's a bit awkward to detect whether the input was an atom because it hasn't been parsed yet
David Renshaw (Feb 08 2023 at 22:56):
If something rewrites to an atom, that doesn't sound useless to me.
Mario Carneiro (Feb 08 2023 at 22:56):
for sure, this is a bug, but the fix is not so easy
David Renshaw (Feb 08 2023 at 22:57):
is there an existing github issue?
David Renshaw (Feb 08 2023 at 22:57):
I'll open one if not
Mario Carneiro (Feb 08 2023 at 22:57):
no
David Renshaw (Feb 08 2023 at 23:04):
https://github.com/leanprover-community/mathlib4/issues/2171
Thomas Murrills (Feb 09 2023 at 10:12):
could we add a skipParse
field to either the cache or eval
which would optionally hold the data necessary to skip the parsing part of eval
? Then functions like rewrite
could do it themselves (it could be none
by default, so nothing would have to change everywhere)
Or, maybe we could refactor the post-parsing part of eval
into eval.core
or something (which would still itself call eval
, not eval.core
) (I’m guessing this would need mutual
)
Thomas Murrills (Feb 09 2023 at 10:13):
if one of these would be acceptable I think I could do it
Scott Morrison (Mar 08 2023 at 01:37):
I don't understand @Thomas Murrills's suggestion here. If they or @Mario Carneiro have time to outline a proposed fix I can try implementing it.
Mario Carneiro (Mar 08 2023 at 01:45):
The issue is that eval
does both parsing and evaluation simultaneously, so it is difficult to tell whether we took the code path "it's an atom so we did nothing" as distinct from "it was not an atom but it was reduced to one", and it's not easy to see what kind of additions we can make that don't impact performance in the normal case. I think the best option would be to just detect atoms directly, basically copying the code of eval
but only using it to determine whether we would have done something other than the evalAtom
path
Heather Macbeth (Mar 08 2023 at 01:52):
How did it work in mathlib3?
Scott Morrison (Mar 08 2023 at 02:36):
!4#2708 hopefully implements Mario's suggestion, and resolves !4#2171.
Scott Morrison (Mar 09 2023 at 00:55):
I've made another attempt at this one. :-)
Last updated: Dec 20 2023 at 11:08 UTC