report done, 1st submission

This commit is contained in:
Claudio Maggioni 2023-03-28 10:18:35 +02:00
parent 6a297f80c2
commit 7b6c5f7201
3 changed files with 56 additions and 16 deletions

View file

@ -1,5 +1,5 @@
# Assignment 1 -- Software Analysis # Assignment 1 -- Software Analysis
Dafny *pygments* lexer stored in `pygmentize.py` directory thanks to: Dafny *pygments* lexer stored in `pygmentize.py` implemented by:
https://github.com/Locke/pygments-dafny/ https://github.com/Locke/pygments-dafny/

Binary file not shown.

View file

@ -66,10 +66,13 @@ Assignment 1 -- Software Analysis \\\vspace{0.5cm}
\begin{document} \begin{document}
\maketitle \maketitle
\tableofcontents
\section{Choice of Sorting Algorithm} \section{Choice of Sorting Algorithm}
In order to choose I browse the implementations of some classical sorting
algorithms to find one that strikes a good tradeoff between ease-of-proof and a
solid understanding of how it works on my part.
I decide to implement and verify the correctness of selection sort. The I decide to implement and verify the correctness of selection sort. The
algorithm sorts a given list in place with average and worst-case complexity algorithm sorts a given list in place with average and worst-case complexity
$O(n^2)$. It works by iteratively finding either the minimum or maximum element $O(n^2)$. It works by iteratively finding either the minimum or maximum element
@ -86,10 +89,6 @@ in algorithm \ref{alg:sel}.
\begin{algorithmic}[1] \begin{algorithmic}[1]
\Require $a$ list of values \Require $a$ list of values
\Ensure $a$ is sorted in-place \Ensure $a$ is sorted in-place
\If{$a = \emptyset$}
\State \Return
\EndIf
\State $s \gets 0$ \State $s \gets 0$
\While{$s < |a|$} \While{$s < |a|$}
\State {$m \gets \argmin_x{a[x]}$ for $s \leq x < |a|$} \State {$m \gets \argmin_x{a[x]}$ for $s \leq x < |a|$}
@ -154,7 +153,7 @@ procedural implementation of the assignment
$$m \gets \argmin_x{l[x]} \text{\hspace{1cm} for \hspace{1cm}} s \leq x < |l|$$ $$m \gets \argmin_x{l[x]} \text{\hspace{1cm} for \hspace{1cm}} s \leq x < |l|$$
at line 6 of the pseudocode. at line 3 of the pseudocode.
\section{Verification} \section{Verification}
@ -282,21 +281,62 @@ decreases a.Length - i
The only assignments to variable \textit{min} are at line 11 and line 17 of the The only assignments to variable \textit{min} are at line 11 and line 17 of the
pseudocode, where \textit{min} is initialized to $s$ and \textit{min} is pseudocode, where \textit{min} is initialized to $s$ and \textit{min} is
assigned the value of $i$ respectively. assigned the value of $i$ respectively. Therefore we can say the value of
\textit{min} at any point where is in scope is either $s$ or $\in [s + 1,|a|)$
as it is assigned a possible value of $i$ \textit{inside} the loop. We can
formalize this fact with an invariant:
\begin{minted}{dafny}
invariant s <= min < a.Length
\end{minted}
{\color{red}TBD} Finally % it's here for you, it's the last member of the DK crew
we can define a loop invariant for the values of the list element referenced by
\textit{min}. As the loop scans for values referenced by $i$ less than
\mintinline{dafny}{a[min]}, updating \textit{min} with the value of $i$ when
this is true, we can say that for all values smaller than $i$ in the scanned
region \mintinline{dafny}{a[min]} indeed contains the smallest value. This fact
in predicate form results in the following loop invariant:
\begin{minted}{dafny}
invariant forall j: int :: s <= j < i ==> a[min] <= a[j]
\end{minted}
\begin{verbatim} \subsection{Dafny implementation with specification}
Did you introduce some that you then realized were not needed? The Dafny implementation of selection sort complete with the specification
explained so far can be found in the file \texttt{selectionsort.dfy} found in
the repository:
Any details of the algorithms implementation that you may have had to adjust to \begin{center}
make specification or verification easier. \href{https://gitlab.com/usi-si-teaching/msde/2022-2023/software-analysis/maggioni/assigment-1}{gitlab.com:usi-si-teaching/msde/2022-2023/software-analysis/maggioni/assigment-1}
> if list is empty \end{center}
What were the hardest steps of the verification process? on the \textit{main} branch.
\end{verbatim}
\section{Conclusions}
Writing specifications with Dafny turned out to indeed be a challenge. Choosing
the right predicates and the right places to put them to satisfy Danfy and
Boogie, its embedded theorem prover, was an iterative process requiring many
attempts and careful scrutiny at the reported errors.
As part of this process, I have introduced many \mintinline{dafny}{assert} and
\mintinline{dafny}{assume} clauses to tackle the algorithm portion by portion.
As \mintinline{dafny}{assume}s are basically ``cheats'' w.r.t. the correctness
proving process and \mintinline{dafny}{assert}s were redundant, no such
statement survives in my implementation.
Lines 3-5 of the algorithm's implementation (a simple check of the list $a$
being empty, and an immediate \mintinline{dafny}{return} if this is the case)
are not strictly needed according to the pseudocode. However, handling this edge
case specifically simplifies somewhat the process of determining
the loop invariants as we can assume in all further statements that the list is
non-empty.
Indeed, the hardest step in the verification process was determining appropriate
loop invariants to satisfy the theorem proven. The need for redundant
order-indifferent equality predicates in both loops is quite counter-intuitive
as those invariants merely re-state a property that is true across the method.
\end{document} \end{document}