157 lines
6.1 KiB
Markdown
157 lines
6.1 KiB
Markdown
# 8.1 Implementation - preliminaries
|
|
## Implies
|
|
A specification can be written as a single temporal formula.
|
|
|
|
`P => Q` reads _P implies Q_. Unlike everyday speech, _implies_ does NOT assert causality,
|
|
only correlation.
|
|
|
|
## Definitions
|
|
### Module-closed formulas
|
|
|
|
A _module-closed_ expression, after resolution, contains only:
|
|
|
|
- built-in TLA+ operators and constructs
|
|
- numbers and strings
|
|
- declared constants and variables
|
|
- identifiers declared locally within the expression, including those
|
|
- in \A and \E
|
|
- in function `[]` and set `{}` constructors
|
|
- `\E v \in Nat: x' = x + v` is module-complete if `x` is a declared variable
|
|
- but the subexpression `x' = x + v` is not, because `v` is neither in it, nor declared
|
|
|
|
A _module-closed_ formula is a boolean module-closed expression:
|
|
|
|
- `(x \in 1..42) /\ (y' = x + 1)` is a module-closed formula if both `x` and `y` are declared variables
|
|
|
|
Only in this lecture, expression/formula will only consider those which are module-closed.
|
|
|
|
### Constant formulas
|
|
|
|
A constant expression is a (module-complete) expression that
|
|
- has no declared variables
|
|
- has no non-constant operators (e.g. `'` and `UNCHANGED`)
|
|
- Example: `foo \cup { n \in 1..22 : n^2 > m}` depends only on constants `foo` and `m`
|
|
- It is also a state expression that has the same value on all states
|
|
|
|
An assumption, introduced by an `ASSUME` statement, must be a constant formula.
|
|
|
|
### State expressions
|
|
|
|
A _state expression_ can contain anything in a constant expression, as well as variables
|
|
declared in a `VARIABLES` statement. Example, if `foo` is a declared constant,
|
|
and `x` and `y` are declared variables: `x + y[foo]`.
|
|
- It has value on a s state: states assign values to variables.
|
|
- It is an action expression whose value only depends on the first state of the step.
|
|
|
|
A state formula is a boolean state expression.
|
|
|
|
### Action expressions
|
|
|
|
An _action expression_ can contain anything a state expression can, as well as `'` and `UNCHANGED`.
|
|
It has value on a step or pair of states.
|
|
|
|
The prime operator `'` does not only apply to variables, but to any state expression.
|
|
For a state expression `se`, the value of `se'` on step `s -> t` is the value
|
|
of `se` on state `t`.
|
|
|
|
This defines: `UNCHAGED e` equals `e' = e`, so
|
|
```
|
|
UNCHANGED <<x, y, z>> equals <<x, y, z>>' = <<x, y, z>>
|
|
equals <<x', y', z'>> = <<x, y, z>>
|
|
equals (x' = x) /\ (y' = y) /\ (z' = z)
|
|
```
|
|
|
|
## Temporal formulas
|
|
### Definition
|
|
|
|
A temporal formula has a boolean value (formula) on a sequence of states,
|
|
which is what we've been calling a behavior.
|
|
|
|
We can write any specification as a temporal formula, whose value is true
|
|
on the behaviors allowed by the spec.
|
|
For example, let's call `TPSpec` the specification of the two-phase commit protocol.
|
|
|
|
Since the two-phase commit spec has
|
|
- initial formula: `TPInit`
|
|
- next-state formula: `TPNext`
|
|
|
|
Then, `TPSpec` should be true on `s(1) -> s(2) -> ...` iff
|
|
- `TPInit` is true on state s1
|
|
- `TPNext` is true on all steps s(i) -> s(i+1) for all i.
|
|
|
|
Considering the state expression `TPInit` as an action, its value is the one it has on
|
|
the initial state of the step, that is true on s(1).
|
|
|
|
If we consider it as a temporal formula, the state it has on the first state of the behavior is true.
|
|
|
|
Similarly, `TPNext` is true on a behavior iff it is true on the first state of the behavior.
|
|
If we allow it to stutter indefinitely with the `always` temporal operator, we get `[]TPNExt`,
|
|
which is true on a behavior iff `TPNExt` is true on all first states of the behavior.
|
|
|
|
So `TPSpec == TPInit /\ []TPNext`
|
|
|
|
That is really is too simple. It really is:
|
|
`TPSpec == TPInit /\ [][TPNext]_<<rmState, tmState, tmPrepared, msgs>>`
|
|
In general, the specification with initial formula `Init`, next-state formula `Next`,
|
|
and declared variables `v_1, ..., v_n` is expressed by the temporal formula:
|
|
|
|
`Init /\ [][Next]_<<v_1, ..., v_n>>`
|
|
|
|
But for now, ignore that last part.
|
|
|
|
We can tell TLC that the spec is this, we can d
|
|
- In the toolbox:
|
|
- either define Initial predicate and next-state relation
|
|
- or give it the complete temporal formula, even using its name if it is in the spec
|
|
- define `INIT` and `NEXT` in a CFG file.
|
|
|
|
### Applying [] to a state formula
|
|
|
|
For action `A`, `[]A` is true on a behavior iff `A` is true on all steps of the behavior.
|
|
|
|
Consider `TPTypeOK` in [two-phase commit](../specs/TwoPhase.tla)
|
|
|
|
```tla+ code fragment
|
|
TPTypeOK ==
|
|
(*************************************************************************)
|
|
(* The type-correctness invariant *)
|
|
(*************************************************************************)
|
|
/\ rmState \in [RM -> {"working", "prepared", "committed", "aborted"}]
|
|
/\ tmState \in {"init", "done"}
|
|
/\ tmPrepared \subseteq RM
|
|
/\ msgs \subseteq Messages
|
|
```
|
|
|
|
- It is an action, so `[]TPTypeOK` is true on a behavior iff `TPTypeOK` is true on all steps of the behavior.
|
|
- The _state formula_ `TPTypeOK` is an action whose value depends only on `s_i`,
|
|
because it contains no primed variables
|
|
- So `[]TPTypeOK` is true on a behavior iff `TPTypeOK` is true on all states (vs steps) of the behavior
|
|
- This is written `[]TPTypeOK` without adding the `[ ]_<<var_1, ...var_n>>`,
|
|
because it is a `state formula`, not just an `action formula`.
|
|
|
|
### Theorems
|
|
|
|
If `TF` is a temporal formula, `THEOREM TF` asserts that `TF` is true on
|
|
- every possible behavior
|
|
- not just behaviors satisfying some spec
|
|
|
|
`THEOREM TPSpec => []TPTypeOK` asserts that for every behavior:
|
|
- if `TPSpec` is true on the behavior, which means that the behavior satisfies `TPSpec`,
|
|
- then _always_ `[]TPTypeOK` is true on the behavior
|
|
- which means `TPTypeOK` is true on every state of the behavior
|
|
- Meaning that the theorem asserts that `TPTypeOK` is an `INVARIANT` of `TPSpec`
|
|
|
|
TLC does NOT automatically check theorems: we add them in the specs to tell
|
|
the reader what the author expects to be true.
|
|
|
|
To force checking the theorem,
|
|
- In the toolbox,
|
|
- add `[]TPTypeOK` to the properties for a model with behavior spec `TPSpec`
|
|
- or add `TPTypeOK` to the invariants for the model
|
|
- In TLC
|
|
- add `PROPERTY []TPTypeOK` to the CFG file
|
|
- or add `INVARIANT TPTypeOK` to the CFG file
|
|
|
|
|
|
|
|
|