fix: make the Banach fixpoint opaque#498
Merged
Merged
Conversation
fixpointP packs fixpoint with its unfolding equation as one opaque subtype value; fastFixpoint projects out the point. The opaque constant is stuck for elaborator and kernel isDefEq alike, and fixpoint_unique transports the fixpoint API (fastFixpoint_unfold, fastFixpoint_eqv, fastFixpoint_unique, fastFixpoint_ne). Iris.Tests.Fixpoint exercises the API on a constant contraction over LeibnizO Nat.
fixpoint is now the value projection of the opaque fixpointP, which packs the fixpoint together with its unfolding equation as a Subtype; the chain construction lives on in fixpointAux. Both the elaborator and the kernel treat fixpoint as a stuck constant during definitional- equality checks, which keeps isDefEq out of the approximation chain. fixpoint_unfold is the property projection, fixpoint_ne is reproved from the unfolding equation, and the rest of the fixpoint API is unchanged. The regression test Iris.Tests.Fixpoint elaborates a failing-then- recovering unification between two applications of a hom-space fixpoint to different arguments under a maxHeartbeats 4000 cap; chain descent on that example exceeds even the default heartbeat budget.
Drop the constant-contraction API examples; the fixpoint API is already exercised by the rest of the testsuite. Rewrite the header comment to explain the failure mechanism: the failed exact unifies two applications of the same fixpoint to different arguments, a stuck constant fails that check at the arguments, while unfolding into the approximation chain doubles the reduction tree at every level with distinct arguments on each path, defeating the defeq cache. The maxHeartbeats 4000 cap makes any reintroduction of that unfolding a deterministic failure.
sgraf812
marked this pull request as ready for review
July 4, 2026 10:50
Kaptch
self-requested a review
July 5, 2026 11:30
2 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes a class of deterministic timeouts in
isDefEqchecks that involvefixpoint.The regression test
Iris.Tests.Fixpointshows the minimal shape: a contractionPhion the hom spaceSiProp -n> SiPropwhose body applies the recursive call to two different argument transformations, and a unification between(fixpoint Phi.f) P1and(fixpoint Phi.f) P2for syntactically differentP1,P2(a failedexactthat a subsequent tactic recovers from). WhenisDefEqcan unfoldfixpointintoCOFE.complof the approximation chain, the comparison only resolves after reducing both applications to theirTrue-leaf trees; the two recursive-call arguments give every path through the unfolding a distinct argument, so the defeq cache cannot collapse the descent, and at step index 24 the single failed unification exceeds even the defaultmaxHeartbeatsbudget. The same mechanism measured in a downstream development (a guarded recursive-domain interpreter):Fixpoint.chainiterations x77-295 and tens of thousands of projection unfolds per goal, ending in deterministic timeouts.The fix follows #497's treatment of
Tower.iso:fixpointP f : { x : α // x ≡ f x }packs the fixpoint together with its unfolding equation as a singleopaquevalue, with the chain construction kept infixpointAux.fixpointandfixpoint_unfoldare its two projections, so both the elaborator and the kernel treatfixpointas a stuck constant: the failed unification above is detected at the arguments, within amaxHeartbeats 4000cap that turns any reintroduction of chain descent into a deterministic timeout.fixpoint_neis reproved fromfixpoint_unfold; every otherfixpointlemma (fixpoint_unique,fixpoint_ind, thefixpointABfamily) already lived on the API and is untouched. All statements are unchanged.As in the #497 test, the test file is deliberately not a
module(non-module importers ignore module-system annotations such as@[expose], soopaqueis what sealsfixpointfor them, and the file checks the seal from such an importer; theIrisTestglob builds it), andPhi's proof fields aresorry(silenced): unification only ever touches the data.Verified in both directions: replacing
fixpointby the chain-basedfixpointAuxin the regression example reproduces the deterministic timeout at the 4000 cap (and still at 200000); with the opaque packing it passes under a 400 cap.Checklist
authorssection of any appropriate files