mirror of
https://github.com/achlipala/frap.git
synced 2024-11-10 00:07:51 +00:00
ModelChecking chapter done
This commit is contained in:
parent
cbf2bb71fa
commit
211ede66a0
2 changed files with 86 additions and 8 deletions
|
@ -1016,14 +1016,6 @@ Definition withInterference shared private (inv : shared -> Prop)
|
||||||
Step := stepWithInterference inv sys.(Step)
|
Step := stepWithInterference inv sys.(Step)
|
||||||
|}.
|
|}.
|
||||||
|
|
||||||
(* We also have a ready-made invariant we could try to prove for any such
|
|
||||||
* system, asserting that [inv] always holds of the shared state. *)
|
|
||||||
Inductive sharedInvariant shared private (inv : shared -> Prop)
|
|
||||||
: threaded_state shared private -> Prop :=
|
|
||||||
| SharedInvariant : forall sh pr,
|
|
||||||
inv sh
|
|
||||||
-> sharedInvariant inv {| Shared := sh; Private := pr |}.
|
|
||||||
|
|
||||||
(* Tired of simulation proofs yet? Then you'll love this theorem, which shows
|
(* Tired of simulation proofs yet? Then you'll love this theorem, which shows
|
||||||
* a free simulation for any use of [withInterference]! We even get to pick the
|
* a free simulation for any use of [withInterference]! We even get to pick the
|
||||||
* trivial simulation relation, state equality. *)
|
* trivial simulation relation, state equality. *)
|
||||||
|
|
|
@ -1108,6 +1108,7 @@ At each step, we check whether the expanded set is actually equal to the previou
|
||||||
If so, our process of \emph{multi-step closure}\index{multi-step closure} has terminated, and we have an invariant, by construction.
|
If so, our process of \emph{multi-step closure}\index{multi-step closure} has terminated, and we have an invariant, by construction.
|
||||||
Again, keep in mind that multi-step closure will not terminate for most transition systems, and there is an art to phrasing a problem in terms of systems where it \emph{will} terminate.
|
Again, keep in mind that multi-step closure will not terminate for most transition systems, and there is an art to phrasing a problem in terms of systems where it \emph{will} terminate.
|
||||||
|
|
||||||
|
|
||||||
\section{Abstracting a Transition System}
|
\section{Abstracting a Transition System}
|
||||||
|
|
||||||
When analyzing an infinite-state system, it is not necessary to give up hope for model checking.
|
When analyzing an infinite-state system, it is not necessary to give up hope for model checking.
|
||||||
|
@ -1204,6 +1205,91 @@ If we do manage to handle them all, then Theorem \ref{abstract_simulation} appli
|
||||||
However, we should be careful, in our choices of abstractions, to bias our designs toward those that don't introduce extra complexities.
|
However, we should be careful, in our choices of abstractions, to bias our designs toward those that don't introduce extra complexities.
|
||||||
|
|
||||||
|
|
||||||
|
\section{Modular Decomposition of Invariant-Finding}
|
||||||
|
|
||||||
|
Many transition systems are straightforward to abstract into others, as single global steps.
|
||||||
|
Other times, the right way to tame a complex system is to decompose it into others and analyze them separately for invariants.
|
||||||
|
In such cases, the key is a proof principle to combine the invariants of the component systems into an invariant of the overall system.
|
||||||
|
We will refer to this style of proof decomposition as \emph{modularity}\index{modularity}, and this section gives our first example of modularity, for multithreaded systems.
|
||||||
|
|
||||||
|
Imagine that we have a system consisting of $n$ different copies of a transition system $\angled{S, S_0, \to}$ running as concurrent threads, modeled in the way introduced in the previous chapter.
|
||||||
|
It's not obvious that we can analyze each thread separately, since, during that thread's execution, the other threads are constantly interrupting and modifying global state.
|
||||||
|
To make matters worse, we can only understand their patterns of state modification by analyzing their thread-local state.
|
||||||
|
The situation seems inherently unmodular.
|
||||||
|
|
||||||
|
However, consider the following construction on transition systems.
|
||||||
|
Given a transition relation $\to$ and an invariant $I$ on the global state shared by all threads, we define a new transition relation $\to^I$ as follows.
|
||||||
|
$$\infer{s \to^I s'}{
|
||||||
|
s \to s'
|
||||||
|
}
|
||||||
|
\quad \infer{(g, \ell) \to^I (g', \ell)}{
|
||||||
|
I(g')
|
||||||
|
}$$
|
||||||
|
|
||||||
|
The first rule says that any step of the original relation is also a step of the new relation.
|
||||||
|
However, the second rule adds a new kind of step: the global state may change \emph{arbitrarily}, so long as the new value satisfies invariant $I$.
|
||||||
|
We lift this operation to full transition systems, defining $\angled{S, S_0, \to}^I = \angled{S, S_0, \to^I}$.
|
||||||
|
|
||||||
|
This construction trivially acts as an abstraction.
|
||||||
|
\begin{theorem}\label{shared_invariant_abstract}
|
||||||
|
\abstraction
|
||||||
|
$\mathbb S \simulate_\mathsf{id} {\mathbb S}^I$, for any system $\mathbb S$ and property $I$.
|
||||||
|
\end{theorem}
|
||||||
|
|
||||||
|
\newcommand{\modularity}[0]{\marginpar{\fbox{\textbf{Modularity}}}}
|
||||||
|
|
||||||
|
However, we wouldn't want to make this abstraction step in a proof about a single thread.
|
||||||
|
We needlessly complicate our model checking by forcing ourselves to consider all modifications of the global state that obey $I$.
|
||||||
|
The payoff comes in analyzing multithreaded systems.
|
||||||
|
\begin{theorem}\label{shared_invariant_modular}
|
||||||
|
\modularity
|
||||||
|
Where $I$ is an invariant over only the shared state of a multithreaded system, let $I' = \{(g, \ell) \mid I(g)\}$ be the lifting of $I$ to cover full states, local parts included. If $I'$ is an invariant for both ${\mathbb S}_1^I$ and ${\mathbb S}_2^I$, then $I'$ is also an invariant for $({\mathbb S}_1 \mid {\mathbb S}_2)^I$.
|
||||||
|
\end{theorem}
|
||||||
|
|
||||||
|
This theorem gives us a way to analyze the threads in a system separately.
|
||||||
|
As an example, consider this program, where multiple threads will run \texttt{f()} simultaneously.
|
||||||
|
\begin{verbatim}
|
||||||
|
int global = 0;
|
||||||
|
|
||||||
|
f() {
|
||||||
|
int local = 0;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
local = global;
|
||||||
|
local = 3 + local;
|
||||||
|
local = 7 + local;
|
||||||
|
global = local;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
Call the transition-system encoding of this code $\mathbb S$.
|
||||||
|
We can apply the Boolean-for-evenness abstraction to model a single thread with finite state, but we are left needing to account for interference by other threads.
|
||||||
|
However, we can apply Theorem \ref{shared_invariant_modular} to analyze threads separately.
|
||||||
|
|
||||||
|
For instance, we want to show that ``\texttt{global} is always even'' is an invariant of ${\mathbb S} \mid {\mathbb S}$.
|
||||||
|
By Theorem \ref{shared_invariant_abstract}, we can switch to analyzing system $({\mathbb S} \mid {\mathbb S})^I$, where $I$ is the evenness invariant.
|
||||||
|
By Theorem \ref{shared_invariant_modular}, we can switch to proving the same invariant separately for systems ${\mathbb S}^I$ and ${\mathbb S}^I$, which are, of course, the same system in this case.
|
||||||
|
We apply the Boolean-for-evenness abstraction to this system, to get one with a finite state space, so we can check the invariant automatically by model checking.
|
||||||
|
Following the chain of reasoning backward, we have proved the invariant for ${\mathbb S} \mid {\mathbb S}$.
|
||||||
|
|
||||||
|
Even better, that last proof includes the hardest steps that carry over to the proof for an arbitrary number of threads.
|
||||||
|
Define an exponentially growing system of threads ${\mathbb S}^n$ by:
|
||||||
|
\begin{eqnarray*}
|
||||||
|
{\mathbb S}^0 &=& \mathbb S \\
|
||||||
|
{\mathbb S}^{n+1} &=& {\mathbb S}^n \mid {\mathbb S}^n
|
||||||
|
\end{eqnarray*}
|
||||||
|
|
||||||
|
\begin{theorem}
|
||||||
|
For any $n$, it is an invariant of ${\mathbb S}^n$ that the global variable is always even.
|
||||||
|
\end{theorem}
|
||||||
|
|
||||||
|
\begin{proof}
|
||||||
|
By induction on $n$, repeatedly using Theorem \ref{shared_invariant_modular} to push the obligation down to the leaves of the tree of concurrent compositions, after applying Theorem \ref{shared_invariant_abstract} at the start to introduce the use of $\ldots^I$.
|
||||||
|
Every leaf is the same system $\mathbb S$, for which we abstract and apply model checking, appealing to the step above where we ran the same analysis.
|
||||||
|
\end{proof}
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
||||||
\appendix
|
\appendix
|
||||||
|
|
Loading…
Reference in a new issue