Zulip Chat Archive
Stream: lean4
Topic: reducible defeq and rewrites
Jireh Loreaux (Apr 04 2024 at 21:20):
I just found out that my mental model of how rw
works with definitional equality is broken. I expected the following to fail because X
is not reducibly defeq to Nat
, and so I thought Nat.mul_comm
wouldn't fire with rw
. But it does!
def X := Nat
instance : Mul X := inferInstanceAs (Mul Nat)
example (x y : X) : x * y = y * x := by rw [Nat.mul_comm] -- works! why?
Can someone explain what I'm missing here?
Adam Topaz (Apr 04 2024 at 21:23):
I assume it's because x * y
is notation for Nat.mul x y
.
Jireh Loreaux (Apr 04 2024 at 21:24):
I don't follow.
Adam Topaz (Apr 04 2024 at 21:27):
ok, I don't know the details of how rw
actually works, but my guess is that in this case it works because the match of the lhs of the goal with Nat.mul ? ?
succeeds
Adam Topaz (Apr 04 2024 at 21:28):
again, just a guess
Damiano Testa (Apr 04 2024 at 21:28):
You could try with X := ℝ
. :shrug:
Adam Topaz (Apr 04 2024 at 21:30):
Still works for what I assume are similar reasons:
import Mathlib.Tactic
def X := ℝ
instance : Mul X := inferInstanceAs (Mul ℝ)
lemma Real.mul_comm (x y : ℝ) : x * y = y * x := by ring
example (x y : X) : x * y = y * x := by rw [Real.mul_comm]
Jireh Loreaux (Apr 04 2024 at 21:30):
This also works:
import Mathlib
def X := ℝ
instance : Mul X := inferInstanceAs (Mul ℝ)
example (x y : X) : x * y = y * x := by rw [mul_comm (G := ℝ)] -- works! why?
Matthew Ballard (Apr 04 2024 at 21:33):
I thought rw
operated at default
Adam Topaz (Apr 04 2024 at 21:34):
yeah that's right.
Jireh Loreaux (Apr 04 2024 at 21:34):
Surely this wasn't the case in Lean 3, though?
Matthew Ballard (Apr 04 2024 at 21:39):
I thought everything was at default/semireducible
there (says the person who used it very little)
Kevin Buzzard (Apr 04 2024 at 22:15):
Yeah I am also surprised by this. I thought that the whole point of def
was not to let this stuff leak through so how can it leak through?
Jireh Loreaux (Apr 04 2024 at 22:16):
I mean, it makes sense if rw
works at default transparency, I just didn't think that was the case. I'm fairly confident it didn't in Lean 3, but perhaps that changed.
Kyle Miller (Apr 04 2024 at 23:00):
Implicit arguments switch to a higher transparency setting, but I don't remember the exact details
Jireh Loreaux (Apr 05 2024 at 16:50):
@Kyle Miller the first example works even if you write by rw [Nat.mul_comm x y]
Kyle Miller (Apr 05 2024 at 18:52):
Sure, but that makes sense if implicit arguments use a higher transparency setting:
Kyle Miller (Apr 05 2024 at 18:54):
example (x y : X) : type_of% (Nat.mul_comm x y) = (x * y = y * x) := by with_reducible rfl
Eric Wieser (Apr 06 2024 at 08:37):
What breaks if this behavior is disabled?
Eric Wieser (Apr 06 2024 at 08:39):
If a heuristic of some kind is still needed, perhaps adapting the rule to not change reducibility of Sort
s would work?
Jovan Gerbscheid (Apr 07 2024 at 10:47):
The reducibility can be controlled using Rewrite.Config
:
structure Config where
transparency : TransparencyMode := TransparencyMode.reducible
offsetCnstrs : Bool := true
occs : Occurrences := Occurrences.all
Setting it can be done with this syntax: rw (config := {transparency := .all})
. As you can see the default setting is reducible
.
Eric Wieser (Apr 07 2024 at 10:56):
Jovan, as alluded to above, the default is using a more lenient interpretation of reducIbility than reducible
is supposed to mean.
Eric Wieser (Apr 07 2024 at 10:56):
Which is to say; I think that setting is only partially respected
Jovan Gerbscheid (Apr 07 2024 at 10:58):
Eric Wieser said:
If a heuristic of some kind is still needed, perhaps adapting the rule to not change reducibility of
Sort
s would work?
Looking at it from a DiscrTree
perspective, I think you want unification with the lookup results to work in the reducible
transparency. DiscrTree
does not index instance arguments, and does not index implicit arguments if they do not satisfy isType
. For the not indexed terms I think you do want to change the transparency. But not changing the transparency in the case of implicit type arguments seems alright.
Eric Wieser (Apr 07 2024 at 12:22):
Does rw not currently use discrtrees?
Jovan Gerbscheid (Apr 07 2024 at 13:00):
No, I thought you were suggesting to change the behaviour of isDefEq
. And isDefEq
is used in combination with DiscrTree
for example in simp.
Jovan Gerbscheid (Apr 07 2024 at 13:02):
Because in the above example isDefEq
is what changes the transparency setting for implicit arguments.
Jovan Gerbscheid (Apr 07 2024 at 14:08):
rw??
also uses discrimination trees, but in that case it is my RefinedDiscrTree
instead of lean's DiscrTree
.
rw
uses a more light weight form of "indexing" (in the function kabstract
): it uses Expr.toHeadIndex
and Expr.headNumArgs
to find the head and number of arguments of each subexpression. And only if those match, will it try the more expensive isDefEq
check.
Last updated: May 02 2025 at 03:31 UTC