\documentclass[11pt,twoside]{scrartcl}

%opening
\newcommand{\lecid}{15-414}
\newcommand{\leccourse}{Bug Catching: Automated Program Verification}
\newcommand{\lecdate}{} %e.g. {October 21, 2013}
\newcommand{\lecnum}{6}
\newcommand{\lectitle}{Invariants for Arbitrary Loops}
\newcommand{\lecturer}{Matt Fredrikson}

\usepackage{lecnotes}

\usepackage[irlabel]{bugcatch}


\begin{document}

\maketitle
\thispagestyle{empty}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\section{Introduction}

The previous lecture provided axioms for compositional reasoning about deterministic sequential programs.
All the axioms compositionally reduce the truth of a postcondition of a more complex program to a logical combination of postconditions of simpler programs.
All axioms?
Well, all the axioms but one: those about loops.

But putting loops aside for the moment, these axioms completely tell us what we need to do to understand a program.
All we need to do is to identify the top-level operator of the program and apply the corresponding axiom from its left hand side to its structurally simpler right hand side, which will eventually reduce the property of a program to first-order logic with arithmetic but without programs.
This process is completely systematic.

So except for the (nontrivial) fact that we will have to hope that an SMT solver will be able to handle the remaining arithmetic, our ``only'' problem is what we could possibly to with a loop.
The unwinding axioms from the previous lecture were only partially helpful, which is why this lecture investigates more comprehensive reasoning techniques for loops.
We follow an entirely systematic approach~\cite[Chapter 7]{Platzer17} to understanding loop invariants, an induction technique for loops, which is of central significance for program verification.
We will also experience our share of the important phenomenon of loop invariant search.

\section{Derived Soundness}

Recall the axioms that we introduced in the last lecture.
Writing down axioms is one thing.
Making use of them for proofs is quite helpful, too.
But if the axioms are wrong, then that would not help making the programs any more correct.
Consequently, it is imperative that all axioms we adopt are indeed sound, so only allow us to prove formulas that are actually valid.
An axiom is sound iff all its instances are valid formulas, so true in all states.
The notes from the previous lecture give some examples of how to show this by referring to the semantics of Dynamic Logic, in a similar way to how the soundness of proof rules for propositional logic were established.

The \irref{unfold} axiom can be justified to be sound in another way.
Rather than arguing by semantics, which would work, too, we can derive it with a sequent calculus proof from the other axioms.
After all other axioms are proved to be sound the \emph{derived axiom} \irref{unfold} is thus sound too.

\begin{lemma}
  The following axiom is a \dfn[axiom!derived]{derived axiom}, so can be proved from the other axioms in sequent calculus, and is, thus, sound:
  \[
\cinferenceRule[unfold|$\dibox{\text{unfold}}$]{unfold while loop}
{\linferenceRule[equiv]
  {(\ivr\limply\dbox{\ausprg}{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}) \land (\lnot\ivr\limply\ausfml)}
  {\axkey{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}}
}{}%
  \]
\end{lemma}
\begin{proof}
The axiom \irref{unfold} can be proved from the other axioms by using some of them in the backwards implication direction:
\begin{sequentdeduction}[array]
\linfer[composeb]
{\linfer[ifb]
  {\linfer[whileiterateb]
    {\lclose}
    {\lsequent{} {{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}\lbisubjunct
 {\dbox{\pifs{\ivr}{\plgroup\ausprg;\pwhile{\ivr}{\ausprg}\prgroup}}{\ausfml}}}}
 }
  {\lsequent{} {{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}\lbisubjunct
 {(\ivr\limply\dbox{\ausprg;\pwhile{\ivr}{\ausprg}}{\ausfml}) \land (\lnot\ivr\limply\ausfml)}}}
}
{\lsequent{} {{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}\lbisubjunct
 {(\ivr\limply\dbox{\ausprg}{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}) \land (\lnot\ivr\limply\ausfml)}}}
\end{sequentdeduction}
\end{proof}
Every time we need the derived axiom \irref{unfold}, we could instead write down this sequent proof to prove it.
It just won't be very efficient, so instead we will settle for deriving axiom \irref{unfold} in the sequent calculus once and then just believing it from then on.

This gives us two ways of establishing the soundness of an axiom.
Either by a mathematical proof from the semantics of the operators.
Or as a derived axiom by a formal proof in sequent calculus from other axioms and proof rules that have already been proved to be sound.
Of course, the first time a new operator is mentioned in any of our axioms, we cannot derive it yet but have to work from its semantics.
But the second time, it may become possible to argue as in a  derived axiom.

\section{Recall: Loop the Loop}

Recall the two (equivalent) axioms for handling while-loops by unwinding the loop:

\begin{calculus}
\cinferenceRule[whileiterateb|$\dibox{\text{unwind}}$]{unfold while loop}
{\linferenceRule[equiv]
  {\dbox{\pifs{\ivr}{\plgroup\ausprg;\pwhile{\ivr}{\ausprg}\prgroup}}{\ausfml}}
  {\axkey{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}}
}{}%
\cinferenceRule[unfold|$\dibox{\text{unfold}}$]{unfold while loop}
{\linferenceRule[equiv]
  {(\ivr\limply\dbox{\ausprg}{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}) \land (\lnot\ivr\limply\ausfml)}
  {\axkey{\dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}}
}{}%
\end{calculus}

