Tactic: swap
The swap tactic applies to program-logic goals by rewriting the program
into a semantically equivalent form where two consecutive, independent
program fragments are exchanged.
In a nutshell, swap permutes commands when doing so does not change the
program’s behavior (typically because the swapped fragments do not
interfere, e.g., they write to disjoint variables and neither reads what the
other writes).
Applying swap replaces the current goal by the same goal, but with the
selected commands swapped in the program. This is useful to expose a more
convenient program structure, for example to align programs in relational
proofs or to bring related statements closer together.
Syntax
The swap tactic comes in several forms:
Syntax
swap {side}? {codepos1}swap {side}? {codepos1} {codeoffset1}swap {side}? [{codepos1}..{codepos1}] {codeoffset1}`
Here:
{side}is optional and is either1or2. It selects the left or right program in relational goals. If omitted, the tactic applies to the single program under consideration.{codepos1}denotes a top-level code position.A
{codeoffset1}is either:a signed integer (
nor-n), denoting a relative position, oran absolute code position written
@ {codepos1}.
The meaning of these forms is as follows:
swap {side}? {codepos1}swaps the two adjacent commands starting at the top-level position
{codepos1}.swap {side}? {codepos1} {codeoffset1}swaps the command at top-level position
{codepos1}with the command at the position designated by{codeoffset1}.swap {side}? [{codepos1}..{codepos1}] {codeoffset1}swaps a whole sequence of commands delimited by
[{codepos1}..{codepos1}]with the commands starting at the position designated by{codeoffset1}.
In all cases, the swap is only valid when the exchanged fragments are independent, so that the transformation preserves the program semantics.
Example (single statement)
The following example swaps two adjacent assignments that do not interfere. The returned result is unchanged, but the rewritten program may be more convenient for subsequent proof steps.
Example (swapping a block)
The following example illustrates the block form
swap [{codepos1}..{codepos1}] {codeoffset1}. We swap a block of two
commands with a later, independent command.
Example (invalid swap)
The following example shows a swap attempt that fails because the two commands are not independent: the second command reads the value written by the first one.