while loop termination in Dafny - while-loop

I am trying to verify an algorithm using Dafny. I am struggling to fix the error message "decreases expression might not decrease (timed out)". The basic structure of my algorithm is as follows:
while (U != {})
decreases |S| - |B - U|; // S is a constant and |B| <= |S|
invariant U < B; // U is a subset of B
{
var u :| u in U; // pick an element of u
U := U - {u}; // remove the element
while (...)
invariant U < B; // U is a subset of B
{
// modifies B and U but does not modify |B - U|
}
}
S, B and U are all sets. S is not modified at all in the algorithm. I have proved that the cardinality of B is less than or equal to the cardinality of S, so the decreases clause is bound by zero.
After each assignment to either B or U (in the inner while loop), I can prove that |B - U| remains the same. However, this is not enough, I need a loop invariant in the inner while loop that states this, but I do not know how to express this in Dafny. I have tried the following but it did not solve the problem:
invariant |old(B) - old(U)| == |B - U|;
(Note: This is the first time I am using Dafny and I have been stuck on this problem for around a week, any suggestions will be helpful).

To express that the inner loop has no effect on the value of |B - U|, you can save the value of |B - U| in a ghost variable just before the inner loop. Then, mention that ghost variable in the inner loop invariant. Like this:
ghost var previousCardinalityOfBminusU := |B - U|;
while (...)
invariant |B - U| == previousCardinalityOfBminusU
{
// ...
}
Here are some other comments:
If the inner loop does not add any elements to U, then a simpler termination metric for the outer loop is just |U|. You'll then want to add a loop invariant like |U| <= prev to the inner loop, where prev is a ghost variable that you set to |U| just before the inner loop.
Do you also have a plan for proving the termination of inner loop?
The expression U < B says that U is a proper subset of B, but maybe that is already what you meant by the comment "U is a subset of B"?
You error message also says "timed out". Sometimes, there may be more than one cause of the time out, and it could be that fixing one also takes care of the other. To make sure that everything else is fine, I suggest you temporarily let the verifier assume termination works out.
One way to do that is to (temporarily) mark each loop with decreases *, which tells the verifier that you're okay with the loop not terminating. (This will also require you to mark any enclosing loop and the enclosing method with decreases *.)
Another way to temporarily let the verifier assume termination works out is to use an assumestatement. For example, for the outer loop, you can do:
while U != {}
// as before
{
ghost var prev := |S| - |B - U|;
// as before
// inner loop as before
assume |S| - |B - U| < prev; // give verifier the (possibly incorrect) assumption that the termination metric has gone down
}
This may discover if there are other problems as well (that were previously masked by the time out), and those could be another cause of the time out. If, however, your program verifies correctly with these assumptions, then it is indeed termination proof that's causing the time out. You'll then need to try to provide more of the correctness argument to the verifier (my hunch is that some additional invariant on the inner loop will do the trick).

Related

How can I store a code block in a variable and call it and get its return value whenever needed?