Especially the \irref{unfold} axiom makes it very apparent that the deficiency with both axioms is that, when used from left to right, they reduce a property of a while loop to some logic and then the same property of the same loop again.
While the isolated $\ausprg$ loop body can be handled with the other axioms, the \m{\pwhile{\ivr}{\ausprg}} loop is still remaining and could be handled by another \irref{unfold} but then the same issue persists.
This principle of successively unrolling the loop is still perfectly helpful for loops that terminate right away or that always terminate after 1 rounds or after 2 rounds or after some other fixed finite maximum number of iterations such as 5.
But ``most'' loops are not like that.
If the loop terminates after a very large number of loop iterations, or if we cannot know ahead of time after which fixed natural number of loop iterations it terminates, then unrolling the loop does not help, because there will always be a conjunct referring to what happens if the loop repeats again.\footnote{
There is a very subtle argument why such unrolling is still enough progress to prove properties of loops \cite{DBLP:journals/tocl/Platzer15}, but this is beyond the scope here.
}

%%%%%%%%%%%%%%%%%%%%

\section{Loops and Nondeterministic Repetition}

In order to resolve these issues with how to prove loops, we will follow a completely systematic approach to develop compositional proof principles for loops. 
Successive loop unrolling with the \irref{unfold} axiom ran into the difficulty that it had to predict perfectly when the loop stops because the loop condition $\ivr$ is false.
The number of iterations for a while loop is hard to predict.
It was of course defined exactly in the semantics:
\begin{enumerate}
\addtocounter{enumi}{4}
\item \m{\iaccess[\pwhile{\ivr}{\asprg}]{\I} = \big\{(\iget[state]{\I},\iget[state]{\It}) \with}
there are an $n$ and states
\(\iget[state]{\Iz[0]}=\iget[state]{\I},\iget[state]{\Iz[1]},\iget[state]{\Iz[2]},\dots,\iget[state]{\Iz[n]}=\iget[state]{\It}\)
such that for all $0\leq i<n$:
\textcircled{1} the loop condition is true \m{\imodels{\Iz[i]}{\ivr}} and
\textcircled{2} from state $\iget[state]{\Iz[i]}$ is state $\iget[state]{\Iz[i+1]}$ reachable by running $\asprg$ so
\m{\iaccessible[\asprg]{\Iz[i]}{\Iz[i+1]}}
and \textcircled{3} the loop condition is false \m{\inonmodels{\Iz[n]}{\ivr}} in the end$\big\}$
\end{enumerate}
But mapping this exact termination of while loops into logic will be a distraction from the essential aspects.
In order to understand the principle of repetition in loops we will, instead, make it principally unpredictable when exactly the loop terminates by entirely removing the loop guard $\ivr$.
For one thing, it is easier to understand the principle of repetition without simultaneously having to worry about the impact that loop guards have.
After understanding the principle of repetition, we will then come back to apply the knowledge we gained from that excursion to the original question of while loops.


In order to understand the principle of repetition, we will, in this lecture, investigate the \dfn[repetition!nondeterministic]{nondeterministic repetition} $\prepeat{\asprg}$.
The effect of the nondeterministic repetition $\prepeat{\asprg}$ is to repeat the program $\asprg$ any arbitrary $n$ number of times for any nondeterministically chosen natural number $n\in\naturals$.
We cannot predict $n$.
Just like in a regular expression such as \(\texttt{a}^*\) which matches any natural number of occurrences of the letter \texttt{a}, for example \texttt{aaa} or \texttt{aaaaa}, the nondeterministic repetition $\prepeat{\asprg}$ repeats $\asprg$ any number of times, for example \(\asprg;\asprg;\asprg\) or  \(\asprg;\asprg;\asprg;\asprg;\asprg\).
Since the nondeterministic repetition $\prepeat{\asprg}$ can repeat program $\asprg$ any arbitrary number of times, this makes the resulting programs nondeterministic, because they can run in more than one way.

In fact, this is a little bit like what happens for \(\pwhile{\ivr}{\asprg}\) loops in practice, too.
In principle, the computations of \(\pwhile{\ivr}{\asprg}\) are deterministic because from every initial state there is at most one run of this program and this run takes some deterministic number of loop iterations.
But in practice, it's not like we could easily tell how often exactly a \(\pwhile{\ivr}{\asprg}\) loop repeats.
If we could we would have solved the halting problem, which Church-Turing thought of as a difficult one.
So when we try to understand a \(\pwhile{\ivr}{\asprg}\) loop, realistically, we would also often have to say that this loop might repeat any number of times, just because we don't know any better.

For the sake of better understanding while loops, let's extend the syntax as follows:\footnote{
Nondeterministic programs usually include a slightly different set of operators \cite{DBLP:conf/focs/Pratt76,Harel_et_al_2000}. Here we consider nondeterministic while programs which only involve a minimal change compared to deterministic while programs.
}
\begin{definition}[Nondeterministic program] \label{def:nondeterministic-program}
\dfn[program!nondeterministic]{Nondeterministic while programs} are defined by extending the grammar of deterministic while programs with one additional case, highlighted in \textbf{bold}:
\begin{equation*}
  \asprg,\bsprg ~\bebecomes~
  \pupdate{\pumod{x}{\astrm}}
  \alternative
  \ptest{\ivr}
  \alternative
  \pif{\ivr}{\asprg}{\bsprg}
  \alternative
  \asprg;\bsprg
  \alternative
  \pwhile{\ivr}{\asprg}
  \alternative
  \medit{\prepeat{\asprg}}
