fix: refuse to finalize spec when an assertion declaration failed to elaborate#17
Closed
hwbehrens wants to merge 1 commit into
Closed
Conversation
…elaborate An assertion whose body fails to elaborate is reported as an error but is not registered in the module. #gen_spec then finalized the specification without it and #check_invariants reported all green, silently omitting the property the user wrote. elabAssertion now records the names of failed assertion declarations, and Module.ensureSpecIsFinalized refuses to finalize while any exist. Since all checking commands require a finalized spec, nothing downstream can run against a specification that silently lost an assertion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
If an assertion's body fails to elaborate (say, a typo like a primed variable
C', or a capitalized variable that happens to resolve to an existing global), the declaration errors but the assertion is simply not registered in the module.#gen_specthen finalizes the specification without it, and#check_invariantsreports all green. The property the user wrote is silently gone; if the model has a bug that property would catch, the report still looks like a clean pass. On a small mutex model withsafety [mutual_exclusion] holds C ∧ holds C' → C = C':mutual_exclusionappears nowhere in the roster, and in a 40+ minute build log the lone error line is easy to lose while the wall of green reads as verified, which nearly bit me.This PR makes the failure impossible to miss.
elabAssertionrecords the names of assertion declarations that fail to elaborate, andModule.ensureSpecIsFinalizedrefuses to finalize the specification while any exist. Since#check_invariants,#check_action, trace commands, and#model_checkall require a finalized spec, nothing downstream can run against a specification that silently lost an assertion. Same model, after:The change is pretty small: a
_failedAssertions : Array Namefield onModule, a try/catch inelabAssertionthat records the name and rethrows, and the finalization gate.VeilTest/Regression/DroppedAssertion.leanguards both the declaration error and the new#gen_specerror. Fulllake build(Veil + VeilTest) passes.One design choice though: a recorded failure is not scrubbed if a later declaration with the same name succeeds; the broken declaration still has to be fixed or removed. Scrubbing would reopen the silent-omission path, since a later unrelated assertion reusing the name could mask the failed one.
Happy to adjust if needed, for instance a warning instead of a hard error, or reporting the dropped names in the
#check_invariantsoutput as well.