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>
33 lines
840 B
Text
33 lines
840 B
Text
|
|
|
|
open Nat
|
|
|
|
inductive BV : Nat → Type
|
|
| nil : BV 0
|
|
| cons : ∀ (n) (hd : Bool) (tl : BV n), BV (succ n)
|
|
|
|
open BV
|
|
|
|
variable (f : Bool → Bool → Bool)
|
|
|
|
def map2 : {n : Nat} → BV n → BV n → BV n
|
|
| .(0), nil, nil => nil
|
|
| .(n+1), cons n b1 v1, cons .(n) b2 v2 => cons n (f b1 b2) (map2 v1 v2)
|
|
|
|
theorem ex1 : map2 f nil nil = nil :=
|
|
rfl
|
|
|
|
theorem ex2 (n : Nat) (b1 b2 : Bool) (v1 v2 : BV n) : map2 f (cons n b1 v1) (cons n b2 v2) = cons n (f b1 b2) (map2 f v1 v2) :=
|
|
rfl
|
|
|
|
#check @map2
|
|
|
|
def map2' : {n : Nat} → BV n → BV n → BV n
|
|
| _, nil, nil => nil
|
|
| _, cons _ b1 v1, cons _ b2 v2 => cons _ (f b1 b2) (map2' v1 v2)
|
|
|
|
theorem ex3 : map2' f nil nil = nil :=
|
|
rfl
|
|
|
|
theorem ex4 (n : Nat) (b1 b2 : Bool) (v1 v2 : BV n) : map2' f (cons n b1 v1) (cons n b2 v2) = cons n (f b1 b2) (map2' f v1 v2) :=
|
|
rfl
|