Skip to content

fix: emit variable declarations in single-hole workspaces#280

Merged
kim-em merged 1 commit into
mainfrom
issue-276
May 19, 2026
Merged

fix: emit variable declarations in single-hole workspaces#280
kim-em merged 1 commit into
mainfrom
issue-276

Conversation

@kim-em
Copy link
Copy Markdown
Collaborator

@kim-em kim-em commented May 19, 2026

This PR makes the extractor re-emit variable declarations in generated single-hole workspaces so a theorem that inherits binders from a preceding variable {n : Type*} [Fintype n] [DecidableEq n] declaration still type-checks under autoImplicit = false.

Closes #276.

The new extractContextVariables walks the source up to the theorem, tracking section/namespace/end frames and block-comment state, and collects every still-in-scope variable declaration (multi-line variables are kept by absorbing indented continuation lines). A variableShadowedByTheorem filter drops a variable whose named binders are all already explicit on the theorem, so existing @[eval_problem]s that inline binders (Gleason, etc.) do not pick up a redundant variable line that would trigger Lean's unused-variable linter.

There is a sandbox regression problem variable_binder_example whose theorem refers to a variable-introduced n, plus a closed section and a docstring mention of variable to exercise the scoping and block-comment handling.

🤖 Prepared with Claude Code

Before this fix, when an `@[eval_problem]` theorem inherited binders from
a preceding `variable {n : Type*} [Fintype n] [DecidableEq n]` declaration,
`lake exe lean-eval generate` would slice only the literal theorem source
between `theorem <name>` and `:= by` into `Challenge.lean` / `Solution.lean`
/ `Submission.lean`, dropping the surrounding `variable` lines. With
`autoImplicit = false` in the generated workspace, identifiers like `n`
were then unbound and the build failed.

The new `extractContextVariables` walks the source up to the theorem,
tracking `section`/`namespace`/`end` frames and block-comment state, and
collects every still-in-scope `variable` declaration (including multi-line
ones, kept by absorbing indented continuation lines). A
`variableShadowedByTheorem` filter drops a `variable` whose named binders
are all already explicit binders on the theorem, so existing
`@[eval_problem]`s that inline binders (Gleason, etc.) do not pick up a
redundant `variable` line that would trigger the unused-variable linter.

Includes a regression sandbox problem `variable_binder_example` whose
theorem refers to a variable-introduced `n`, plus a closed `section` and
a docstring mention of `variable` to exercise the scoping and
block-comment handling.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@kim-em kim-em merged commit 9a06713 into main May 19, 2026
1 check passed
@kim-em kim-em deleted the issue-276 branch May 19, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extractor drops variable binders, producing unbound identifiers in generated Challenge.lean

1 participant