This PR replaces the `std::unordered_map`/`std::unordered_set` caches of the kernel's expression traversals (`replace`, `Expr.replace`, `Expr.instantiateLevelParams`, `expr_eq_fn`, `for_each_fn`, `instantiateMVars`) with small open-addressing tables. The first 16 slots are stored inline, so traversals that cache only a few subterms allocate no memory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
EOB
perf: use open-addressing caches in the kernel's expression traversals

This PR replaces the `std::unordered_map`/`std::unordered_set` caches of the kernel's expression traversals (`replace`, `Expr.replace`, `Expr.instantiateLevelParams`, `expr_eq_fn`, `for_each_fn`, `instantiateMVars`) with small open-addressing tables. The first 16 slots are stored inline, so traversals that cache only a few subterms allocate no memory.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 files changed