Zulip Chat Archive
Stream: general
Topic: unable to get definition constants in enviroment
Frederick Pu (Feb 02 2026 at 19:42):
when running this
unsafe def main : IO Unit := do
let input ← IO.FS.readFile "testfile.lean"
let fileMap := FileMap.ofString input
let inputCtx := Parser.mkInputContext input fileName.toString
let (header, parserState, messages) ← Parser.parseHeader inputCtx
let (env, messages) ← processHeader header {} messages inputCtx
let imports := env.imports
let commandState := Command.mkState env messages
let s ← IO.processCommands inputCtx parserState { commandState with infoState.enabled := true }
let envAfter := s.commandState.env
IO.println (envAfter.constants.toList.map (·.1))
as an executable (with supportInterpreter := true), I'm only able to get the constants for the inductive types and not the constants for definitions in the file
Aaron Liu (Feb 02 2026 at 19:45):
what's in the testfile.lean
Frederick Pu (Feb 02 2026 at 19:46):
inductive MyNat where
| zero : MyNat
| succ : MyNat -> MyNat
def somefun (x : Nat) : Nat := 2 * x
Frederick Pu (Feb 02 2026 at 19:46):
the constants for MyNat are showing up but not somefun
Frederick Pu (Feb 02 2026 at 19:47):
and what's weirder is that if you do #eval (do let env ← getEnv; IO.println (env.constants.toList.map (·.1)) : Lean.MetaM Unit) in testfile.lean the somefun will actually show up
Aaron Liu (Feb 02 2026 at 19:50):
what if you use MyNat instead of Nat in the definition of somefun
Aaron Liu (Feb 02 2026 at 19:51):
of course the contents will have to be something other than 2 * x (since multiplication isn't defined on MyNat)
Frederick Pu (Feb 02 2026 at 19:58):
i dont think that wiill solve it sinc ethe issue is that somefun will get garbage collected
Frederick Pu (Feb 02 2026 at 20:15):
yeah it doesn't fixx it
Aaron Liu (Feb 02 2026 at 20:20):
ok I'll have a look later when I can run this locally
Sebastian Ullrich (Feb 02 2026 at 20:25):
Are you sure the messages are in fact empty?
Sebastian Ullrich (Feb 02 2026 at 20:26):
Of s as well
Frederick Pu (Feb 02 2026 at 21:20):
i dont see any messages
Frederick Pu (Feb 02 2026 at 21:21):
when i print them
Frederick Pu (Feb 03 2026 at 04:36):
i just realized the mwe i gave earlier doesnt compile. Please refer to this one:
import Lean
open Lean Meta Elab Core
unsafe def main : IO Unit := do
let input ← IO.FS.readFile "testfile.lean"
let fileMap := FileMap.ofString input
let inputCtx := Parser.mkInputContext input "testfile.lean"
let (header, parserState, messages) ← Parser.parseHeader inputCtx
let (env, messages) ← processHeader header {} messages inputCtx
let imports := env.imports
let commandState := Command.mkState env messages
let s ← IO.processCommands inputCtx parserState { commandState with infoState.enabled := true }
let envAfter := s.commandState.env
IO.println (envAfter.constants.toList.map (·.1))
Frederick Pu (Feb 03 2026 at 04:36):
lakefile:
lean_exe mwe where
root := `Tactic.MWE
supportInterpreter := true
Frederick Pu (Feb 03 2026 at 04:36):
and testfile.lean:
inductive MyNat where
| zero : MyNat
| succ : MyNat -> MyNat
def somefun (x : Nat) : Nat := 2 * x
Frederick Pu (Feb 03 2026 at 04:37):
and running lake env .lake/build/bin/mwe
James E Hanson (Feb 03 2026 at 05:00):
Frederick Pu said:
i just realized the mwe i gave earlier doesnt compile. Please refer to this one:
import Lean open Lean Meta Elab Core unsafe def main : IO Unit := do let input ← IO.FS.readFile "testfile.lean" let fileMap := FileMap.ofString input let inputCtx := Parser.mkInputContext input "testfile.lean" let (header, parserState, messages) ← Parser.parseHeader inputCtx let (env, messages) ← processHeader header {} messages inputCtx let imports := env.imports let commandState := Command.mkState env messages let s ← IO.processCommands inputCtx parserState { commandState with infoState.enabled := true } let envAfter := s.commandState.env IO.println (envAfter.constants.toList.map (·.1))
You're not doing anything with fileMap anymore. Is that intentional?
Frederick Pu (Feb 03 2026 at 06:07):
oh yeah i was using the filemap for somethine else in my main script
Frederick Pu (Feb 03 2026 at 06:07):
but not relevant for mwe
Frederick Pu (Feb 03 2026 at 06:08):
also for some reason this works as intended:
import Lean
open Lean Elab Meta
def somefun (x y : Nat) : Nat := x + y
#eval (do let env ← getEnv; let mm := env.getModuleIdx? env.mainModule; IO.println (((← getEnv).constants.toList.map (·.1)).filter (fun x => env.getModuleIdxFor? x == mm)): MetaM Unit)
Frederick Pu (Feb 03 2026 at 06:08):
but the corresponding version with executable doesn't work
Frederick Pu (Feb 03 2026 at 06:08):
also the let imports := env.imports is not used either
Frederick Pu (Feb 03 2026 at 06:09):
so ig an even more minified version would be:
import Lean
open Lean Meta Elab Core
unsafe def main : IO Unit := do
let input ← IO.FS.readFile "testfile.lean"
let inputCtx := Parser.mkInputContext input "testfile.lean"
let (header, parserState, messages) ← Parser.parseHeader inputCtx
let (env, messages) ← processHeader header {} messages inputCtx
let commandState := Command.mkState env messages
let s ← IO.processCommands inputCtx parserState { commandState with infoState.enabled := true }
let envAfter := s.commandState.env
IO.println (envAfter.constants.toList.map (·.1))
Frederick Pu (Feb 03 2026 at 16:37):
so it turns out I just had to do Lean.initSearchPath (← Lean.findSysroot) at the start
Frederick Pu (Feb 03 2026 at 16:38):
but now i'm getting issue where if testfile.lean has a compilation error i can't catch it:
inductive MyNat where
| zero : MyNat
| succ : MyNat -> MyNat
theorem womp : + 2 = 4 := by sorry
def somefun (x : Nat) : Nat := 2 * x
Frederick Pu (Feb 03 2026 at 16:38):
even when printing messages i don't get anything:
import Lean
open Lean Meta Elab Core
unsafe def main : IO Unit := do
Lean.initSearchPath (← Lean.findSysroot)
enableInitializersExecution
let input ← IO.FS.readFile "testfile.lean"
let fileMap := FileMap.ofString input
let inputCtx := Parser.mkInputContext input "testfile.lean"
let (header, parserState, messages) ← Parser.parseHeader inputCtx
let (env, messages) ← processHeader header {} messages inputCtx
IO.println (messages.toArray.map (·.caption))
let imports := env.imports
let commandState := Command.mkState env messages
let s ← IO.processCommands inputCtx parserState { commandState with infoState.enabled := true } <&> Frontend.State.commandState
IO.println (s.messages.toArray.map (·.caption))
let envAfter := s.env
-- IO.println (env.constants.toList.map (·.1))
let mm := env.getModuleIdx? env.mainModule;
IO.println ((envAfter.constants.toList.map (·.1)).filter (fun x => env.getModuleIdxFor? x == mm))
Last updated: Feb 28 2026 at 14:05 UTC