src/HOL/SPARK/Manual/VC_Principles.thy
author wenzelm
Sat, 24 Mar 2018 20:51:42 +0100
changeset 67945 984c3dc46cc0
parent 63167 0909deb8059b
child 76987 4c275405faae
permissions -rw-r--r--
tuned output;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
45044
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     1
(*<*)
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     2
theory VC_Principles
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     3
imports Proc1 Proc2
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     4
begin
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     5
(*>*)
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     6
63167
0909deb8059b isabelle update_cartouches -c -t;
wenzelm
parents: 58622
diff changeset
     7
chapter \<open>Principles of VC generation\<close>
45044
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
     8
63167
0909deb8059b isabelle update_cartouches -c -t;
wenzelm
parents: 58622
diff changeset
     9
text \<open>
45044
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    10
\label{sec:vc-principles}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    11
In this section, we will discuss some aspects of VC generation that are
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    12
useful for understanding and optimizing the VCs produced by the \SPARK{}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    13
Examiner.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    14
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    15
\begin{figure}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    16
\lstinputlisting{loop_invariant.ads}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    17
\lstinputlisting{loop_invariant.adb}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    18
\caption{Assertions in for-loops}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    19
\label{fig:loop-invariant-ex}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    20
\end{figure}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    21
\begin{figure}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    22
\begin{tikzpicture}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    23
\tikzstyle{box}=[draw, drop shadow, fill=white, rounded corners]
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    24
\node[box] (pre) at (0,0) {precondition};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    25
\node[box] (assn) at (0,-3) {assertion};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    26
\node[box] (post) at (0,-6) {postcondition};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    27
\draw[-latex] (pre) -- node [right] {\small$(1 - 1) * b \mod 2^{32} = 0$} (assn);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    28
\draw[-latex] (assn) .. controls (2.5,-4.5) and (2.5,-1.5) .. %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    29
node [right] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    30
(i - 1) * b \mod 2^{32} = c ~\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    31
(i + 1 - 1) * b \mod 2^{32} ~= \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    32
(c + b) \mod 2^{32} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    33
\end{array}$} (assn);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    34
\draw[-latex] (assn) -- node [right] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    35
(a - 1) * b \mod 2^{32} = c ~\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    36
a * b \mod 2^{32} = (c + b) \mod 2^{32} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    37
\end{array}$} (post);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    38
\draw[-latex] (pre) .. controls (-2,-3) .. %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    39
node [left] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    40
\neg 1 \le a ~\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    41
a * b \mod 2^{32} = 0 %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    42
\end{array}$} (post);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    43
\end{tikzpicture}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    44
\caption{Control flow graph for procedure \texttt{Proc1}}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    45
\label{fig:proc1-graph}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    46
\end{figure}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    47
\begin{figure}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    48
\begin{tikzpicture}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    49
\tikzstyle{box}=[draw, drop shadow, fill=white, rounded corners]
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    50
\node[box] (pre) at (0,0) {precondition};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    51
\node[box] (assn1) at (2,-3) {assertion 1};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    52
\node[box] (assn2) at (2,-6) {assertion 2};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    53
\node[box] (post) at (0,-9) {postcondition};
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    54
\draw[-latex] (pre) -- node [right] {\small$(1 - 1) * b \mod 2^{32} = 0$} (assn1);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    55
\draw[-latex] (assn1) -- node [left] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    56
(i - 1) * b \mod 2^{32} = c \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    57
\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    58
i * b \mod 2^{32} = \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    59
(c + b) \mod 2^{32} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    60
\end{array}$} (assn2);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    61
\draw[-latex] (assn2) .. controls (4.5,-7.5) and (4.5,-1.5) .. %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    62
node [right] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    63
i * b \mod 2^{32} = c ~\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    64
(i + 1 - 1) * b \mod 2^{32} = c %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    65
\end{array}$} (assn1);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    66
\draw[-latex] (assn2) -- node [right] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    67
a * b \mod 2^{32} = c ~\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    68
a * b \mod 2^{32} = c %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    69
\end{array}$} (post);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    70
\draw[-latex] (pre) .. controls (-3,-3) and (-3,-6) .. %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    71
node [left,very near start] {\small$\begin{array}{l} %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    72
\neg 1 \le a ~\longrightarrow \\ %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    73
a * b \mod 2^{32} = 0 %
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    74
\end{array}$} (post);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    75
\end{tikzpicture}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    76
\caption{Control flow graph for procedure \texttt{Proc2}}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    77
\label{fig:proc2-graph}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    78
\end{figure}
58622
aa99568f56de more antiquotations;
wenzelm
parents: 45044
diff changeset
    79