\end{equation*}
\end{definition}

Of course, as soon as we add a new operator into our syntax, we have to give it a meaning.
The meaning of nondeterministic repetition is quite different from the meaning of all the other deterministic program operators, precisely because its effect is nondeterministic.
But our semantics of programs is already perfectly prepared for that, because it is a relation \(\iaccess[\asprg]{\I} \subseteq \linterpretations{\Sigma}{V} \times \linterpretations{\Sigma}{V}\) on states.
In deterministic programs, at most one final state is reachable from every initial state.
In nondeterministic programs, instead, it can also happen that multiple states are reachable.
The nondeterministic while program \(\prepeat{\plgroup\pupdate{\pumod{x}{x+2}}\prgroup}\) for example will repeatedly increment variable $x$ by 2 for any number of times.
It might increment $x$ by 2 or by 10 or by 0 or by 414 or \dots, but not by 3 because that's an odd number.
Even if this may sound like a lot of options, it turns out that the semantics of nondeterministic repetition is actually much easier than that of while loops, precisely because we do not need to keep track of when exactly it exits on account of the loop guard $\ivr$.

\begin{definition}[Transition semantics of nondeterministic while programs] \label{def:program-transition}
\indexn{\lenvelope\asprg\renvelope|textbf}%
Each nondeterministic while program $\asprg$ is interpreted semantically as a binary reachability relation \m{\iaccess[\asprg]{\I}\subseteq\linterpretations{\Sigma}{V}\times\linterpretations{\Sigma}{V}} over states, defined inductively by extending the definition for deterministic while programs with the following case
\begin{enumerate}
\addtocounter{enumi}{5}

\item \m{\iaccess[\prepeat{\asprg}]{\I} = \big\{(\iget[state]{\I},\iget[state]{\It}) \with}
there are an $n$ and states
\(\iget[state]{\Iz[0]}=\iget[state]{\I},\iget[state]{\Iz[1]},\iget[state]{\Iz[2]},\dots,\iget[state]{\Iz[n]}=\iget[state]{\It}\)
such that
\m{\iaccessible[\asprg]{\Iz[i]}{\Iz[i+1]}} for all $0\leq i<n\}$\\
That is, state $\iget[state]{\Iz[i+1]}$ is reachable from state $\iget[state]{\Iz[i]}$ by running $\asprg$ for all $i$.
\end{enumerate}
\end{definition}

Comparing the definition of the semantics, the meaning of nondeterministic repetition is much easier to define even if it allows more behavior, because all it says is that the nondeterministic repetition $\prepeat{\asprg}$ repeats (and leaves open how often exactly).
But while loops are easy to get back from nondeterministic repetitions and tests, because while loops \(\pwhile{\ivr}{\ausprg}\) are equivalent to guarding the loop body of a nondeterministic repetition by the test $\ptest{\ivr}$ and guarding the loop exit by the test $\ptest{\lnot\ivr}$ so that no execution can succeed that stops too early or too late:

\begin{equation}
  \pwhile{\ivr}{\ausprg} ~\mequiv~ \prepeat{\plgroup\ptest{\ivr};\ausprg\prgroup}; \ptest{\lnot\ivr}
  \label{eq:while-def}
\end{equation}
This equivalence of while programs with nondeterministic repetitions using suitable tests gives us confidence that we will later be able to understand while loops if we just first understand nondeterministic repetition itself.

Remember that the box modality in the formula \(\dbox{\prepeat{\ausprg}}{\ausfml}\) considers \emph{all} possible executions of the nondeterministic repetition $\prepeat{\ausprg}$.
So \(\dbox{\prepeat{\ausprg}}{\ausfml}\) really says, but more concisely, that the following infinite collection of formulas is true:
\[
\ausfml,\quad \dbox{\ausprg}{\ausfml},\quad \dbox{\ausprg;\ausprg}{\ausfml},\quad \dbox{\ausprg;\ausprg;\ausprg}{\ausfml},\quad \dbox{\ausprg;\ausprg;\ausprg;\ausprg}{\ausfml},\quad \dbox{\ausprg;\ausprg;\ausprg;\ausprg}{\ausfml},\quad \dbox{\ausprg;\ausprg;\ausprg;\ausprg;\ausprg}{\ausfml},\quad \dots
\]


\section{Induction}

Of course it would be very easy to also design and justify an axiom that unwinds a nondeterministic repetition, just like axioms \irref{whileiterateb} and \irref{unfold} do for while loops:
\[
\cinferenceRule[iterateb|$\dibox{{}^*}$]{iteration/repeat unwind} %|$\dibox{{}^{*n}}$
{\linferenceRule[equiv]
  {\ausfml \land \dbox{\ausprg}{\dbox{\prepeat{\ausprg}}{\ausfml}}}
  {\axkey{\dbox{\prepeat{\ausprg}}{\ausfml}}}
}{}%
\]
But that axiom also still shares the exact same problem of reducing a property of a nondeterministic repetition to a logical combination involving the same property of the same nondeterministic repetition.

