Fixed some minor errors and clarified some things

This commit is contained in:
David Holland 2021-06-10 11:50:12 +02:00
parent 8d17f39761
commit ea5abff33f
1 changed files with 49 additions and 19 deletions

View File

@ -159,10 +159,23 @@ public class HighSoreTable {
* 2 if new high score
* 1 if otherwise
*/
//@ requires newScore >= 0;
//@ ensures (\forall int i; 0<=i && i<10; newScore <= \old(scores[i])) ==> (\result == 0);
//@ ensures (\exists int i; 0<=i && i<10; newScore > \old(scores[i])) && (\exists int i; 0<=i && i<10; newScore <= \old(scores[i])) ==> (\result == 1);
//@ ensures (\forall int i; 0<=i && i<10; newScore > \old(scores[i])) ==> (\result == 2);
/*@ requires newScore >= 0;
@ ensures (\forall int i; 0<=i && i<10;
@ newScore <= \old(scores[i])
@ )
@ ==> (\result == 0);
@ ensures (\exists int i; 0<=i && i<10;
@ newScore > \old(scores[i])
@ )
@ && (\exists int i; 0<=i && i<10;
@ newScore <= \old(scores[i])
@ )
@ ==> (\result == 1);
@ ensures (\forall int i; 0<=i && i<10;
@ newScore > \old(scores[i])
@ )
@ ==> (\result == 2);
@*/
public int addScore(int newScore) {
// [...]
}
@ -193,7 +206,7 @@ public class HighSoreTable {
@ (\forall int i; 0<=i && i<10;
@ score <= \old(scores[i])
@ );
*/
@*/
//@ ensures lowerThanMin(newScore) ==> (\result == 0);
// [...]
public int addScore(int newScore) {
@ -212,7 +225,7 @@ So for example
@ (\forall int i; 0<=i && i<10;
@ score <= \old(scores[i])
@ );
*/
@*/
//@ ensures lowerThanMin(newScore) ==> (\result == 0);
\end{minted}
@ -235,7 +248,7 @@ In the case of a type mismatch between macro parameter usage and parameter input
@ (\forall int i; 0<=i && i<10;
@ score <= \old(scores[i])
@ );
*/
@*/
//@ ensures lowerThanMin(newScore) ==> (\result == 0);
\end{minted}
@ -252,10 +265,9 @@ Another problem not solved by this approach, especially not with using a simplis
/*@ def lowerThanMin(int score) =
@ (\forall int i; 0<=i && i<10;
@ score <= \old(scores[i])
@ &&
@ lowerThanMin(score-1)
@ && lowerThanMin(score-1)
@ );
*/
@*/
//@ ensures lowerThanMin(newScore) ==> (\result == 0);
\end{minted}
@ -274,10 +286,9 @@ This property of a minimal score can then be reused and clearly states what it d
/*@ def minScore =
@ (\some int score;
@ (\exists int i; 0<=i && i<10; score == scores[i])
@ &&
@ (\forall int i; 0<=i && i<10; score <= scores[i])
@ && (\forall int i; 0<=i && i<10; score <= scores[i])
@ );
*/
@*/
//@ ensures newScore <= \old(minScore) ==> (\result ==0);
\end{minted}
@ -342,14 +353,13 @@ An implementation could therefore be possible using something like this pseudo c
/*@ def minScore =
@ (\ifEx int score;
@ (\exists int i; 0<=i && i<10; score == scores[i])
@ &&
@ (\forall int i; 0<=i && i<10; score <= scores[i])
@ && (\forall int i; 0<=i && i<10; score <= scores[i])
@ \then
@ return score
@ \else
@ return None
@ );
*/
@*/
//@ ensures newScore <= \old(minScore) ==> (\result == 0);
\end{minted}
@ -360,6 +370,26 @@ This could also be something some kind of ghosting variable could achieve, but I
For the time being, one could inline this whole concept and possibly have a working example, though this would not necessarily improve either readability or code reusage, but definitely increase versatility and expressiveness.
\begin{minted}{java}
/*@ ensures
@ (\ifEx int minScore;
@ (\exists int i; 0<=i && i<10; minScore == scores[i])
@ && (\forall int i; 0<=i && i<10; minScore <= scores[i])
@ \then
@ newScore <= minScore ==> (\result == 0)
@ \else
@ \result != 0
@ );
@*/
\end{minted}
Note however that I noticed the \texttt{\tbs{}else} branch is not really doing what it should be.
The else part doesn't handle the case of the \texttt{newScore} being higher than the minScore!
Instead it is handling the case when \emph{no} \texttt{minScore}, with the property of being an element in the \texttt{scores} array, as well as being the smallest element in this array, exists!
So in this case this would mean that our high score table is empty.
So this branch should either throw some kind of error, or rather make sure the ensures doesn't evaluate to true in that case, if this behaviour is not allowed, or if this is allowed, handle this case differently.
In case it isn't allowed to have an empty high score table, the example should be like follows
\begin{minted}{java}
/*@ ensures
@ (\ifEx int minScore;
@ -368,10 +398,10 @@ For the time being, one could inline this whole concept and possibly have a work
@ (\forall int i; 0<=i && i<10; minScore <= scores[i])
@ \then
@ newScore <= minScore ==> (\result == 0)
@ \else
@ \result != 0
@ \else
@ false
@ );
*/
@*/
\end{minted}
The main difficulty of this approach is the handling of the bound variable, the way of returning the notion of the fulfilling value to the caller, as in the notion of a value matching the property description, as well as handling the case of no value fulfilling the formula.