As explained by Barnes @{cite \<open>\S 11.5\<close> Barnes}, the \SPARK{} Examiner unfolds the loop
45044
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    80
\begin{lstlisting}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    81
for I in T range L .. U loop
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    82
  --# assert P (I);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    83
  S;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    84
end loop;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    85
\end{lstlisting}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    86
to
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    87
\begin{lstlisting}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    88
if L <= U then
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    89
  I := L;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    90
  loop
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    91
    --# assert P (I);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    92
    S;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    93
    exit when I = U;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    94
    I := I + 1;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    95
  end loop;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    96
end if;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    97
\end{lstlisting}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    98
Due to this treatment of for-loops, the user essentially has to prove twice that
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
    99
\texttt{S} preserves the invariant \textit{\texttt{P}}, namely for
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   100
the path from the assertion to the assertion and from the assertion to the next cut
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   101
point following the loop. The preservation of the invariant has to be proved even
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   102
more often when the loop is followed by an if-statement. For trivial invariants,
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   103
this might not seem like a big problem, but in realistic applications, where invariants
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   104
are complex, this can be a major inconvenience. Often, the proofs of the invariant differ
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   105
only in a few variables, so it is tempting to just copy and modify existing proof scripts,
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   106
but this leads to proofs that are hard to maintain.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   107
The problem of having to prove the invariant several times can be avoided by rephrasing
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   108
the above for-loop to
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   109
\begin{lstlisting}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   110
for I in T range L .. U loop
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   111
  --# assert P (I);
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   112
  S;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   113
  --# assert P (I + 1)
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   114
end loop;
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   115
\end{lstlisting}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   116
The VC for the path from the second assertion to the first assertion is trivial and can
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   117
usually be proved automatically by the \SPARK{} Simplifier, whereas the VC for the path
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   118
from the first assertion to the second assertion actually expresses the fact that
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   119
\texttt{S} preserves the invariant.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   120
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   121
We illustrate this technique using the example package shown in \figref{fig:loop-invariant-ex}.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   122
It contains two procedures \texttt{Proc1} and \texttt{Proc2}, both of which implement
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   123
multiplication via addition. The procedures have the same specification, but in \texttt{Proc1},
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   124
only one \textbf{assert} statement is placed at the beginning of the loop, whereas \texttt{Proc2}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   125
employs the trick explained above.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   126
After applying the \SPARK{} Simplifier to the VCs generated for \texttt{Proc1}, two very
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   127
similar VCs
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   128
@{thm [display] (concl) procedure_proc1_5 [simplified pow_2_32_simp]}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   129
and
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   130
@{thm [display,margin=60] (concl) procedure_proc1_8 [simplified pow_2_32_simp]}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   131
remain, whereas for \texttt{Proc2}, only the first of the above VCs remains.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   132
Why placing \textbf{assert} statements both at the beginning and at the end of the loop body
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   133
simplifies the proof of the invariant should become obvious when looking at \figref{fig:proc1-graph}
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   134
and \figref{fig:proc2-graph} showing the \emph{control flow graphs} for \texttt{Proc1} and
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   135
\texttt{Proc2}, respectively. The nodes in the graph correspond to cut points in the program,
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   136
and the paths between the cut points are annotated with the corresponding VCs. To reduce the
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   137
size of the graphs, we do not show nodes and edges corresponding to runtime checks.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   138
The VCs for the path bypassing the loop and for the path from the precondition to the
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   139
(first) assertion are the same for both procedures. The graph for \texttt{Proc1} contains
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   140
two VCs expressing that the invariant is preserved by the execution of the loop body: one
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   141
for the path from the assertion to the assertion, and another one for the path from the
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   142
assertion to the conclusion, which corresponds to the last iteration of the loop. The latter
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   143
VC can be obtained from the former by simply replacing $i$ by $a$. In contrast, the graph
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   144
for \texttt{Proc2} contains only one such VC for the path from assertion 1 to assertion 2.
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   145
The VC for the path from assertion 2 to assertion 1 is trivial, and so is the VC for the
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   146
path from assertion 2 to the postcondition, expressing that the loop invariant implies
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   147
the postcondition when the loop has terminated.
63167
0909deb8059b isabelle update_cartouches -c -t;
wenzelm
parents: 58622
diff changeset
   148
\<close>
45044
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   149
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   150
(*<*)
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   151
end
2fae15f8984d Added documentation for HOL-SPARK
berghofe
parents:
diff changeset
   152
(*>*)