Repository navigation
fix: reject a pHL bound read in another memory by call / rnd - #1189
Merged
Merged
Conversation
The bound of `phoare[s; i : P ==> Q] cmp bd` is interpreted in the initial memory. Two pHL rules also used a bound in the memory reached after `s`, without relating the two values: - `call` (`t_bdhoare_call`) gives the bound of the goal (or its optional bound parameter) to the specification of the called procedure, which interprets it in the memory the procedure starts from: after `s`, and with the local variables of the callee instead of those of the caller. A bound written by `s`, or mentioning a local variable (read as the callee's variable of the same name), gave a false judgement. - `rnd phi d1 d2 d3 d4` checks `phi => mu d E <= d2` (resp. `d4`) after `s`, but `d1 * d2 + d3 * d4 <= bd` in the initial memory. All three allowed deriving `false`, e.g. (#1124) `phoare[M.g : !M.x ==> res] <= b2r M.x` for `M.x <- true; r <@ f(); return true;`, and likewise `phoare[N.g : true ==> res] <= b2r x` for `r <@ f(!x); return r;` where `f(x)` returns `x`. Both rules now reject such bounds (as #1131 does for `while`): `call` fails when the bound depends on a local variable or on a variable written by `s`, `rnd phi d1 d2 d3 d4` when `d2` or `d4` depends on a variable written by `s`. A seq-style non-modification goal would be more permissive, but no in-tree proof needs it: an instrumented build saw 221 pHL `call` applications in unit, stdlib and examples, none with a local or prefix-written bound, and no use of `rnd phi d1 d2 d3 d4`. A bound can still be frozen in a logical variable first. Fixes the `call` and `rnd phi d1 d2 d3 d4` parts of #1124 (its `while` part is #1131). Origin: the pHL `call` rule, 75d66ec (2013-06-06), and `rnd phi d1 d2 d3 d4`, addc94d (2013-07-07); both first released in r2022.04. Test: tests/phoare-call-prefix-bound.ec and tests/phoare-rnd-prefix-bound.ec (the previous build accepts every `fail` line). unit (122 files), stdlib (128) and examples (49) pass.
This was referenced Oct 9, 2026
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.
The bound of
phoare[s; i : P ==> Q] cmp bdis interpreted in theinitial memory. Two pHL rules also used a bound in the memory reached
after
s, without relating the two values:call(t_bdhoare_call) gives the bound of the goal (or itsoptional bound parameter) to the specification of the called
procedure, which interprets it in the memory the procedure starts
from: after
s, and with the local variables of the callee insteadof those of the caller. A bound written by
s, or mentioning alocal variable (read as the callee's variable of the same name),
gave a false judgement.
rnd phi d1 d2 d3 d4checksphi => mu d E <= d2(resp.d4)after
s, butd1 * d2 + d3 * d4 <= bdin the initial memory.All three allowed deriving
false, e.g. (#1124)phoare[M.g : !M.x ==> res] <= b2r M.xforM.x <- true; r <@ f(); return true;, and likewisephoare[N.g : true ==> res] <= b2r xforr <@ f(!x); return r;where
f(x)returnsx.Both rules now reject such bounds (as #1131 does for
while):callfails when the bound depends on a local variable or on a variable
written by
s,rnd phi d1 d2 d3 d4whend2ord4depends on avariable written by
s. A seq-style non-modification goal would bemore permissive, but no in-tree proof needs it: an instrumented build
saw 221 pHL
callapplications in unit, stdlib and examples, nonewith a local or prefix-written bound, and no use of
rnd phi d1 d2 d3 d4. A bound can still be frozen in a logicalvariable first.
Fixes the
callandrnd phi d1 d2 d3 d4parts of #1124 (itswhilepart is #1131).Origin: the pHL
callrule, 75d66ec (2013-06-06), andrnd phi d1 d2 d3 d4, addc94d (2013-07-07); both first released inr2022.04.
Test: tests/phoare-call-prefix-bound.ec and
tests/phoare-rnd-prefix-bound.ec (the previous build accepts every
failline). unit (122 files), stdlib (128) and examples (49) pass.