There isn't much that we can do to improve matters in how the iteration axiom \irref{iterateb} insists on the postcondition $\ausfml$ in the first conjunct, because nondeterministic loops are allowed to repeat 0 times, which keeps them in the initial state.
So unless we show that the postcondition $\ausfml$ is true in the initial state, the property \(\dbox{\prepeat{\ausprg}}{\ausfml}\) can never be true.
But the second conjunct of axiom \irref{iterateb} retains the exact same property \(\dbox{\prepeat{\ausprg}}{\ausfml}\) after \(\dbox{\ausprg}{}\).
Let's develop a new axiom of the form:
\[
\dbox{\prepeat{\ausprg}}{\ausfml} \lbisubjunct \ausfml \land \dots
\]

What we definitely need to show in addition to $\ausfml$ is that \(\dbox{\ausprg}{\ausfml}\) is true.
But since we already showed that $\ausfml$ is true in the first conjunct, it is enough for us to show the implication \(\ausfml\limply\dbox{\ausprg}{\ausfml}\).
Unfortunately, showing just those two conditions is not enough:
\[
\dbox{\prepeat{\ausprg}}{\ausfml} \lbisubjunct \ausfml \land (\ausfml\limply\dbox{\ausprg}{\ausfml})
\]
because the second conjunct only says that the implication \(\ausfml\limply\dbox{\ausprg}{\ausfml}\) is true in the current state, which says nothing about states that are reached after the loop \(\prepeat{\ausprg}\) ran repeatedly, say, for 10 times.
We need to know that the implication \(\ausfml\limply\dbox{\ausprg}{\ausfml}\) also holds again after the loop ran a bunch more times.

These thoughts lead to the induction axiom for loops \cite{Platzer17}:
\begin{lemma}
  The induction axiom \irref{I} is sound:
\[
\cinferenceRule[Ieq|I]{loop induction}
{\linferenceRule[equiv]
  {\ausfml \land \dbox{\prepeat{\ausprg}}{(\ausfml\limply\dbox{\ausprg}{\ausfml})}}
  {\axkey{\dbox{\prepeat{\ausprg}}{\ausfml}}}
}{}%
\]
\end{lemma}
\begin{proof}
In order to prove validity, we consider any state $\iget[state]{\I}$ and show that 
\[\imodels{\I}{{\dbox{\prepeat{\ausprg}}{\ausfml}} \lbisubjunct {\ausfml \land \dbox{\prepeat{\ausprg}}{(\ausfml\limply\dbox{\ausprg}{\ausfml})}}}\]
As usual the proof considers each direction separately.
\begin{enumerate}
\item[``$\limply$''] 
This direction is easy to see because a nondeterministic repetition $\prepeat{\ausprg}$ is allowed to repeat 0 times such that \m{\imodels{\I}{\dbox{\prepeat{\ausprg}}{\ausfml}}} implies \m{\imodels{\I}{\ausfml}}.
Also if $\ausfml$ is true after any number of repetitions of $\prepeat{\ausprg}$ then also \(\imodels{\I}{\dbox{\prepeat{\ausprg}}{\dbox{\ausprg}{\ausfml}}}\) after at least one iteration.
This implies the right hand side.

\item[``$\lylpmi$'']
This direction is by induction on the number $n$ of loop iterations.
\begin{enumerate}
\item[$n=0$:] The first conjunct implies $\ausfml$ holds in the final state, which is the initial state $\iget[state]{\I}$ after 0 repetitions.
\item[$n+1$:]
By induction hypothesis, $\ausfml$ is always true after $n$ repetitions from initial state $\iget[state]{\I}$.
In order to show that $\ausfml$ is also always true after $n+1$ repetitions from $\iget[state]{\I}$, consider any intermediate state $\iget[state]{\Iz}$ such that \(\iaccessible[\prepeat{\asprg}]{\I}{\Iz}\) with $n$ iterations and any final state $\iget[state]{\It}$ with \(\iaccessible[\asprg]{\Iz}{\It}\).
By induction hypothesis, \(\imodels{\Iz}{\ausfml}\).
By the right conjunct of the assumption also \(\imodels{\Iz}{\ausfml\limply\dbox{\ausprg}{\ausfml}}\).
Consequently, \(\imodels{\It}{\ausfml}\).
\qedhere
\end{enumerate}
\end{enumerate}
\end{proof}


\section{Proofs of Loops}

The induction axiom \irref{Ieq} is a wonderful equivalence but it still comes with the challenge of reducing a property of a loop to another property of the same loop.
Even if the other property \(\ausfml\limply\dbox{\ausprg}{\ausfml}\) comes with an assumption to use, it's still a property of a loop.
But now we can combine the induction axiom \irref{I} with another important proof principle: generalization.
G\"odel's generalization rule \irref{G} says that one way of proving a postcondition of a box modality is to just prove the postcondition itself:

