Skip to content

Add contract and transparency pass#16

Closed
keyboardDrummer wants to merge 329 commits into
mainfrom
issue-924-contract-and-proof-pass
Closed

Add contract and transparency pass#16
keyboardDrummer wants to merge 329 commits into
mainfrom
issue-924-contract-and-proof-pass

Conversation

@keyboardDrummer
Copy link
Copy Markdown
Owner

@keyboardDrummer keyboardDrummer commented Apr 21, 2026

Builds on:

No longer, maybe we can close this:

Summary

Add these passes:

  • [New] EliminateReturnStatements: rewrite return to exit statements, needed for the next pass.
  • [New] ContractPass: translate away pre and postconditions entirely by introducing assertion and assumptions at call sites and at procedure starts and ends
  • [New] TransparencyPass: for each Core procedure, generate a function with the same signature and name suffixed with $asFunction. If a Core procedure is marked as transparent, attempt to generate a functional version of it, where assertions are erased and all calls are to functional versions. Tie the functional version to the procedure using a free postcondition.
  • [Existing] Lift assertions, assumptions and procedure calls when they occur in expressions.
  • [Follow-up] AxiomatizeExpressionAssumptionsPass: erase assumptions in Core function expressions by introducing functions and axioms.

The effect of the contract and transparency pass:

  1. Allow postconditions on functions
  2. Allow calling procedures from contracts
  3. Improve diagnostics related to contracts, using the correct verbiage "precondition" and "postcondition" instead of "assertion"
  4. Allow transparent procedures IF they have an expression body
  5. Allow assertions in transparent procedures and functions

The combined effect of 2 and 4 is that there is no more difference between Laurel functions and transparent procedures.

TODO

  • Differentiate between bugs and user errors in LaurelToCoreTranslator translateExpr
  • Add a free postcondition to the Core procedure to tie it to its functional counterpart.
  • Lift all calls inside expressions in Core procedure bodies, since they are calls to procedures and are not allowed.
  • Let all remaining calls from expressions - which is all calls in Core functions, and all calls in the free procedure postconditions - be to Core functions, and other calls to procedures.
  • Rename FunctionsAndProofsProgram to UnorderedCoreWithLaurelTypes and FunctionsAndProof.lean to TransparencyPass.lean

Follow-up work

  • Remove the 'functional' keyword from the Laurel grammar
  • Lift assumptions in expressions to axioms.
  • In the transparency phase, if something has no asserts and only calls functions, only create a function and no procedure
  • Move the transparency phase so its Core->Core instead of UnorderedCoreWithLaurelTypes -> UnorderedCoreWithLaurelTypes

keyboardDrummer and others added 30 commits April 20, 2026 15:50
…opaqueSpec

- Changed procedureToOp to produce opaqueSpec op with ensures and modifies
  as nested args (matching the grammar), instead of separate top-level args
- Added missing opaque keyword in MapStmtExprTest and T2_ModifiesClauses tests
…lator

- Add `axioms : List StmtExprMd` field to Laurel's Procedure structure
- In ContractPass, build axiom expressions from invokeOn trigger + ensures
  clauses (nested Forall with trigger on innermost quantifier), then clear
  the invokeOn field
- Update LaurelToCoreTranslator to translate proc.axioms directly instead
  of using the now-removed translateInvokeOnAxiom function
- Update CoreGroupingAndOrdering to use axioms instead of invokeOn for
  procedure ordering and callee collection
