Zulip Chat Archive
Stream: lean4
Topic: simp destroys let bindings in projection
Tomas Skrivan (Feb 13 2024 at 22:42):
When you turn off zeta
simp still destroys let bindings inside of projection application.
mwe
example :
(let a := id 7
let b := a + 42
(a,b)).2
=
let a := id 7
let b := a + 42
b
:= by
conv =>
lhs
simp (config := {zeta := false}) only []
trace_state
prints id 7 + 42
but I'm expecting
let a := id 7
let b := a + 42
b
Is this intended behavior or is that considered as a bug?
Tomas Skrivan (Feb 14 2024 at 15:15):
Ohh I just found out that setting proj:=false
fixes this. I clearly misunderstood this option and never tried it until now.
Kyle Miller (Feb 14 2024 at 16:53):
I think what's happening is that when proj := true
then the projection function is being unfolded, but to unfold it it has to put the argument into whnf. This is independent of zeta
, which is just about whether simp itself will eliminate a let
.
Here's the simp reduction code: https://github.com/leanprover/lean4/blob/master/src/Lean/Meta/Tactic/Simp/Main.lean#L149
Kyle Miller (Feb 14 2024 at 16:54):
Maybe if there were a way to have simp configure docs#Lean.Meta.WhnfCoreConfig you could turn this kind of zeta reduction off too, while still keeping projection reduction.
Tomas Skrivan (Feb 14 2024 at 16:58):
Another approach is to pull let bindings out of applications.
In my own fork of simp I implemented different version of reduceProjFn?
but updating to lean4:v4.6.0-rc1
broke everything. So now I'm trying to figure out an approach without forking simp :)
Kyle Miller (Feb 14 2024 at 17:07):
I suppose you could use the mathlib lift_lets
for that
Kyle Miller (Feb 14 2024 at 17:09):
That could also probably be a pre-simproc. You'd have to decide how deep into an expression you want to look for let
s though, if you care about quadratic performance.
Tomas Skrivan (Feb 14 2024 at 17:10):
Yeah I experimented with it. I'm afraid that as I'm already running simp, calling lift lets might add extra power to the O(n^*)
Tomas Skrivan (Feb 14 2024 at 17:11):
Hmm limiting the depth of lift_lets is a good idea!
Tomas Skrivan (Feb 14 2024 at 17:14):
However, I'm also doing few extra stuff though. For example, I'm splitting let binding of structure constructors into multiple let bindings. And I'm doing it as pre-simproc now as you suggest.
Last updated: May 02 2025 at 03:31 UTC