From 36126508495a64221c4a3695406d2ccf2cd099b7 Mon Sep 17 00:00:00 2001 From: Allan Blanchard <allan.blanchard@cea.fr> Date: Wed, 27 Oct 2021 16:47:33 +0200 Subject: [PATCH] [wp/doc] Document terminates support --- src/plugins/wp/Changelog | 4 +- src/plugins/wp/doc/manual/wp_plugin.tex | 96 ++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/plugins/wp/Changelog b/src/plugins/wp/Changelog index 7c0fa5e2fee..2a4bb7b5026 100644 --- a/src/plugins/wp/Changelog +++ b/src/plugins/wp/Changelog @@ -27,9 +27,9 @@ Plugin WP <next-release> - WP [2021-10-25] Removes -wp-overflows option (unsound) - WP [2021-06-11] Adds an experimental support of "terminates" clauses. Adds the options -wp-declaration-terminate and - -wp-frama-c-stdlib to claims that external functions + -wp-frama-c-stdlib to claim that external functions terminates. - Adds -wp-declarations-terminate option to claims that + Adds -wp-definitions-terminate option to claim that defined function terminates. Adds -wp-variant-with-terminates to verify loop variants under the termination hypothesis. diff --git a/src/plugins/wp/doc/manual/wp_plugin.tex b/src/plugins/wp/doc/manual/wp_plugin.tex index abeb02c808f..afb8bee6f60 100644 --- a/src/plugins/wp/doc/manual/wp_plugin.tex +++ b/src/plugins/wp/doc/manual/wp_plugin.tex @@ -986,7 +986,7 @@ weakest precondition calculus. \texttt{terminates \textbackslash{}false}, any loop variant proof is trivial) (default is: \texttt{no}). \item[\tt -wp-(no)-dynamic] handles calls \textit{via} function pointers - thanks to the dedicated \verb+@calls f1,...,fn+ code annotation (default is: \texttt{yes}). + thanks to the dedicated code annotation \verb+@calls f1,...,fn+ (default is: \texttt{yes}). \end{description} \subsubsection{ACSL extension \texttt{@calls}} @@ -1018,6 +1018,100 @@ These annotations split post-conditions to the dynamic call into two sub-goals: a second for the call to \verb+f2+. A last goal is generated at the call site: one must prove that \verb+fp+ is either \verb+f1+ or \verb+f2+. +\subsubsection{Proof of \texttt{@terminates}} + +In ACSL, a function can be specified to terminate some condition \verb+P+ holds +in precondition. + +\begin{lstlisting}[language=c, alsolanguage=acsl] +/*@ terminates P ; */ +void function(void){ + ... +} +\end{lstlisting} + +If terminates verification is active, WP collects all function calls and loops +and generate different VCs. + +\paragraph{Loop variants.} When a loop has a variant, no particular verification +is generated for termination. However, if \verb+-wp-variant-with-terminates+ is +active, the variant is verified only if \verb+P+ holds at this program point. +Basically, "the variant has to hold only if the function has to terminate". For +example: + +\begin{lstlisting}[language=c, alsolanguage=acsl] +//@ terminates i >= 0 ; +void positive(int i){ + /*@ loop invariant \at(i, Pre) >= 0 ==> 0 <= i <= \at(i, Pre) ; + loop assigns i ; + loop variant i ; // verified when i >= 0 at pre + */ + while(i) --i; +} +\end{lstlisting} + +Note that it means that when one specifies \verb+terminates \false+ any loop +variant trivially holds. + +When a loop does not have a variant, WP checks that the loop is unreachable +when \verb+P+ holds in precondition, which means "a loop is allowed not +terminating when the function does not have to". For example: + +\begin{lstlisting}[language=c, alsolanguage=acsl] +//@ terminates i >= 0 ; +void function(int i){ + if(i < 0){ + // note i >= 0 && i < 0 ==> \false + while(1); + } +} +\end{lstlisting} + +\paragraph{Function call.} When a function \verb+f+ that terminates when +\verb+P+, calls a function \verb+g+ that terminates when \verb+Q+, WP tries to +prove that \verb+P@pre ==> Q@call-point+, "when \verb+f+ terminates, we must +call \verb+g+ in a way that guarantees that it also terminates". Note that it +means that if the function under verification must terminate, any call to a +non terminating function must be unreachable. For example: + +\begin{lstlisting}[language=c, alsolanguage=acsl] +//@ terminates i <= 0 ; +void f(int i) ; + +//@ terminates i > 0 ; +void g(int i) ; + +/*@ requires i <= 0 ; + terminates \true ; */ +void caller(int i){ + f(i); // succeeds + g(i); // fails, thus global termination is not proved +} +\end{lstlisting} + +When a called function does not have a terminates specification, WP assumes one +as specified by the options: + +\begin{itemize} +\item \verb+-wp-frama-c-stdlib-terminate+, +\item \verb+-wp-declarations-terminate+, +\item \verb+-wp-definitions-terminate+. +\end{itemize} + +\paragraph{(Mutually) recursive function.} When a function is in a recursive +cluster (as defined in the ACSL manual) and must terminate, WP checks that a +\verb+decreases+ clause is available for the function. Proving that existing +recursive calls might be unreachable is delegated to the proof of the +\verb+decreases+ clause. Note however that currenlty the proof of such a clause +is not supported. + +\paragraph{Function pointers. } On a call via a function pointer, WP checks that +a \verb+@calls+ is specified for this function pointer. If so, WP just behave +as explained before for function calls. If this specification is not available, +WP considers that the pointed function might call the function under +verification and thus that it is part of a recursive cluster and must provide +a \verb+decreases+ clause. + \subsection{Smoke Tests} During modular deductive verification, inconsistencies in function requirements -- GitLab