Zulip Chat Archive
Stream: new members
Topic: unfold vs dsimp
Kevin Cheung (Feb 27 2024 at 14:06):
I know that the documentation discourages the use of Set.inter. But I would like to know why in the following dsimp works but unfold doesn't:
example : s ∩ u ⊆ u ∩ s := by
dsimp [(· ∩ ·)]
sorry
example : s ∩ u ⊆ u ∩ s := by
unfold (· ∩ ·)
sorry
In the second version, Lean complains about unexpected token '('. Is it simply a limitation of unfold that it cannot unfold operators?
Timo Carlin-Burns (Feb 27 2024 at 19:19):
I'm surprised either of those work. The only good way to unfold notation that I've learned is to define a custom lemma like docs#Set.inter_def which can be proved by rfl. It seems like simp has some special support for the · notation for defining functions.
import Mathlib.Data.Set.Basic
variable (s t : Set α)
-- This is the only one I would've expected to work. I thought `simp` and `unfold` only worked with declaration names.
example : s ∩ u ⊆ u ∩ s := by
dsimp [Inter.inter] -- unfolds to `Set.inter`
sorry
example : s ∩ u ⊆ u ∩ s := by
dsimp [(Inter.inter · ·)] -- unfolds to `Set.inter`
sorry
example : s ∩ u ⊆ u ∩ s := by
dsimp [(· ∩ ·)] -- unfolds to `Set.inter`
sorry
example : s ∩ u ⊆ u ∩ s := by
dsimp [(fun x y => Inter.inter x y)] -- invalid 'simp', proposition expected
sorry
example : s ∩ u ⊆ u ∩ s := by
dsimp [(Inter.inter)] -- invalid 'simp', proposition expected
sorry
example : s ∩ u ⊆ u ∩ s := by
dsimp [((· ∩ ·))] -- invalid 'simp', proposition expected
sorry
Kevin Cheung (Feb 27 2024 at 22:48):
Interesting. Replacing dsimp [Inter.inter] with unfold Inter.inter gives the goal instInterSet.1 s u ⊆ instInterSet.1 u s, not Set.inter s u ⊆ Set.inter u s. I am now utterly confused. Why instInterSet.1 here?
Kyle Miller (Feb 27 2024 at 22:53):
docs#Inter is a "notation typeclass" that provides the notation to whichever types implement the instance.
docs#Set.instInterSet is the instance for Set. When you unfold Inter.inter, you're seeing its definition, which is that it gets the definition from the instance.
Kyle Miller (Feb 27 2024 at 22:54):
If you do unfold_projs (mathlib tactic) it will unfold instInterSet.1 s
Kyle Miller (Feb 27 2024 at 22:56):
The limitation of unfold is that the syntax expects a sequence of identifiers
Kevin Cheung (Feb 27 2024 at 22:56):
So unfold cannot unfold operators?
Kevin Cheung (Feb 27 2024 at 22:57):
It seems that dsimp is more powerful than unfold. Are there reasons for using unfold but not dsimp?
Kyle Miller (Feb 27 2024 at 22:57):
It can, if you give it the underlying identifier. Here it's Inter.inter (you can check that by hovering over the notation)
Kevin Cheung (Feb 27 2024 at 22:58):
When I hover over ∩ , I saw only the following:
Set α
a ∩ b is the intersection of a and b.
Type ∩ using \i or \inter or \intersection or \cap
Kevin Cheung (Feb 27 2024 at 22:59):
Oh. I have to hover in the Infoview to see the Inter.inter
Kyle Miller (Feb 27 2024 at 22:59):
You can also "go to declaration" if you right click on it in the source
Kevin Cheung (Feb 27 2024 at 23:01):
Thanks for the tip! I was trying so hard looking into the documentation to see where intersection is defined.
Timo Carlin-Burns (Feb 27 2024 at 23:17):
Kyle, do you happen to know why (f · ·) is behaving differently from (fun x y => f x y) here? Is simp special casing the · syntax? Or does the · syntax have some eta-reduction built in?
Kyle Miller (Feb 27 2024 at 23:26):
Yeah, there's a special case for cdot syntax for simp (docs#Lean.Elab.Term.elabCDotFunctionAlias?)
Last updated: May 02 2025 at 03:31 UTC