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