\[
\cinferenceRule[G|G]{$\dbox{}{}$ generalization} %|$gen$
{\linferenceRule[formula]
  {\lsequent[g]{}{\ausfml}}
  {\lsequent[L]{}{\dbox{\ausprg}{\ausfml}}}
}{}%
\]

Indeed, if $\ausfml$ has a proof then it is valid by soundness, so true in all states, hence also true in all states after running program $\ausprg$.
Of course, G\"odel's generalization rule \irref{G} cannot soundly keep any information from $\Gamma,\Delta$ for the premise, because it might no longer be true after $\ausprg$.
Using the G\"odel rule \irref{G} after the loop induction axiom \irref{Ieq} reduces the proof of \(\dbox{\prepeat{\ausprg}}{\ausfml}\) to a proof that $\ausfml$ is true in the initial state and to a proof that the implication \(\ausfml\limply\dbox{\ausprg}{\ausfml}\) is valid, so true in all states:

\[
\dinferenceRule[invindgen|ind$'$]{inductive invariant}
{\linferenceRule[sequent]
  {\lsequent[L]{}{\ausfml}
  &\lsequent[g]{\ausfml}{\dbox{\ausprg}{\ausfml}}}
  {\lsequent[L]{}{\dbox{\prepeat{\ausprg}}{\ausfml}}}
}{}%
\]
This proof rule \irref{invindgen} says that for proving \m{\dbox{\prepeat{\ausprg}}{\ausfml}} from assumptions $\Gamma$ with alternatives $\Delta$ (conclusion) it suffices to prove the postcondition $\ausfml$ from assumptions $\Gamma$ with alternatives $\Delta$ (left premise) in addition to proving that the postcondition $\ausfml$ is inductive so \(\dbox{\ausprg}{\ausfml}\) is true in any state where $\ausfml$ is true (right premise).
Proving that rule \irref{invindgen} is sound is easy by deriving it from axiom \irref{Ieq} and rule \irref{G}.

\begin{lemma}
  The basic loop induction rule \irref{invindgen} is a derived rule and, thus, sound:
  \[
  \cinferenceRuleQuote{invindgen}
  \]
\end{lemma}
\begin{proof}
Showing that rule \irref{invindgen} is a derived rule requires us to derive its conclusion in sequent calculus from its premises, which we derive from axiom \irref{Ieq} with rule \irref{G}:
\begin{sequentdeduction}[array]
\linfer[Ieq]
{\linfer[andr]
{\lsequent[L]{}{\ausfml}
  !\linfer[G]
    {\linfer[implyr]
      {\lsequent[g]{\ausfml}{\dbox{\ausprg}{\ausfml}}}
      {\lsequent[g]{}{\ausfml\limply\dbox{\ausprg}{\ausfml}}}
    }
    {\lsequent[L]{} {\dbox{\prepeat{\ausprg}}{(\ausfml\limply\dbox{\ausprg}{\ausfml})}}}
    }
{\lsequent[L]{}{\ausfml\land\dbox{\prepeat{\ausprg}}{(\ausfml\limply\dbox{\ausprg}{\ausfml})}}}
}
{\lsequent[L]{}{\dbox{\prepeat{\ausprg}}{\ausfml}}}
\end{sequentdeduction}
\end{proof}

\section{Loop Invariants}

Proof rule \irref{invindgen} properly reduces the proof of a nondeterministic repetition to a proof of subquestions that do not involve the repetition again.
Its only downside is that the rule no longer comes in the form of an equivalence axiom.
And indeed there are cases where the \irref{invindgen} rule does not work like it should.
How could that happen?

\clearturnpage

Everything that proof rule \irref{invindgen} proves is valid, after all the rule is sound because it is derived from sound axioms and proof rules.
There are, however, cases where proof rule \irref{invindgen} does not prove the conclusion even though it is valid.
The problem is very apparent from how rule \irref{invindgen} is derived with the help of the \irref{G} rule which misplaces a whole \(\dbox{\prepeat{\ausprg}}{}\) modality.
That might have contained valuable information about what exactly changes as the loop runs, which is lost when setting out for an isolated proof of the postcondition.

We can make up for that by retaining a little more information about the long history of loop body executions by providing a little more information in a loop invariant $\inv$ that we choose freely and perform induction with invariant $\inv$ instead.
Of course, we then also have to prove that the loop invariant $\inv$ we dreamed up implies the original postcondition we were interested in (third premise):

\[
\dinferenceRule[loop|loop]{inductive invariant}
{\linferenceRule[sequent]
  {\lsequent[L]{} {\inv}
  &\lsequent[g]{\inv} {\dbox{\ausprg}{\inv}}
  &\lsequent[g]{\inv} {\ausfml}}
  {\lsequent[L]{} {\dbox{\prepeat{\ausprg}}{\ausfml}}}
}{}%
\]

This rule can easily be derived from the monotonicity principle that if $\ausfml$ implies $\busfml$ then if $\ausfml$ is always true after running $\ausprg$ then $\busfml$ is also always true after running $\ausprg$:
\[
\cinferenceRule[Mb|M${\dibox{\cdot}}$]{$\dbox{}{}$ monotone}
{\linferenceRule[formula]
  {\lsequent[g]{\ausfml}{\busfml}}
  {\lsequent[L]{\dbox{\ausprg}{\ausfml}}{\dbox{\ausprg}{\busfml}}}
}{}%
\]


\begin{lemma}
  Loop rule \irref{loop} is a derived rule and thus sound:
  \[
  \cinferenceRuleQuote{loop}
  \]
\end{lemma}
\begin{proof}
The proof rule \irref{loop} can be derived from rule \irref{invindgen} by rule \irref{Mb}:
\begin{sequentdeduction}[array]
\linfer[cut]
{\linfer[invindgen]
{\lsequent[L]{}{\inv}
  !
  \lsequent[g]{\inv} {\dbox{\ausprg}{\inv}}
}
{\lsequent[L]{}{\dbox{\prepeat{\ausprg}}{\inv}}}
!
\linfer[Mb]
{\lsequent{\inv} {\ausfml}}
{\lsequent[L]{\dbox{\prepeat{\ausprg}}{\inv}} {\dbox{\prepeat{\ausprg}}{\ausfml}}}
}
{\lsequent[L]{}{\dbox{\prepeat{\ausprg}}{\ausfml}}}
\end{sequentdeduction}
\end{proof}

\section{Loop Invariants for While Loops}

This is a great answer for nondeterministic repetitions $\prepeat{\ausprg}$ that repeat $\ausprg$ any number of times but our actual interest was in understanding the \(\pwhile{\ivr}{\ausprg}\) loop which says precisely when to repeat and when to stop according to the loop guard $\ivr$.
Let's take what we learned about repetition by and large from $\prepeat{\ausprg}$ and apply it back to while loops.

The following version of the loop invariant rule for \(\pwhile{\ivr}{\ausprg}\) loops (which we simply call \irref{whileloop}) can be derived from the \irref{loop} rule for nondeterministic repetitions $\prepeat{\ausprg}$ using the definition of the former using the latter from \rref{eq:while-def}:
\[
\cinferenceRule[whileloop|while]{while loop invariant}
{\linferenceRule[sequent]
  {\lsequent[L]{}{\inv}
  &
  \lsequent[G]{\inv,\ivr}{\dbox{\ausprg}{\inv}}
  &
  \lsequent[G]{\inv,\lnot\ivr}{\ausfml}}
  {\lsequent[L]{}{
    \dbox{\pwhile{\ivr}{\ausprg}}{\ausfml}}}
}{}
\]

The DL sequent calculus consists of the axioms that we have seen already oriented into the direction that turns properties of complex programs into properties of simpler programs.
It also includes an assignment axiom that takes care of renaming variables appropriately.
%Most importantly, the calculus includes an induction / invariant rule for while-loops as a replacement for the \irref{inv} rule of the Hilbert calculus.
In the left most branch, rule \irref{whileloop} proves that the induction invariant $J$ is true in the beginning.
On the middle branch, rule \irref{whileloop} proves that the invariant is true again after executing the loop body $\alpha$ once, if only $J$ was true before executing the loop body and the loop test $\ivr$ was true (otherwise the loop doesn't execute).
On the right branch, rule \irref{whileloop} proves that the invariant $J$ together with the knowledge that the loop test $\ivr$ must have failed for the loop to terminate at all imply the original postcondition $\phi$.

Proving that this \irref{whileloop} rule for while loops is a derived proof rule is an excellent exercise.
The rule is also an excellent example how the study of something more general can provide systematic insights about something more specific.


\section{Proving a Loopy Program}

Enough theory.
Let's turn to an actual program with a loop that we would like to prove.
Consider the following program:

\begin{minipage}{\textwidth}
\begin{verbatim}
  s := 0;
  i := 0;
  while (i<x) {
    s := s+2*i+1;
    i := i+1
  }
\end{verbatim}  
\end{minipage}

What does this program do? How can we prove it?

\clearturnpage

\section{Sum Up the Square}

Let $\beta$ be the above while program. 
We set out to prove the DL formula \m{\dbox{\beta}{s=x*x}} saying that the program $\beta$ always computes the square of $x$ in variable $s$ in this section.
For the most part, the proof of DL formula \m{\dbox{\beta}{s=x*x}} is completely canonical.
The one step that is not is, of course, also the most difficult one.
The \irref{whileloop} proof rule expects a loop invariant $\inv$ as input.
Do you have a good idea?

Let's proceed very systematically.
The most obvious possibility for a loop invariant $\inv$ is to choose the postcondition $s=x*x$ because that will then clearly imply the postcondition since every formula is very good at implying itself.
So let's use the following abbreviation and loop invariant:
\begin{align}
  \alpha &~\mdefequiv~ s := s+2*i+1; i := i+1 \notag\\
  \inv &~\mdefequiv~ s = x*x \label{eq:s=x*x}
\end{align}
After this crucial choice, the rest of the proof steps are entirely systematic:
\begin{sequentdeduction}[array]
\linfer[composeb]
{\linfer[assignbeqr]
{\linfer[composeb]
{\linfer[assignbeqr]
{\linfer[whileloop]
{\lsequent{s=0,i=0} {\inv}
!\lsequent{\inv,i<x} {{}\dbox{\alpha}{\inv}}
!\lsequent{\inv,\lnot(i<x)} {s=x*x}}
{\lsequent{s=0, i=0} {{}[\pwhile{i<x}{\alpha}] s=x*x}}
}
{\lsequent{s=0} {{}[i:=0] [\pwhile{i<x}{\alpha}] s=x*x}}
}
{\lsequent{s=0} {{}[i:=0; \pwhile{i<x}{\alpha}] s=x*x}}
}
{\lsequent{} {{}[s:=0][i:=0; \pwhile{i<x}{\alpha}] s=x*x}}
}
{\lsequent{} {{}[s:=0;i:=0; \pwhile{i<x}{\alpha}] s=x*x}}
\end{sequentdeduction}
Note that this proof cannot directly use axiom \irref{assignb} to substitute in the new value $0$ for $i$ because it still keeps changing in the loop. Instead rule \irref{assignbeqr} is used from \rref{fig:extrarules}, which keeps it around as an equational assumption $i=0$ in the antecedent instead.
For notational convenience, the above proof uses one optimization where the \irref{assignbeqr} step for $s:=0$ keeps using variable $s$ instead of a new variable name $y$, because the context $\Gamma,\Delta$ is empty and the right hand side of the assignment does not mention $s$ either.

\begin{figure}[tbp]
  \centering
  \begin{calculus}
\dinferenceRule[assignbeqr|$\dibox{:=}_=$]{assignb}%{assignment equational rule}
  {\linferenceRule[sequent]
    {\lsequent[L]{y=\austrm} {p(y)}}
    {\lsequent[L]{} {\dbox{\pupdate{\umod{x}{\austrm}}}{p(x)}}}
   ~~
  }
  {\text{$y$ new}}
  \end{calculus}~~~~%
  \begin{calculus}
    \cinferenceRule[applyeqr|=\rightrule]{apply equation}
    {\linferenceRule[sequent]
      {\lsequent[L]{x=\astrm}{p(\astrm)}}
      {\lsequent[L]{x=\astrm}{p(x)}}
    }{}%
  \end{calculus}~~~~%
  \begin{calculus}
    \cinferenceRule[applyeql|=\leftrule]{apply equation}
    {\linferenceRule[sequent]
      {\lsequent[L]{x=\astrm,p(\astrm)}{}}
      {\lsequent[L]{x=\astrm,p(x)}{}}
    }{}%
  \end{calculus}
  \caption{Some proof rules related to equations}
  \label{fig:extrarules}
\end{figure}

While the proof of the right branch is entirely trivial by rule \irref{id} with \rref{eq:s=x*x}, the middle branch with the induction step poses quite a challenge, because \rref{eq:s=x*x} is not true after $\alpha$ even if it was true before, because the program $\alpha$ changes $s$ while keeping $x$ constant.
So that loop invariant \rref{eq:s=x*x} was too naive.
Instead, let's choose a loop invariant that says the same thing, just about the loop variable $i$ instead of $x$ because the result about the square of $x$ is only attained in the end with partial progress till $i$:
\begin{align}
  \inv &~\mdefequiv~ s = \boldsymbol{i}*\boldsymbol{i} \label{eq:s=i*i}
\end{align}
Thanks to our use of abbreviation $\inv$ for the loop invariant that change does not change the structure of the above proof but gives us a new chance of proving its premises.
Of course now the proof of the right premise becomes less trivial since \irref{id} no longer suffices, but let's first worry about the middle branch that gave us so much trouble before.

The---most exciting---middle branch \(\lsequent{\inv,i<x} {{}\dbox{\alpha}{\inv}}\) can be proved using the usual decompositions with axioms (inside out for assignments) and the rule \irref{applyeqr} to replace the left hand side $s$ of an equation $s=i*i$ with the right hand side $i*i$:

\begin{sequentdeduction}[array]
\linfer
{\linfer[composeb]
{\linfer[assignb]
{\linfer[assignb]
{\linfer[applyeqr]
{\linfer[qear]
{\lclose}
{\lsequent{s = i*i,i<x} {{} i*i+2*i+1 = (i+1)*(i+1)}}
}
{\lsequent{s = i*i,i<x} {{} s+2*i+1 = (i+1)*(i+1)}}
}
{\lsequent{s = i*i,i<x} {{}[s := s+2*i+1] (s = (i+1)*(i+1))}}
}
{\lsequent{s = i*i,i<x} {{}[s := s+2*i+1] [i := i+1] (s = i*i)}}
}
{\lsequent{s = i*i,i<x} {{}[s := s+2*i+1; i := i+1] (s = i*i)}}
}
{\lsequent{\inv,i<x} {{}\dbox{\alpha}{\inv}}}
\end{sequentdeduction}
But as soon as we march on to the right branch \(\lsequent{\inv,\lnot(i<x)} {s=x*x}\), which is:
\[\lsequent{s=i*i,\lnot(i<x)} {s=x*x}\]
we find it impossible to prove, because it simply is not true.
What could have gone wrong?

Of course. The loop invariant \rref{eq:s=i*i} was no good either.
While it is inductive (the middle branch proves) it fails to imply the postcondition (the right branch does not).
Contrast this with the loop invariant \rref{eq:s=x*x} which implies the postcondition but failed to be inductive.
Neither are any good for proving the original DL formula.
But if \rref{eq:s=i*i} is already inductive, then it might merely be missing additional knowledge.

When thinking back about where loop invariants came from (dropping $\dbox{\prepeat{\ausprg}}{}$) then the only information that could be missing in a loop invariant is to retain additional information about the past iterations that we still need to prove the postcondition.
Indeed, \rref{eq:s=i*i} successfully relates the square variable $s$ to the square of the loop variable $i$ but doesn't tell us anything about how any of them relate to the input variable $x$.
The loop guard tells us that $i<x$ holds when the loop body runs and that $\lnot(i<x)$ holds when the loop exits.
But it doesn't tell us that we indeed went about increasing $i$ all the time until its value equals $x$.
So let's discard the invariant candidate \rref{eq:s=i*i} and move on to:
\let\extra\boldsymbol%
\begin{align}
  \inv &~\mdefequiv~ \boldsymbol{i\leq x} \land s = i*i \label{eq:invdef}
\end{align}
Having made that chance of loop invariant, the proof of the middle branch needs to be adapted as indicated in boldface, but fortunately still proves:
\begin{sequentdeduction}[array]
\linfer
{\linfer[composeb]
{\linfer[assignb]
{\linfer[assignb]
{\linfer[andl]
{\linfer[applyeqr]
{\linfer[qear]
{\lclose}
{\lsequent{\extra{i\leq x} , s = i*i,i<x} {{} (\extra{i+1\leq x} \land i*i+2*i+1 = (i+1)*(i+1))}}
}
{\lsequent{\extra{i\leq x} , s = i*i,i<x} {{} (\extra{i+1\leq x} \land s+2*i+1 = (i+1)*(i+1))}}
}
{\lsequent{\extra{i\leq x} \land s = i*i,i<x} {{} (\extra{i+1\leq x} \land s+2*i+1 = (i+1)*(i+1))}}
}
{\lsequent{\extra{i\leq x} \land s = i*i,i<x} {{}[s := s+2*i+1] (\extra{i+1\leq x} \land s = (i+1)*(i+1))}}
}
{\lsequent{\extra{i\leq x} \land s = i*i,i<x} {{}[s := s+2*i+1] [i := i+1] (\extra{i\leq x} \land s = i*i)}}
}
{\lsequent{\extra{i\leq x} \land s = i*i,i<x} {{}[s := s+2*i+1; i := i+1] (\extra{i\leq x} \land s = i*i)}}
}
{\lsequent{\inv,i<x} {{}\dbox{\alpha}{\inv}}}
\end{sequentdeduction}
The right branch \(\lsequent{\inv,\lnot(i<x)} {s=x*x}\) can now be proved easily thanks to \rref{eq:invdef}.
The easiest way is a \irref{cut} to show that $i=x$ follows by arithmetic from $i\leq x$ and $\lnot(i<x)$:
\begin{sequentdeduction}[array]
\linfer
{\linfer[andl]
{\linfer[cut]
{\linfer[qear]
  {\lclose}
  {\lsequent{i\leq x, \lnot(i<x)} {i=x}}
!\linfer[applyeqr]
{\linfer[id]
{\lclose}
{\lsequent{s=i*i, i= x} {s = i*i}}
}
{\lsequent{s=i*i, i= x} {s = x*x}}
}
{\lsequent{i\leq x, s=i*i, \lnot(i<x)} {s = x*x}}
}
{\lsequent{i\leq x \land s=i*i, \lnot(i<x)} {s = x*x}}
}
{\lsequent{\inv, \lnot(i<x)} {s = x*x}}
\end{sequentdeduction}
Finally the only thing that remains to be done is to prove the left branch \(\lsequent{s=0,i=0} {\inv}\) (again there is a simple branch with trivial arithmetic on $0=0*0$):
\begin{sequentdeduction}[array]
\linfer
{\linfer[applyeqr]
{\linfer[andr]
{\lsequent{s=0,i=0} {0 \leq x}
!\linfer[qear]
  {\lclose}
  {\lsequent{\dots} {0 = 0*0}}}
{\lsequent{s=0,i=0} {0\leq x \land 0 = 0*0}}
}
{\lsequent{s=0,i=0} {i\leq x \land s = i*i}}
}
{\lsequent{s=0,i=0} {\inv}}
\end{sequentdeduction}
Wait a second. 
We cannot prove that property. Shocking!
What's wrong? Probably yet another mistake in the choice of the loop invariant $\inv$ from \rref{eq:invdef}.
How could we change it?

It is quite crucial to realize that whatever we do to try and find another loop invariant, it won't succeed, simply because the formula \(\dbox{\beta}{\,s=x*x}\) we were trying to prove is not valid.
In fact the above proof attempt already points out what we're missing.
We simply do not know if $0\leq x$ is true in the beginning, but that is actually good news because the original DL formula is not even valid for negative $x$, so it cannot have a (sound) proof.

Obviously, all we need to do to get a proof now is to assume the precondition $x\geq0$ in the beginning to obtain a provable DL formula and preserve this knowledge in the appropriate places of the proof:
\[
x\geq0 \limply \dbox{s:=0;i:=0; \pwhile{i<x}{\plgroup s := s+2*i+1; i := i+1\prgroup}} {\,s=x*x}
\]

\bibliography{platzer,bibliography}
\end{document}