fix: prevent cbv crash on dependent projections with @[cbv_eval] rewrites (#12612)
This PR fixes a crash in the `cbv` tactic's `handleProj` simproc when processing a dependent projection (e.g. `Sigma.snd`) whose struct is rewritten via `@[cbv_eval]` to a non-definitionally-equal term that cannot be further reduced. - Previously, `handleProj` returned `.rfl (done := false)`, causing the `.proj` expression to flow into `simpStep` which throws "unexpected kernel projection term" - The fix marks the result as `done := true` so that `cbv` gracefully gets stuck instead of crashing - Adds regression tests for dependent projections on `Sigma`, custom structures, and `Subtype` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
78df48bdf4
commit
14e1d4328f
2 changed files with 74 additions and 1 deletions
|
|
@ -121,7 +121,7 @@ def handleProj : Simproc := fun e => do
|
|||
unless (← isDefEq struct e') do
|
||||
-- If we rewrote the projection body using something that holds up to propositional equality, then there is nothing we can do.
|
||||
-- TODO: Check if there is a need to report this to a user, or shall we fail silently.
|
||||
return .rfl
|
||||
return .rfl (done := true)
|
||||
let hcongr ← mkHCongr congrArgFun
|
||||
let newProof := mkApp3 (hcongr.proof) struct e' proof
|
||||
-- We have already checked if `struct` and `e'` are defEq, so we can skip the check.
|
||||
|
|
|
|||
73
tests/lean/run/cbv_dep_proj.lean
Normal file
73
tests/lean/run/cbv_dep_proj.lean
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
set_option cbv.warning false
|
||||
|
||||
/-! Tests for `cbv` handling of dependent projections.
|
||||
|
||||
When a struct is rewritten (e.g. via `@[cbv_eval]`) but the projection is
|
||||
dependent and the original struct can't be reduced, `cbv` should gracefully
|
||||
get stuck rather than crash.
|
||||
-/
|
||||
|
||||
-- Sigma: .1 is non-dependent, .2 is dependent
|
||||
def myPair : Σ n : Nat, Fin (n + 1) := ⟨5, ⟨3, by omega⟩⟩
|
||||
axiom otherPair : Σ n : Nat, Fin (n + 1)
|
||||
@[cbv_eval ←] axiom otherPair_eq : myPair = otherPair
|
||||
|
||||
example : otherPair.1 = 5 := by cbv
|
||||
|
||||
/--
|
||||
error: unsolved goals
|
||||
⊢ otherPair.2.1 = 3
|
||||
-/
|
||||
#guard_msgs in
|
||||
example : otherPair.2.val = 3 := by cbv
|
||||
|
||||
-- Custom structure with a dependent field
|
||||
structure DepPkg where
|
||||
n : Nat
|
||||
val : Fin (n + 1)
|
||||
|
||||
def concretePkg : DepPkg := ⟨5, ⟨3, by omega⟩⟩
|
||||
axiom opaquePkg : DepPkg
|
||||
@[cbv_eval ←] axiom opaquePkg_eq : concretePkg = opaquePkg
|
||||
|
||||
example : opaquePkg.n = 5 := by cbv
|
||||
|
||||
/--
|
||||
error: unsolved goals
|
||||
⊢ opaquePkg.2.1 = 3
|
||||
-/
|
||||
#guard_msgs in
|
||||
example : opaquePkg.val.val = 3 := by cbv
|
||||
|
||||
-- Subtype: .val is non-dependent, so the rewrite goes through
|
||||
def concreteSubtype : { n : Nat // n > 0 } := ⟨5, by omega⟩
|
||||
axiom opaqueSubtype : { n : Nat // n > 0 }
|
||||
@[cbv_eval ←] axiom opaqueSubtype_eq : concreteSubtype = opaqueSubtype
|
||||
|
||||
example : opaqueSubtype.val = 5 := by cbv
|
||||
|
||||
-- Non-dependent projections: function projected from a structure and applied
|
||||
structure FnStruct where
|
||||
fn : Nat → Nat
|
||||
|
||||
def myFnStruct : FnStruct := ⟨fun n => n + 1⟩
|
||||
example : myFnStruct.fn 5 = 6 := by cbv
|
||||
|
||||
-- Nested non-dependent projections
|
||||
structure Layer1 where val : Nat
|
||||
structure Layer2 where inner : Layer1
|
||||
structure Layer3 where inner : Layer2
|
||||
|
||||
def nested : Layer3 := ⟨⟨⟨42⟩⟩⟩
|
||||
example : nested.inner.inner.val = 42 := by cbv
|
||||
|
||||
-- Double projection through a product
|
||||
structure FnPairS where
|
||||
fst : Nat → Nat
|
||||
snd : Nat → Nat
|
||||
|
||||
def fnPairPair : FnPairS × FnPairS :=
|
||||
(⟨fun n => n + 1, fun n => n + 2⟩, ⟨fun n => n + 3, fun n => n + 4⟩)
|
||||
|
||||
example : fnPairPair.1.fst 5 = 6 := by cbv
|
||||
example : fnPairPair.2.snd 5 = 9 := by cbv
|
||||
Loading…
Add table
Reference in a new issue