Zulip Chat Archive
Stream: new members
Topic: native_decide: "(kernel) declaration has free variables "
Alex Meiburg (Mar 15 2024 at 21:02):
When I try
import Mathlib
theorem stupid : IsLeast {s | true} 0 := by
have : Decidable (IsLeast {s | true} 0 ) := by
apply isTrue
simp
native_decide
I get the fairly inscrutable message
(kernel) declaration has free variables 'stupid._nativeDecide_1'
Any idea what this means / how to fix it?
Alex Meiburg (Mar 15 2024 at 21:07):
Best I can find is that it comes from declHasFVars
in the kernel, which comes from a declaration_has_free_vars_exception
in C, which comes from check_no_metavar_no_fvar
(which is only caller of check_no_fvar
).
Mario Carneiro (Mar 15 2024 at 22:26):
Lean can't evaluate your decidable instance because it is a local variable in that context. If you lift it to a separate definition then it should work
Alex Meiburg (Mar 15 2024 at 22:27):
Oh, huh. Is this related to the fact that theorems are opaque? Like somehow native_decide doesn't "pass on" the relevant details to the kernel?
Mario Carneiro (Mar 15 2024 at 22:27):
native_decide
only works when (inferInstance : Decidable <your_goal>)
results in a proof with no free variables
Mario Carneiro (Mar 15 2024 at 22:28):
which can therefore be sent to the compiler
Mario Carneiro (Mar 15 2024 at 22:28):
it's the same reason that
variable (a : Nat)
#eval a
doesn't work
Alex Meiburg (Mar 15 2024 at 22:28):
Interesting. Alright! Maybe worth mentioning in the docstring for native_decide (or a clearer error message?) I was banging my head on this for fifteen minutes and wouldn't have guessed that :)
Thanks!
Mario Carneiro (Mar 15 2024 at 22:29):
yeah no that's a really bad error message, you should report it
Mario Carneiro (Mar 15 2024 at 22:31):
Normally this is a point where I would point out that you've used have
where you really should have used let
, but in this case I think that won't be good enough because the code in question is not smart enough to unfold let variables before the free variable check
Alex Meiburg (Mar 15 2024 at 22:32):
Yeah,
theorem stupid : IsLeast {s | true} 0 := by
let inst : Decidable (IsLeast {s | true} 0 ) := by
apply isTrue
simp
native_decide
has the same message
Last updated: May 02 2025 at 03:31 UTC