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 Sorts 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 Sorts 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