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