I'm making a little text adventure in Smalltalk. It's made up of "screens" that have their texts and choices for other screens included. Since I want the game to be dynamic, I also want to include branching. For instance, if the player is at a blacksmith and wants to buy an axe, the screen the player goes to immediately checks if the player has enough money and jumps to one of two other screens based on that.
I already have this working: The screens (classes named Place) have a list where the first item is the function and the following items are the arguments. However, I have it done in a very ugly way: the first item is a string that is then compared against in a big "action" method, so it looks something like this:
game data method:
blacksmith := Place new.
blacksmith choiceText: 'I would like an axe.';
blacksmith action add: 'money'; add: 20; add: blacksmith_good; add: blacksmith_bad.
action method: (currentScreen is also a Place; the class also contains a BranchMoney method that does the actual decision making)
(currentScreen action at: 1) = 'money'
ifTrue: [
currentScreen := (currentScreen BranchMoney)
]
That's obviously not ideal, and I would like to compact it by doing something like this:
game data method:
blacksmith action add: [blacksmith BranchMoney]; add: 20; add: blacksmith_good; add: blacksmith_bad.
action method:
currentScreen := (currentScreen action at: 1)
So that instead of string checking the game would just directly proceed with the method I want it to do.
However, it doesn't seem to work - I've tried different changes to the code, and the problem seems to be that the currentScreen := (currentScreen action at: 1) line just replaces the contents of currentScreen with the code block contents – it doesn't calculate the block's contents and use its resulting value that is of type Place.
I've tried using round brackets in the game data method – that throws a list out of bounds exception, because it tries to calculate the expression immediately, before other arguments have even been added. Changing the first item name in game data method to currentScreen BranchMoney doesn't seem to make a difference.
I've also tried adding a return in the game data method, like this: blacksmith action add: [^blacksmith BranchMoney], so that it would have a value to return, no luck. Doing something like currentScreen := [^currentScreen action at: 1] in the action method doesn't work either.
For some shots in the dark, I tried the ExternalProcedure call and call: methods, but that failed too.
In Smalltalk every block is a regular object that you can store and retrieve the same you would do with any other object:
b := [self doSomething]
stores in b the block (much as b := 'Hello' stores a string in b). What I think you are missing is the #value message. To execute the block do the following
b value "execute self doSomething and answer with the result"
In case your block has one argument use #value: instead
b := [:arg | self doSomethingWith: arg]
later on
b value: 17 "execute the block passing 17 as the argument"
(for two arguments use #value:value:, for three #value:value:value: and for many #valueWithArguments:.)
Note however that this approach of using blocks and Arrays of arguments doesn't look very elegant (or even convenient). However, to help you with some better alternative we would need to learn more about your game. So, go check whether #value (and friends) let you progress a little bit and feel free to come back here with your next question. After some few iterations we could guide you towards a clearer route.
Example
b := [:m | m < 20 ifTrue: ['bad'] ifFalse: ['good']].
will produce
b value: 15 "==> 'bad'"
b value: 25 "==> 'good'"

Exponential method in dafny: invariant might not be maintained

I started learning Dafny and I just learned invariants. I've got this code:
function pot(m:int, n:nat): int
{
if n==0 then 1
else if n==1 then m
else if m==0 then 0
else pot(m,n-1) * m
}
method Pot(m:int, n:nat) returns (x:int)
ensures x == pot(m,n)
{
x:=1;
var i:=0;
if n==0 {x:=1;}
while i<=n
invariant i<=n;
{
x:=m*x;
i:=i+1;
}
}
And the given error is the following: "This loop invariant might not be maintained by the loop." I think I might need another invariant, but I think my code is correct other than that (I guess). Any help is appreciated. Thanks in advance.
A loop invariant must hold whenever the loop branch condition is evaluated. But on the last iteration of your loop, i will actually be n+1, so the loop invariant is not true then.
Changing the loop invariant to i <= n + 1 or changing the loop branch condition to i < n will fix this particular problem.
After that, you will still have some work to do to finish proving the method correct. Feel free to ask further questions if you get stuck.

Live variable analysis , is my explanation correct?

As stackexchange have not more tags about compiler tags , so I'm posting here , this question .
A variable x is said to be live at a statement Si in a program if the following three conditions hold simultaneously :
1. There exists a statement Sj that uses x
2. There is a path from Si to Sj in the flow
graph corresponding to the program
3. The path has no intervening assignment to x
including at Si and Sj
The variables which are live both at the statement in basic block 2 and at the statement in basic block 3 of the above control flow graph are
p, s, u
r, s, u
r, u
q, v
I try to explain :
As the wikipedia says "Stated simply: a variable is live if it holds a value that may be needed in the future."
As per the definition given in question, a variable is live if it is used in future before any new assignment.
Block 2 has ‘r’ and ‘v’ both as live variables. as they are used in block 4 before any new value assinged to them. Note that variable ‘u’ is not live in block 2 as ‘u’ is assigned a new value in block 1 before it is used in block 3. Variables ‘p’, ‘s’ and ‘q’ are also not live in block 2 due to same reason.
Block 3 has only ‘r’ as live variable as every other variable is assigned a new value before use.
Another explanation given as :
Only r.
p, s and u are assigned to in 1 and there is no intermediate use of them before that. Hence p, s and u are not live in both 2 and 3.
q is assigned to in 4 and hence is not live in both 2 and 3.
v is live at 3 but not at 2.
Only r is live at both 2 and 3.
But official GATE key said both r and u.
I see two things that are probably at least part of your confusion.
First, in the list of conditions for live variables, there is no restriction stating that Si != Sj, so this makes the definitions a little imprecise in my mind.
The second is your assertion "Note that variable ‘u’ is not live in block 2 as ‘u’ is assigned a new value in block 1 before it is used in block 3."
The way I would look at this would be this:
Upon entry into block 2, before the statement v = r + u is
executed (imagine a no-op empty statement inserted as the entry to
each block, and another as the exit from the block), then both r
and u must be live, because there exists an upcoming statement
that uses both, and there is a path in the code from the entry to
that statement that contains no intermediate assignments to either.
Rather than imagining these extra empty statements, using the
original semantics of the definitions, then we're just talking about
the case where Si == Sj, because both refer to the v = r + u
statement - there is trivially a path from a statement to itself
containing no additional assignments in that sense. I find it easier
to think about it with the extra empty entry and exit statements,
though.
After the execution of v = r + u, however, at the imaginary
block exit empty statement, it is now safe to consider u as not
live (alternatively, dead), because nothing in block 4 uses it, and
it's reassigned in block 1 before it's ever used again in either
block 2 or 3.
So, part of the confusion seems to be thinking of whether a variable is live in a particular block, which doesn't really fit with the definitions - you need to think about whether a variable is live at the point of a particular statement. You could make the case that the variable u is both alive and dead in block 2, depending on whether you look at it before execution of the lone statement, or after...

Is this considered memoisation?

In optimising some code recently, we ended up performing what I think is a "type" of memoisation but I'm not sure we should be calling it that. The pseudo-code below is not the actual algorithm (since we have little need for factorials in our application, and posting said code is a firing offence) but it should be adequate for explaining my question. This was the original:
def factorial (n):
if n == 1 return 1
return n * factorial (n-1)
Simple enough, but we added fixed points so that large numbers of calculations could be avoided for larger numbers, something like:
def factorial (n):
if n == 1 return 1
if n == 10 return 3628800
if n == 20 return 2432902008176640000
if n == 30 return 265252859812191058636308480000000
if n == 40 return 815915283247897734345611269596115894272000000000
# And so on.
return n * factorial (n-1)
This, of course, meant that 12! was calculated as 12 * 11 * 3628800 rather than the less efficient 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1.
But I'm wondering whether we should be calling this memoisation since that seems to be defined as remembering past results of calculations and using them. This is more about hard-coding calculations (not remembering) and using that information.
Is there a proper name for this process or can we claim that memoisation extends back not just to calculations done at run-time but also those done at compile-time and even back to those done in my head before I even start writing the code?
I'd call it pre-calculation rather than memoization. You're not really remembering any of the calculations you've done in the process of calculating a final answer for a given input, rather you're pre-calculating some fixed number of answers for specific inputs. Memoization as I understand it is really more akin to "caching" a set of results as you calculate them for later reuse. If you were to store each value calculated so that you didn't need to recalculate it again later, that would be memoization. Your solution differs in that you never store any "calculated" results from your program, only the fixed points that have been pre-calculated. With memoization if you reran the function with an input different than one of the pre-calculated ones it would not have to recalculate the result, it would simply reuse it.
Whether or not you are hard coding the results in, this is still memoization because you have already calculated results that you are expecting to calculate again. Now this may come in the form of run-time, or compile time.. but either way, it's memoization.
Memoization is done at run-time. You are optimizing at compile time. So, it is not.
See for example ... Wikipedia
Or ...
Memoization
The term memoization was coined by Donald Michie (1968) to refer to the process by which a function is made to automatically remember the results of previous computations. The idea has become more popular in recent years with the rise of functional languages; Field and Harrison (1988) devote a whole chapter to it. The basic idea is just to keep a table of previously computed input/result pairs.
Peter Norvig
University of California
(the bold is mine)
Link
def memoisation(f):
dct = {}
def myfunction(x):
if x not in dct:
dct[x] = f(x)
return dct[x]
return myfunction
#memoisation
def fibonacci(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fibonacci(n-1) + fibonacci(n-2)
def nb_appels(n):
if n==0 or n==1:
return 0
else:
return 1 + nb_appels(n-1) + 1 + nb_appels(n-2)
print(fibonacci(13))
print ('nbappel',nb_appels(13))

First and follow of the non-terminals in two grammars

Given the following grammar:
S -> L=L
s -> L
L -> *L
L -> id
What are the first and follow for the non-terminals?
If the grammar is changed into:
S -> L=R
S -> R
L -> *R
L -> id
R -> L
What will be the first and follow ?
When I took a compiler course in college I didn't understand FIRST and FOLLOWS at all. I implemented the algorithms described in the Dragon book, but I had no clue what was going on. I think I do now.
I assume you have some book that gives a formal definition of these two sets, and the book is completely incomprehensible. I'll try to give an informal description of them, and hopefully that will help you make sense of what's in your book.
The FIRST set is the set of terminals you could possibly see as the first part of the expansion of a non-terminal. The FOLLOWS set is the set of terminals you could possibly see following the expansion of a non-terminal.
In your first grammar, there are only three kinds of terminals: =, *, and id. (You might also consider $, the end-of-input symbol, to be a terminal.) The only non-terminals are S (a statement) and L (an Lvalue -- a "thing" you can assign to).
Think of FIRST(S) as the set of non-terminals that could possibly start a statement. Intuitively, you know you do not start a statement with =. So you wouldn't expect that to show up in FIRST(S).
So how does a statement start? There are two production rules that define what an S looks like, and they both start with L. So to figure out what's in FIRST(S), you really have to look at what's in FIRST(L). There are two production rules that define what an Lvalue looks like: it either starts with a * or with an id. So FIRST(S) = FIRST(L) = { *, id }.
FOLLOWS(S) is easy. Nothing follows S because it is the start symbol. So the only thing in FOLLOWS(S) is $, the end-of-input symbol.
FOLLOWS(L) is a little trickier. You have to look at every production rule where L appears, and see what comes after it. In the first rule, you see that = may follow L. So = is in FOLLOWS(L). But you also notice in that rule that there is another L at the end of the production rule. So another thing that could follow L is anything that could follow that production. We already figured out that the only thing that can follow the S production is the end-of-input. So FOLLOWS(L) = { =, $ }. (If you look at the other production rules, L always appears at the end of them, so you just get $ from those.)
Take a look at this Easy Explanation, and for now ignore all the stuff about ϵ, because you don't have any productions which contain the empty-string. Under "Rules for First Sets", rules #1, #3, and #4.1 should make sense. Under "Rules for Follows Sets", rules #1, #2, and #3 should make sense.
Things get more complicated when you have ϵ in your production rules. Suppose you have something like this:
D -> S C T id = V // Declaration is [Static] [Const] Type id = Value
S -> static | ϵ // The 'static' keyword is optional
C -> const | ϵ // The 'const' keyword is optional
T -> int | float // The Type is mandatory and is either 'int' or 'float'
V -> ... // The Value gets complicated, not important here.
Now if you want to compute FIRST(D) you can't just look at FIRST(S), because S may be "empty". You know intuitively that FIRST(D) is { static, const, int, float }. That intuition is codified in rule #4.2. Think of SCT in this example as Y1Y2Y3 in the "Easy Explanation" rules.
If you want to compute FOLLOWS(S), you can't just look at FIRST(C), because that may be empty, so you also have to look at FIRST(T). So FOLLOWS(S) = { const, int, float }. You get that by applying "Rules for follow sets" #2 and #4 (more or less).
I hope that helps and that you can figure out FIRST and FOLLOWS for the second grammar on your own.
If it helps, R represents an Rvalue -- a "thing" you can't assign to, such as a constant or a literal. An Lvalue can also act as an Rvalue (but not the other way around).
a = 2; // a is an lvalue, 2 is an rvalue
a = b; // a is an lvalue, b is an lvalue, but in this context it's an rvalue
2 = a; // invalid because 2 cannot be an lvalue
2 = 3; // invalid, same reason.
*4 = b; // Valid! You would almost never write code like this, but it is
// grammatically correct: dereferencing an Rvalue gives you an Lvalue.