You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
## Functional changes
1. [Debugging] Improve the printing of Laurel if-then-else expressions
1. `EliminateReturnsInExpression` now runs for procedures as well, which
enables more types of transparent bodies for procedures. To make it work
for both functions and procedures, it was also necessary for the body of
functions to be immediately wrapped in a return statement during
parsing.
1. Allow calling procedures from contracts. Combined with the previous
change this makes procedures strictly more powerful than functions
1. Let the transparency pass rewrite the bodies of assume statements so
they don't assert anything.
1. Improve diagnostics related to contracts, using the correct verbiage
"precondition" and "postcondition" instead of "assertion"
1. Generalized the `LaurelPass` concept so it works for all
transformation between Laurel source and Core, not just the
Laurel->Laurel transformation. This helps make the documentation more
complete.
### Why let the transparency pass rewrite the bodies of assume
statements so they don't assert anything?
After the contract pass, a call will look like `assert <preconditions>;
call(..); assume <postconditions>`, where the body of the callee looks
like `assume <preconditions>; <body>; assert <postconditions>`. If we
now do either concrete execution, or we do inlining, then any assertions
that occur inside the pre or postconditions will be asserted twice,
because they occur once in an assert and once in an assume. By ignoring
the assertions inside the assume, we prevent the duplication.
Whether you also want this behavior for assumptions that were created by
users is something I'm not sure about. However, if we want we can let
those behave differently. Right now I think we don't have enough data to
decide what we want for user created assumptions, and they are AFAIK not
yet used, so I think it's OK to change their behavior.
## Implementation
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
- [Updated] Lift assertions, assumptions and procedure calls when they
occur in expressions. Note: the changes in this pass could have been
extracted to a different PR to reduce the scope of this one, but I think
that keeping them in this PR is most efficient from a developer time
perspective.
## Follow-up work
- Remove the now obsolete functions from Laurel
- Create WF proofs for quantifier bodies
- 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
---------
Co-authored-by: keyboardDrummer-bot <keyboardDrummer-bot@users.noreply.github.com>
Co-authored-by: Fabio Madge <fabio@madge.me>
documentation := "Eliminates constrained types by replacing them with their base types and generating constraint-checking functions and witness procedures. Type tests against constrained types are rewritten to call the generated constraint function."
documentation := "Rewrites short-circuit boolean operators (`&&` and `||`) into equivalent conditional expressions. This simplifies subsequent passes and the final translation to Core, which does not have short-circuit semantics built in."
61
-
run := fun p m =>
62
-
(desugarShortCircuit m p, [], {})
62
+
run := fun p _ _ =>
63
+
(desugarShortCircuit p, [], {})
63
64
comesBefore := [
64
-
⟨ liftExpressionAssignmentsPass, "The desugar short circuit pass introduces if-then-else expressions whose control-flow must be taken into account by the lifting pass."⟩]
65
+
⟨ liftImperativeExpressionsPass.meta, "The desugar short circuit pass introduces if-then-else expressions whose control-flow must be taken into account by the lifting pass."⟩]
documentation := "Replaces every deterministic hole with a call to a freshly generated uninterpreted function. After this pass the program contains only non-deterministic holes. Assumes `InferHoleTypes` has already annotated holes with types."
documentation := "Lowers post-test `While` loops (the `do … while` form) into the pre-test loop `{ while(true) invariant I { BODY; if (!COND) exit L } } L`, with a fresh `$`-prefixed exit label `L`. Runs early so no later pass observes a post-test loop; the invariant is checked at the loop head, matching `while`."
documentation := "Lowers Java-style increment/decrement operators (`++x`, `x++`, `--x`, `x--`) into existing Laurel assignment and arithmetic constructs. Prefix forms yield the new value; postfix forms yield the old value. Runs early so that no later pass observes an `.IncrDecr` node."
106
-
run := fun p _m => (eliminateIncrDecr p, [], {})
106
+
run := fun p _m _ => (eliminateIncrDecr p, [], {})
0 commit comments