This PR extracts the functional (lambda) passed to `brecOn` in structural recursion into a named `_f` helper definition (e.g. `foo._f`), similar to how well-founded recursion uses `._unary`. This way the functional shows up with a helpful name in kernel diagnostics rather than as an anonymous lambda. The `_f` definition is added with `.abbrev` kernel reducibility hints and the `@[reducible]` elaborator attribute, so the kernel unfolds it eagerly after `brecOn` iota-reduces. For inductive predicates, the previous inline lambda behavior is kept. To ensure that parent definitions still get the correct reducibility height (since `getMaxHeight` ignores `.abbrev` definitions), each `_f`'s body height is registered via a new `defHeightOverrideExt` environment extension. `getMaxHeight` checks this extension for all definitions, making the height computation transparent to the extraction. This change improves code size (a bit). It may regress kernel reduction times, especially if a function defined by structural recursion is used in kernel reduction proofs on the hot path. Functions defined by structural recursion are not particularly fast to reduce anyways (due to the `.brecOn` construction), so already now it may be worth writing a kernel-reduction-friendly function manually (using the recursor directly, avoiding overloaded operations). This change will guide you in knowing which function to optimize. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
29 lines
1.1 KiB
Text
29 lines
1.1 KiB
Text
inductive Tree (α : Type _) : Type _
|
||
| leaf : α → Tree α
|
||
| branch : Tree α → Tree α → Tree α
|
||
|
||
inductive Path {α : Type _} : Tree α → Type _
|
||
| term (x : α) : Path (Tree.leaf x)
|
||
| left (tl tr : Tree α) : Path tl → Path (Tree.branch tl tr)
|
||
| right (tl tr : Tree α) : Path tr → Path (Tree.branch tl tr)
|
||
|
||
section map
|
||
variable {α : Type _} {β : Type _} (f : α → β)
|
||
|
||
protected def Tree.map : Tree α → Tree β
|
||
| Tree.leaf x => Tree.leaf (f x)
|
||
| Tree.branch tl tr => Tree.branch (Tree.map tl) (Tree.map tr)
|
||
|
||
protected def Path.map : {t : Tree α} → Path t → Path (t.map f)
|
||
| Tree.leaf _, Path.term x => Path.term (f x)
|
||
| Tree.branch _ _, Path.left tl tr p => Path.left (tl.map f) (tr.map f) (Path.map p)
|
||
| Tree.branch _ _, Path.right tl tr p => Path.right (tl.map f) (tr.map f) (Path.map p)
|
||
|
||
protected def Path.unmap : {t : Tree α} → Path (t.map f) → Path t
|
||
| Tree.leaf x, Path.term _ => Path.term x
|
||
| Tree.branch tl tr, Path.left _ _ p => Path.left tl tr (Path.unmap p)
|
||
| Tree.branch tl tr, Path.right _ _ p => Path.right tl tr (Path.unmap p)
|
||
|
||
#check @Path.unmap
|
||
|
||
end map
|