- Update Resolution to preserve axioms through name resolution
- Update MapStmtExpr to traverse axioms in mapProcedureM
- Fix InvokeOn test expected error messages
- Grammar: Add `modifiesWildcard` op for `modifies *` syntax
- Parser: Handle `modifiesWildcard` by producing `StmtExpr.All` in modifies list
- Printer: Emit `modifiesWildcard` when modifies list contains `All`
- ModifiesClauses: Skip frame condition generation for wildcard modifies
- FilterNonCompositeModifies: Preserve `All` entries (don't filter as non-composite)
- HeapParameterization: Don't treat wildcard `All` as evidence of heap access
- PythonToLaurel: Use `modifies *` for all opaque procedures
- Specs/ToLaurel: Use `modifies *` for spec procedures
- T2_ModifiesClauses: Uncomment wildcard test case
Two issues were causing the Python test failures:

1. dbg_trace statements in LaurelCompilationPipeline.lean were printing
   massive debug output that polluted #guard_msgs test expectations.

2. The contract pass (ContractPass.lean) created Assert/Assume nodes
   with source := none (via mkMd). When these reached the Core
   translator, getNameFromMd triggered 'BUG: metadata without a
   filerange' debug traces, further polluting test output.

Fix: propagate source locations from the original preconditions and
body to the Assert/Assume/Block nodes created by transformProcBody.
Prefix `program` parameter with underscore to suppress the
'unused variable' warning that causes the docs build to fail
with --wfail.
@keyboardDrummer keyboardDrummer force-pushed the issue-924-contract-and-proof-pass branch from da18905 to 3ce6673 Compare May 4, 2026 13:17
@github-actions github-actions Bot added the SMT label May 4, 2026
@github-actions github-actions Bot added the Git conflicts PR has merge conflicts with the base branch label May 5, 2026
keyboardDrummer-bot and others added 12 commits May 5, 2026 13:41
Formatting improvements:
- Change block formatting to use indent(2) with newlines for vertical layout
  instead of single-line '{ ... }' format
- Update semicolon separator to use newlines instead of spaces

Debugging improvements:
- Replace boolean 'coreProgramHasSuperfluousErrors' with 'coreDiagnostics' list
  that records why the Core program was suppressed, enabling better error surfacing
- Add source location and reason parameters to 'invalidCoreType' for more
  informative diagnostics
- Surface core diagnostics when no other diagnostics explain program suppression
- Add 'processLaurelFileKeepIntermediates' test helper for writing intermediate
  pipeline files to Build/ directory
- Add Build/ to .gitignore

Test updates:
- Update all expected outputs to match new block formatting
- Add 'opaque' keyword to test procedures that need it for the new formatting
- Fix #guard_msgs whitespace formatting
Diagnostics with FileRange.unknown are not actionable for users and
can arise from pre-existing resolution limitations (e.g., variables
in multi-assign with field targets losing their uniqueId). Filter
these out when surfacing suppression reasons to avoid spurious errors.
The CodeBuild source location was hardcoded to strata-org/Strata.git,
which fails when the commit only exists in keyboardDrummer/Strata.
Use github.server_url/github.repository so it resolves to the correct
repo dynamically.
The CodeBuild project has credentials for strata-org/Strata only.
On forks like keyboardDrummer/Strata, the job cannot access the source.
Add an 'if' condition to skip the benchmark on non-upstream repos,
and restore the hardcoded source URL that CodeBuild expects.
…gging-improvements

# Conflicts:
#	Strata/Languages/Laurel/LaurelToCoreTranslator.lean
…t emitDiagnostic

- Remove the FileRange.unknown filter in LaurelCompilationPipeline: all
  coreDiagnostics are now surfaced when no other diagnostics explain
  the suppression.
- Remove default parameters from invalidCoreType, making source and
  reason explicit at every call site.
- Remove redundant emitDiagnostic in the catch-all arm of translateType:
  invalidCoreType already records the diagnostic via coreDiagnostics.
Diagnostics without a known source location are not actionable for the
user. Restore the filter that was removed in 0b6cee4 to fix the
T1_MutableFields test failure.
…put params

Key changes:
- $post procedures are functional (isFunctional := true)
- $post takes all inputs AND all outputs as parameters
- $post does not call the original procedure — returns conjunction of
  postconditions over the combined input+output parameters
- At call sites, input arguments are assigned to temporary variables;
  those temps are passed to both the actual call and the assumed $post
  call (along with the output variables after the call)
@github-actions github-actions Bot removed the SMT label May 18, 2026
@keyboardDrummer keyboardDrummer force-pushed the issue-924-contract-and-proof-pass branch from c6bfe97 to 87a87cd Compare May 19, 2026 03:53
@github-actions github-actions Bot removed GOTO Git conflicts PR has merge conflicts with the base branch labels May 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants