lean4-htt/src/Lean/Meta
Leonardo de Moura d57f71c1c0
perf: optimize kernel type-checking for have-telescope simplification in Sym.simp (#11967)
This PR implements a new strategy for simplifying `have`-telescopes in
`Sym.simp` that achieves linear kernel type-checking time instead of
quadratic.

## Problem

When simplifying deep `have`-telescopes, the previous approach using
`have_congr'` produced proofs that type-checked in quadratic time. The
simplifier itself was fast, but the kernel became the bottleneck for
large telescopes.

For example, at n=100:
- **Before**: simp = 2.4ms, kernel = **225ms**
- **After**: simp = 3.5ms, kernel = **10ms**

The quadratic behavior occurred because the kernel creates fresh free
variables for each binder when type-checking, destroying sharing and
producing O(n²) intermediate terms.

## Solution

We transform sequential `have`-telescopes into a parallel
beta-application form:

```
have x₁ := v₁; have x₂ := v₂[x₁]; b[x₁, x₂]
  ↓ (definitionally equal)
(fun x₁ x₂' => b[x₁, x₂' x₁]) v₁ (fun x₁ => v₂[x₁])
```

This parallel form leverages the efficient simplifier for lambdas in
`Sym.simp`. This form enables:
1. Independent simplification of each argument
2. Proof construction using standard congruence lemmas
3. Linear kernel type-checking time

The algorithm has three phases:
1. **`toBetaApp`**: Transform telescope → parallel beta-application
2. **`simpBetaApp`**: Simplify using `congr`/`congrArg`/`congrFun'` and
`simpLambda`
3. **`toHave`**: Convert back to `have` form

## Benchmark Results

### Benchmark 1: Chain with all variables used in body

| n | Before (simp) | Before (kernel) | After (simp) | After (kernel) |
|---|---------------|-----------------|--------------|----------------|
| 50 | 1.2ms | 32ms | 1.6ms | 4.4ms |
| 100 | 2.4ms | **225ms** | 3.5ms | **10ms** |
| 200 | 4.5ms | — | 8.4ms | 27ms |
| 500 | 11.7ms | — | 33.6ms | 128ms |

### Benchmark 3: Parallel declarations (simplified values)

| n | Before (simp) | Before (kernel) | After (simp) | After (kernel) |
|---|---------------|-----------------|--------------|----------------|
| 50 | 0.5ms | 24ms | 0.8ms | 1.8ms |
| 100 | 1.2ms | **169ms** | 1.8ms | **5.3ms** |
| 200 | 2.2ms | — | 3.9ms | 17ms |
| 500 | 5.9ms | — | 12.3ms | 93ms |

### Benchmark 5: Chain with single dependency

| n | Before (simp) | Before (kernel) | After (simp) | After (kernel) |
|---|---------------|-----------------|--------------|----------------|
| 100 | 1.6ms | 6.2ms | 1.8ms | 6.2ms |
| 200 | 2.8ms | 21.6ms | 4.4ms | 16.5ms |
| 500 | 7.3ms | **125ms** | 12.8ms | **72ms** |

Key observations:
- Kernel time is now **linear** in telescope depth (previously
quadratic)
- Simp time increases slightly due to the transformation overhead
- Total time (simp + kernel) is dramatically reduced for large
telescopes
- The improvement is most pronounced when the body depends on many
variables

## Trade-offs

- Proof sizes are larger (more congruence lemma applications)
- Simp time has ~1.5x overhead from the transformation
- For very small telescopes (n < 10), the overhead may not pay off

The optimization targets the critical path: kernel type-checking was the
bottleneck preventing scaling to realistic symbolic simulation
workloads.
2026-01-11 02:20:47 +00:00
..
ArgsPacker refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
Constructions refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
DiscrTree feat: add insertPattern for discrimination tree insertion in Sym (#11884) 2026-01-03 19:27:43 +00:00
Match chore: extract shared match splitting impl from FunInd and mvcgen (#11953) 2026-01-09 15:53:26 +00:00
Sym perf: optimize kernel type-checking for have-telescope simplification in Sym.simp (#11967) 2026-01-11 02:20:47 +00:00
Tactic chore: extract shared match splitting impl from FunInd and mvcgen (#11953) 2026-01-09 15:53:26 +00:00
AbstractMVars.lean fix: instantiate mvars in types of mvars in abstractMVars (#10612) 2025-09-29 16:33:10 +00:00
AbstractNestedProofs.lean chore: more module system fixes and improvements from Mathlib porting (#10655) 2025-10-08 11:30:09 +00:00
ACLt.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
AppBuilder.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
ArgsPacker.lean feat: Add List.zipWithM and Array.zipWithM (#9528) 2025-07-28 08:39:52 +00:00
Basic.lean chore: revert "feat: abstract metavariables when generalizing match motives (#8099)" (#11941) 2026-01-09 08:24:03 +00:00
BinderNameHint.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Canonicalizer.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
CasesInfo.lean chore: fix spelling (#11531) 2025-12-06 13:54:27 +00:00
Check.lean fix: deep recursion type checking grind proof (#11061) 2025-11-02 19:43:48 +00:00
CheckTactic.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
Closure.lean chore: add an assertion about mkValueTypeClosure (#10954) 2025-10-25 12:59:17 +00:00
Coe.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
CoeAttr.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
CollectFVars.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
CollectMVars.lean feat: split out Expr.getMVarDependencies from MVarId.getMVarDependencies (#9785) 2025-08-08 00:28:30 +00:00
CompletionName.lean refactor: move operations on String.Pos.Raw to the String.Pos.Raw namespace (#10735) 2025-10-18 12:12:55 +00:00
CongrTheorems.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
Constructions.lean feat: sparse sparse casesOn splitting in match equations (#11666) 2025-12-14 14:59:45 +00:00
CtorIdxHInj.lean feat: grind support for .ctorIdx (#11652) 2025-12-13 13:32:19 +00:00
CtorRecognizer.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
DecLevel.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Diagnostics.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
DiscrTree.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
Eqns.lean chore: fix spelling (#11531) 2025-12-06 13:54:27 +00:00
Eval.lean fix: #guard should work with the module system (#10535) 2025-09-24 07:38:10 +00:00
ExprDefEq.lean chore: remove leftover (#11895) 2026-01-04 21:42:13 +00:00
ExprLens.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
ExprTraverse.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
ForEachExpr.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
FunInfo.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
GeneralizeTelescope.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
GeneralizeVars.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
GetUnfoldableConst.lean feat: add TransparencyMode.none (#11810) 2025-12-27 03:10:17 +00:00
GlobalInstances.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
HasNotBit.lean perf: use Nat-based bitmask in sparse cases construction (#11200) 2025-11-17 10:05:18 +00:00
HaveTelescope.lean feat: add option for simplifying have decls in two passes (#11923) 2026-01-07 01:58:36 +00:00
Hint.lean chore: rename Substring to Substring.Raw (#11154) 2025-11-16 09:30:04 +00:00
IndPredBelow.lean chore: fix spelling (#11531) 2025-12-06 13:54:27 +00:00
Inductive.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
InferType.lean feat: add Meta.Context.cacheInferType (#11869) 2026-01-02 03:21:43 +00:00
Injective.lean feat: make noConfusion even more heterogeneous 2025-12-10 17:28:06 +01:00
Instances.lean feat: add insertPattern for discrimination tree insertion in Sym (#11884) 2026-01-03 19:27:43 +00:00
IntInstTesters.lean fix: nonstandard instances in grind and simp +arith (#11758) 2025-12-21 17:56:49 +00:00
Iterator.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
KAbstract.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
KExprMap.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
LazyDiscrTree.lean fix: allow exact? to suggest local private declarations (part 2) (#11759) 2025-12-21 20:03:10 +00:00
LetToHave.lean chore: fix spelling errors (#10042) 2025-08-22 07:23:12 +00:00
LevelDefEq.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
LitValues.lean feat: support for Rat scientific literals (#10961) 2025-10-26 02:05:26 +00:00
Match.lean refactor: module-ize Lean (#9330) 2025-07-25 12:02:51 +00:00
MatchUtil.lean refactor: make MatchEqs a leaf module (#11493) 2025-12-03 09:15:36 +00:00
MethodSpecs.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
MkIffOfInductiveProp.lean chore: minor optimizations on the critical path (#10900) 2025-10-22 19:32:26 +00:00
MonadSimp.lean refactor: have telescope support (#11914) 2026-01-06 19:20:25 +00:00
NatInstTesters.lean fix: nonstandard instances in grind and simp +arith (#11758) 2025-12-21 17:56:49 +00:00
NatTable.lean chore: fix spelling errors (#10042) 2025-08-22 07:23:12 +00:00
Offset.lean fix: nonstandard instances in grind and simp +arith (#11758) 2025-12-21 17:56:49 +00:00
Order.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
PPGoal.lean chore: do not set unused Option.Decl.group (#11307) 2025-11-21 16:44:38 +00:00
PProdN.lean fix: complete overhaul of structural recursion on inductives predicates (#9995) 2025-09-01 08:17:58 +00:00
ProdN.lean feat: new do elaborator, part 1: doElem_elab attribute (#11150) 2025-11-12 14:25:28 +00:00
RecursorInfo.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
Reduce.lean chore: remove redundant imports in core (#10750) 2025-10-16 20:27:46 +00:00
ReduceEval.lean feat: upstream ReduceEval instances from quote4 (#10563) 2025-09-26 04:02:55 +00:00
SameCtorUtils.lean refactor: introduce SameCtorUtils (#10316) 2025-09-10 14:32:58 +00:00
SizeOf.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
Sorry.lean feat: pretty print sorry in "declaration uses 'sorry'" (#10034) 2025-09-08 12:14:42 +00:00
SplitSparseCasesOn.lean feat: sparse sparse casesOn splitting in match equations (#11666) 2025-12-14 14:59:45 +00:00
Structure.lean refactor: DiscrTree (#11875) 2026-01-02 19:53:45 +00:00
Sym.lean refactor: reorganize SymM and GrindM monad hierarchy (#11909) 2026-01-06 01:12:07 +00:00
SynthInstance.lean feat: remove the group field of an option description (#11305) 2025-11-24 11:40:58 +00:00
Tactic.lean chore: remove public section from end of files (#10684) 2025-10-06 13:30:48 +00:00
Transform.lean chore: fix spelling (#11531) 2025-12-06 13:54:27 +00:00
TransparencyMode.lean feat: add TransparencyMode.none (#11810) 2025-12-27 03:10:17 +00:00
TryThis.lean chore: rename String.ValidPos to String.Pos (#11240) 2025-11-24 16:40:21 +00:00
UnificationHint.lean feat: add insertPattern for discrimination tree insertion in Sym (#11884) 2026-01-03 19:27:43 +00:00
WHNF.lean perf: do not consult isNoConfusion in whnf (#11571) 2025-12-09 23:36:46 +00:00