Skip to content

feat: bound kernel recursion by maxRecDepth#13956

Open
Kha wants to merge 3 commits into
leanprover:masterfrom
Kha:push-suozorvvkkpz
Open

feat: bound kernel recursion by maxRecDepth#13956
Kha wants to merge 3 commits into
leanprover:masterfrom
Kha:push-suozorvvkkpz

Conversation

@Kha

@Kha Kha commented Jun 4, 2026

Copy link
Copy Markdown
Member

This PR makes the kernel's (kernel) deep recursion detected error deterministic by bounding kernel type checking with the existing maxRecDepth option instead of the physical stack size. The limit previously depended on the native stack, so it varied across platforms, builds, and optimization levels and could not be reproduced reliably; it is now a function of maxRecDepth alone and is raised the usual way with set_option maxRecDepth <num>.

To avoid rejecting existing code that already fits within maxRecDepth during elaboration, the kernel is allowed to recurse up to a fixed multiple (currently 16×) of the configured value before reporting deep recursion; this is sufficient for lean4/Mathlib to build. Since the absolute value of maxRecDepth has no inherent meaning, this multiplier should not lead to surprising behavior.

The value is threaded to the kernel entry points (lean_add_decl, lean_elab_add_decl) alongside maxHeartbeats and tracked with a thread-local recursion-depth counter checked at the type checker's recursive entry points (infer, whnf, isDefEq). The former physical-stack-based budget in the structural Expr comparison is removed. The standalone debugging entry points Kernel.check / Kernel.whnf / Kernel.isDefEq remain unbounded.

This PR also improves the decide +kernel failure report: when the kernel rejects the proof and the tactic's lazy diagnostic itself exceeds maxRecDepth while re-reducing the instance, the tactic now surfaces the kernel's actual error (using tryCatchRuntimeEx, since maxRecDepth is a runtime exception that ordinary try/catch re-raises) instead of an opaque [Error pretty printing: …].

Finally, a couple of kernel-heavy benchmarks that legitimately recurse deeply gain an explicit maxRecDepth (string_simp_ne's O(n) String.ofList verification), and a new test pins the deterministic, option-controlled behavior.

Kha and others added 2 commits June 4, 2026 10:11
This PR makes the kernel type checker bound its recursion depth using the existing `maxRecDepth` option instead of measuring physical stack space. Previously the kernel relied on a non-deterministic stack-space check that varied by platform, build, and optimization, making `(kernel) deep recursion detected` errors irreproducible. The limit is now deterministic and adjustable with `set_option maxRecDepth`.

The `maxRecDepth` value is threaded to the kernel entry points (`lean_add_decl`, `lean_elab_add_decl`) alongside `maxHeartbeats` and tracked via a thread-local recursion-depth counter (`scope_max_rec_depth` / `scope_rec_depth`) checked at the type checker's recursive entry points. The stack-based limit in `expr_eq_fn` is removed, and the `.deepRecursion` message now points at `maxRecDepth`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Kha Kha requested review from kim-em and leodemoura as code owners June 4, 2026 11:39
@Kha

Kha commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Jun 4, 2026

Copy link
Copy Markdown

Benchmark results for 183982a against c47a0c7 are in. There are significant results. @Kha

  • 🟥 build exited with code 1
  • 🟥 other exited with code 1

No significant changes detected.

@Kha Kha added the changelog-language Language features and metaprograms label Jun 4, 2026
@github-actions github-actions Bot added the toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN label Jun 4, 2026
@leanprover-bot

Copy link
Copy Markdown
Collaborator

Reference manual CI status:

  • ❗ Reference manual CI can not be attempted yet, as the nightly-testing-2026-05-28 tag does not exist there yet. We will retry when you push more commits. If you rebase your branch onto nightly-with-manual, reference manual CI should run now. You can force reference manual CI using the force-manual-ci label. (2026-06-04 12:23:02)

@github-actions github-actions Bot added the mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN label Jun 4, 2026
@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added the breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan label Jun 4, 2026
@mathlib-lean-pr-testing

mathlib-lean-pr-testing Bot commented Jun 4, 2026

Copy link
Copy Markdown

Mathlib CI status (docs):

This PR lets the kernel recurse up to 16 times the configured `maxRecDepth` before reporting deep recursion. The kernel re-checks a fully elaborated term from scratch, without the caching, metavariable assignments, and reducibility shortcuts the elaborator relies on while building it, so it bottoms out substantially deeper than elaboration did for the same term; without this headroom, code that fits within `maxRecDepth` during elaboration -- including stdlib `grind`/`simp` proofs -- could be rejected by the kernel.

Adjust the kernel-heavy benchmarks accordingly: `string_simp_ne` needs a higher `maxRecDepth` for its O(n) `String.ofList` verification, while `bv_decide_rewriter` no longer needs its earlier bump. Also fix a stray trailing CRLF in the `identifier_completion` LSP fixture that desynced the message stream.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Kha

Kha commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

!bench

@leanprover-radar

leanprover-radar commented Jun 5, 2026

Copy link
Copy Markdown

Benchmark results for 62082bb against c47a0c7 are in. There are significant results. @Kha

  • build//instructions: -8.9G (-0.08%)

Large changes (2✅)

  • elab/big_omega//instructions: -507.3M (-2.35%)
  • elab/big_omega_MT//instructions: -510.4M (-2.35%)

Small changes (20✅, 1🟥)

Too many entries to display here. View the full report on radar instead.

mathlib-nightly-testing Bot pushed a commit to leanprover-community/batteries that referenced this pull request Jun 5, 2026
mathlib-nightly-testing Bot pushed a commit to leanprover-community/mathlib4-nightly-testing that referenced this pull request Jun 5, 2026
@leanprover-radar

Copy link
Copy Markdown

Benchmark results for 62082bb against c47a0c7 are in. (These commits have already been benchmarked in a previous command.) There are significant results. @Kha

  • build//instructions: -8.9G (-0.08%)

Large changes (2✅)

  • elab/big_omega//instructions: -507.3M (-2.35%)
  • elab/big_omega_MT//instructions: -510.4M (-2.35%)

Small changes (20✅, 1🟥)

Too many entries to display here. View the full report on radar instead.

@Kha

Kha commented Jun 5, 2026

Copy link
Copy Markdown
Member Author

!bench mathlib

@leanprover-radar

leanprover-radar commented Jun 5, 2026

Copy link
Copy Markdown

Benchmark results for leanprover-community/mathlib4-nightly-testing@49f5b1e against leanprover-community/mathlib4-nightly-testing@8a9ccb2 are in. No significant results found. @Kha

  • 🟥 build//instructions: +121.0G (+0.07%)

Small changes (2🟥)

  • 🟥 build/module/Mathlib.Lean.Environment//instructions: +89.4M (+5.37%)
  • 🟥 build/profile/initialization//wall-clock: +10s (+4.04%)

@mathlib-lean-pr-testing mathlib-lean-pr-testing Bot added builds-mathlib CI has verified that Mathlib builds against this PR and removed breaks-mathlib This is not necessarily a blocker for merging: but there needs to be a plan labels Jun 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

builds-mathlib CI has verified that Mathlib builds against this PR changelog-language Language features and metaprograms mathlib4-nightly-available A branch for this PR exists at leanprover-community/mathlib4-nightly-testing:lean-pr-testing-NNNN toolchain-available A toolchain is available for this PR, at leanprover/lean4-pr-releases:pr-release-NNNN

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants