Skip to content

Remove functions#1408

Draft
keyboardDrummer wants to merge 229 commits into
strata-org:reviewed-kbd-will-merge-to-mainfrom
keyboardDrummer:removeFunctions
Draft

Remove functions#1408
keyboardDrummer wants to merge 229 commits into
strata-org:reviewed-kbd-will-merge-to-mainfrom
keyboardDrummer:removeFunctions

Conversation

@keyboardDrummer

Copy link
Copy Markdown
Contributor

Changes

  1. Remove Laurel functions.
  2. Support let expressions in transparent bodies. This is necessary to implement the above change, because the contract pass can produce let expressions when calling procedures with preconditions, and some of the updated tests have transparent bodies that call procedures with preconditions.
  3. Fix several bugs in the lifting pass. Again this is now necessary because with more things being procedures, there were more cases where lifting had to be done correctly.
  4. Improve printing of if-then-else
  5. Fix contract pass so it eliminates all pre and postconditions
  6. Verification performance is worse because calling transparent procedures has a more complicated encoding than calling functions had. Calling transparent procedures should get an encoding optimization but that's out of scope for this PR.
  7. Added #guard_msgs (drop info) in to several tests to prevent getting info output when running lake test. These guards previously already existed but they were accidentally removed in a test refactoring.

Tests

  1. Replaced usages of function in tests with procedure. Tests that had duplicated cases for functions and procedures had the function test-cases removed.
  2. The T3_ControlFlow test was updated to use let expressions in a transparent body
  3. The T2_ImpureExpressions test was updated to check for the new fixed bugs in the lifting pass
  4. Some tests checked against printed if-then-else and they've been updated
  5. No explicit test for this.
  6. Updated tests. Some tests now check for "could not prove" instead of "does not hold"

keyboardDrummer and others added 2 commits June 29, 2026 15:20
The function→procedure changes renumber assertion/assume IDs in the
generated Core programs. Update all expected_interpret/*.expected files
that had hardcoded assertion numbers to use [0-9]+ patterns instead,
matching the approach already used by test_missing_models.expected.
@keyboardDrummer-bot

Copy link
Copy Markdown
Collaborator

I investigated the run_py_interpret.sh failures. The root cause is that the function→procedure changes in this PR renumber assertion/assume IDs in the generated Core programs, which breaks 16 .expected files in StrataPython/StrataPythonTest/expected_interpret/ that had hardcoded assertion numbers in their regex patterns.

For example, test_truthiness_bool_eq.expected previously matched \[ERROR\] assert \(assert\(673\)\) condition did not reduce to bool — but after the refactoring, the assertion is numbered differently.

Fix pushed (b46ab22): I updated all 16 affected .expected files to use [0-9]+ wildcard patterns instead of hardcoded numbers, following the same approach that test_missing_models.expected already used in this PR.

Potential remaining issues I couldn't verify (no Lean toolchain available locally):

  1. Tests with false in .expected (e.g. test_deep_inline, test_chained_compare*) — these assume the interpreter still produces output containing "false" on assertion failure. If the function→procedure change causes these tests to fail differently (e.g. "stuck redex" instead of a clean assertion failure), these would need their .expected updated or converted to .skip files.
  2. Tests that currently pass (no .expected file) might now fail if procedure calls don't reduce correctly in the interpreter. The alwaysCallCoreFunctions := false flag is already set for pyInterpret, so calls go directly to procedures rather than $asFunction copies.

If CI still shows failures after this push, running ./run_py_interpret.sh --update locally would regenerate all .expected files from the actual outputs.

@keyboardDrummer

Copy link
Copy Markdown
Contributor Author

@keyboardDrummer-bot please investigate the CMBC failures that occur when doing ./StrataPython/StrataPythonTest/run_py_cbmc_tests.sh

@keyboardDrummer-bot

Copy link
Copy Markdown
Collaborator

I investigated the CBMC pipeline failures on this branch. Here's what I found:

Root Cause

The GOTO backend (Strata/Backends/CBMC/GOTO/LambdaToCProverGOTO.lean) only supported up to 3-argument (ternary) function applications. With this PR's change from functions to procedures, the contract pass now generates postcondition checks like test_helper_procedure$post0(arg1, arg2, ret, exception) with 4 arguments, causing:

Exception: [toGotoExprCtx] Not yet implemented: LExpr.app () (LExpr.app () (LExpr.app () (LExpr.app () (LExpr.op () { name := "test_helper_procedure$post0", ...

Affected Tests (9 tests)

All tests calling procedures with contracts failed at pyAnalyzeLaurelToGoto:

  • test_function_def_calls, test_class_methods, test_class_with_methods
  • test_datetime, test_datetime_now_tz, test_timedelta_expr
  • test_missing_models, test_multi_function, test_precondition_verification

Fix

I opened PR #1430 (targeting removeFunctions) that adds support for 4-6 argument function applications in both LExprT.toGotoExpr and LExpr.toGotoExprCtx. After the fix, all 29 tests in cbmc_expected.txt pass pyAnalyzeLaurelToGoto.

Additional Note

14 tests currently marked SKIP in cbmc_expected.txt now pass the pyAnalyzeLaurelToGoto stage (even without my fix — the PR's changes made them work). Their expected outcomes will need to be updated once their final CBMC verification results are determined in a full CI run with symtab2gb and cbmc.

@keyboardDrummer

Copy link
Copy Markdown
Contributor Author

@keyboardDrummer-bot please cherry-pick 8a3bbe4 into this PR

The GOTO backend's toGotoExprCtx and toGotoExpr functions only handled
up to ternary (3-argument) function applications. With the removal of
Laurel functions in favor of procedures, the contract pass now generates
pre/postcondition checks with 4+ arguments (e.g., procedure params +
return value + exception variable).

Add explicit pattern matching for quaternary (4), quinary (5), and
senary (6) argument applications in both LExprT.toGotoExpr and
LExpr.toGotoExprCtx. This fixes pyAnalyzeLaurelToGoto failures for
tests that call procedures with contracts (e.g., test_helper.procedure).
@github-actions github-actions Bot added the GOTO label Jun 29, 2026
@keyboardDrummer

Copy link
Copy Markdown
Contributor Author

@keyboardDrummer-bot please debug the failures in this CI run: https://github.com/strata-org/Strata/actions/runs/28402459992/job/84162551771?pr=1408

symtab2gb requires the 'guard' key on every instruction, but the
serializer was omitting it for non-GOTO instructions with a true guard.
This caused 'instruction_from_json: key guard not found' errors for
all 6 failing Python CBMC pipeline tests.
strata-git-sync Bot pushed a commit to strata-org/Strata-Python that referenced this pull request Jul 14, 2026
Port of GitHub PR strata-org/Strata#1408 ("Remove functions"), the
StrataPythonFrontEnd half.

- Convert the Laurel runtime prelude (PythonRuntimeLaurelPart) from
 `function` declarations to `procedure`s.
- Thread `alwaysCallCoreFunctions` through PySpecPipeline / Cli.
- Emit a valueless `.Return` (not a direct `$body` exit) for Python
 `return`, so postcondition assertions appended after the body stay
 reachable; pass the new `postTest` argument to `While`.

Goldens: regenerated all expected_laurel/*.expected via
run_py_analyze.sh --update (with label-ID normalization) and updated the
test_missing_models interpret pattern. AnalyzeGoldenTest and the full FE
test suite pass against the ported Strata.
strata-git-sync Bot pushed a commit that referenced this pull request Jul 14, 2026
…on twins

Ports the TransparencyPass.lean changes from #1408:
- Add redirectCallsToFunctional / redirectCallsInProc helpers
- Split toUpdate into procedures needing a procedural twin vs
 transparent-only (via blockContainsAssumeOrAssert)
- Redirect single-output twinned procedure calls to $asFunction when
 options.alwaysCallCoreFunctions is set
- Thread LaurelTranslateOptions through createFunctionsForTransparentBodies
strata-git-sync Bot pushed a commit that referenced this pull request Jul 14, 2026
…ion classification

Ports the coupled call-site rewrite from #1408 so that
$post/$asFunction helper calls in pure contexts are no longer rejected:

- Add TranslateState.procedureNames + containsProcedure, and switch the
 three call-site checks in translateExpr/translateStmt from the id-based
 model.isFunction to the name-based containsProcedure. TransparencyPass
 redirects foo -> foo$asFunction while preserving uniqueId, so an id-based
 check still resolves to the base procedure and wrongly rejects the call.

- TransparencyPass: this tree still carries the isFunctional field (unlike
 #1408, which removes it), and the SCC/formatter/SemanticModel classification
 all key off it. So restore isFunctional := true on the $asFunction copies
 and isFunctional := false on the procedural twins, and only give a
 procedural twin to non-functional procedures. Without this, genuine
 functions (e.g. 'function assertP(x) requires P(x)') got a procedural twin,
 landed in procedureNames, and their calls in pure bodies were rejected.

- Tests: mark 'safe' as a procedure in the Postconditions well-formedness
 test; update 'assertion could not be proved' -> 'assertion does not hold'
 in TransparentBody; regenerate the ContractPassConditionModeTest golden for
 the new procedure-shaped $post helpers.

Full brazil-build (512 jobs) passes.
strata-git-sync Bot pushed a commit that referenced this pull request Jul 14, 2026
Port of GitHub PR #1408 ("Remove functions").

- Remove the Laurel `function` keyword and the `isFunctional` distinction;
 everything is now a `procedure`.
- Support let expressions in transparent bodies (the contract pass can
 produce them when calling procedures with preconditions).
- Fix several bugs in the lifting pass now that more constructs are
 procedures.
- Improve printing of if-then-else (indent then/else branches).
- Fix the contract pass so it eliminates all pre and postconditions.

Tests: replaced `function` with `procedure` in Laurel tests (dropping
duplicated function/procedure cases), updated printed-output goldens for
the new if-then-else formatting and procedure encoding, and updated
diagnostics that changed wording. Full StrataTest suite builds and passes.
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.

2 participants