-
Notifications
You must be signed in to change notification settings - Fork 434
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug with nested ifs and lets #4375
Comments
I've minimized it to: def dif (p : Prop) (_ : p → Nat) : Nat := Nat.zero
set_option trace.Meta.isDefEq.assign true in
example : Nat :=
let n : Nat := Nat.zero
dif True (fun (_ : True) =>
let m : Nat := n
dif (m = m) fun (_ : m = m) => (
let x := 0
Nat.zero
)
) This is broken all the way back to Lean 4.0.0. Similarly, removing the In either example, if there is an argument in the declaration header, the bug only shows up in f97a7d4 and later. |
Great insight! I thought let reassignments might be the issue but that was a red herring. |
I also found a
It also fails at version 4.0.0. I thought it might be related to this issue so I am adding it here. |
Yup, same bug indeed, since set_option trace.Meta.isDefEq.assign true in
example: Nat :=
let a: Nat := Nat.zero
have: True := trivial
let b: Nat := Nat.zero
have: a = b := Eq.refl a
(fun (_ : Nat) => 0) Nat.zero The
|
) Closes #4375 The following example raises `error: (kernel) declaration has free variables '_example'`: ```lean example: Nat → Nat := let a : Nat := Nat.zero fun (_ : Nat) => let b : Nat := Nat.zero (fun (_ : a = b) => 0) (Eq.refl a) ``` During elaboration of `0`, `elabNumLit` creates a synthetic mvar `?_uniq.16` which gets abstracted by `elabFun` to `?_uniq.16 := ?_uniq.50 _uniq.6 _uniq.12`. The `isDefEq` to `instOfNatNat 0` results in: ``` ?_uniq.50 := fun ([email protected]._hyg.13 : Nat) => let b : Nat := Nat.zero fun ([email protected]._hyg.23 : Eq.{1} Nat _uniq.4 b) => instOfNatNat 0 ``` This has a free variable `_uniq.4` which was `a`. When the application of `?_uniq.50` to `#[#2, #0]` is instantiated, the `let b : Nat := Nat.zero` blocks the beta-reduction and `_uniq.4` remains in the expression. fix: add `(useZeta := true)` here: https://github.com/leanprover/lean4/blob/ea46bf2839ad1c98d3a0c3e5caad8a81f812934c/src/Lean/MetavarContext.lean#L567
I do not think that this was fixed by #4410. The change in #4410 seems fine, but it does not fix the underlying issue in (I think!) Here's another test case that's simpler still: example :=
let a : Nat := Nat.zero
fun (_ : True) =>
let b : Nat := Nat.zero
(fun (_ : a = b) => 0) While #4110 makes some ill-formed metavariable assignments end up not mattering, they are still present. The issue seems to be that the OfNat instance metavariable for If you add well-formedness checks to private def checkTypesAndAssign (mvar : Expr) (v : Expr) : MetaM Bool :=
withTraceNodeBefore `Meta.isDefEq.assign.checkTypes (return m!"({mvar} : {← inferType mvar}) := ({v} : {← inferType v})") do
if !mvar.isMVar then
trace[Meta.isDefEq.assign.checkTypes] "metavariable expected"
return false
else
-- must check whether types are definitionally equal or not, before assigning and returning true
let mvarType ← inferType mvar
let vType ← inferType v
if (← withTransparency TransparencyMode.default <| Meta.isExprDefEqAux mvarType vType) then
unless (← MetavarContext.isWellFormed (← mvar.mvarId!.getDecl).lctx v) do
throwError "in checkTypesAndAssign: metavariable has incompatible local context for value\n{indentD v}\nMetavariable:{indentD mvar.mvarId!}"
unless (← MetavarContext.isWellFormed (← mvar.mvarId!.getDecl).lctx vType) do
throwError "in checkTypesAndAssign: metavariable has incompatible local context for type\n{indentD vType}\nMetavariable:{indentD mvar.mvarId!}"
mvar.mvarId!.assign v
pure true
else
pure false Is there any justification in the PR for not zeta reducing being called a bug in this comment? It seems to me that |
I had a similar theory prior to changing the fix: 625b45c (this implementation is not good but the idea was essentially to change lean4/src/Lean/Meta/ExprDefEq.lean Lines 390 to 420 in 93fa9c8
^Is this what you're referring to? I backtracked on that idea because the existing behavior looked intentional / I couldn't be sure. |
@kmill Your test case is failing for me on "Mathlib stable" but not latest or nightly |
Closing until reconfirmation |
Prerequisites
Please put an X between the brackets as you perform the following steps:
https://github.com/leanprover/lean4/issues
Avoid dependencies to Mathlib or Batteries.
https://live.lean-lang.org/#project=lean-nightly
(You can also use the settings there to switch to “Lean nightly”)
Description
The following code gives
(kernel) declaration has free variables 'getHexDigit?'
on Lean 4.9.0-rc1.Removing the second let or the third let eliminates the problem.
Context
Discovered while updating lean4-unicode-basic to v4.9.0-rc1. Posted on Zulip.
Versions
Lean (version 4.9.0-rc1, arm64-apple-darwin23.5.0, commit be6c4894e0a6, Release)
Impact
Add 👍 to issues you consider important. If others are impacted by this issue, please ask them to add 👍 to it.
The text was updated successfully, but these errors were encountered: