Promela - non-determinism not non-deterministic? - verification

Consider this snippet:
chan sel = [0] of {int};
active proctype Selector(){
int not_me;
endselector:
do
:: sel ? not_me;
if
:: 0 != not_me -> sel ! 0;
:: 1 != not_me -> sel ! 1;
:: 2 != not_me -> sel ! 2;
:: 3 != not_me -> sel ! 3;
:: else -> -1;
fi
od
}
proctype H(){
int i = -1;
int count = 1000;
do
:: sel ! i; sel ? i; printf("currently selected: %d\n",i); count = count -1;
:: count < 0 -> break;
od
assert(false);
}
init{
atomic{
run H();
}
}
You'd expect this to print pretty the values 0..3 pretty arbitrarily until the counter falls below 0, at which point it can either print another number or it will terminate.
However, that doesn't seem to be the case.
The only values returned are 0, then 1, then 0, then 1, then 0, then 1, ...
Did I somehow misunderstand the "non-determinism" of the if/fi statements?
(using ispin on ubuntu, if that matters).

Relevant part of language spec. Seems non-determinstic to me.
If you're looking at (a few) traces of the system only, then you're at the mercy of the (pseudo) random generator.
I thought the main purpose of SPIN is to prove properties. So, you could write a formula F that describes the trace(s) that you want, and then have SPIN check that "system and F" has a model.

If you are running Spin in 'simulation' mode, then the else options are visited deterministically, I believe. So in the Selector proctype, the simulation proceeds in the if by checking the options as: 0 ~= not_me and then the 1, 2, 3 options. For your execution, you thus ping pong between 0 and 1.
You can confirm this, by replacing your if statement with:
if
:: 0 != not_me -> sel ! 0;
:: 1 != not_me -> sel ! 1;
:: else -> assert(false)
fi
and your simulation will never reach the assert.
Spin can also be run in 'verification' mode - generate a pan executable and execute that. Then, all cases will be visited (modulo limits in memory and time). However, in 'verification' mode nothing is printed out - so you might be hard pressed to see the other cases!

Related

dafny non aliased memory weird behavior

I have a dafny defined graph ADT (from this SO question) brought here again for completeness:
class Graph
{
var adjList : seq<seq<int>>;
constructor (adjListInput : seq<seq<int>>)
ensures adjList == adjListInput
{
adjList := adjListInput;
}
}
function ValidGraph(G : Graph) : bool
reads G
{
(forall u :: 0 <= u < |G.adjList| ==> forall v :: 0 <= v < |G.adjList[u]| ==> 0 <= G.adjList[u][v] < |G.adjList|) &&
(forall u :: 0 <= u < |G.adjList| ==> forall v,w :: 0 <= v < w < |G.adjList[u]| ==> G.adjList[u][v] != G.adjList[u][w])
}
method main()
{
var G : Graph := new Graph([[1,2],[0,2],[0,1]]);
var nonRelatedArray := new int[8];
var i := 0; while (i < 14)
{
// nonRelatedArray[3] := 55;
i := i + 1;
}
assert (ValidGraph(G));
}
If I remove the write comment to nonRelatedArray at index 3, I get an assertion violation, which is a bit weird because it seems reasonable that the memory model would be able to determine that nonRelatedArray is (well) non related to G.
You can fix this by adding modifies nonRelatedArray to the loop. The key to this modifies clause is that it does not mention G. So then Dafny knows that G will not be modified by the loop, so it will still be a valid graph.
It is a little confusing what happens if you leave off a modifies clause from a loop. If you don't do any writes to the heap (like when you comment out the write above), then Dafny (actually, Boogie) is able to automatically see that nothing is changed at all. But if you do any writes into the heap, Dafny's default modifies clause all of a sudden becomes "anything the surrounding scope is allowed to modify". If you want something other than these two defaults, you need to ask for it explicitly by giving a modifies clause.

Lock between N Processes in Promela

I am trying to model one of my project in promela for model checking. In that, i have N no of nodes in network. So, for each node I am making a process. Something like this:
init {
byte proc;
atomic {
proc = 0;
do
:: proc < N ->
run node (q[proc],proc);
proc++
:: proc >= N ->
break
od
}
}
So, basically, here each 'node' is process that will simulate each node in my network. Now, Node Process has 3 threads which run parallelly in my original implementation and within these three threads i have lock at some part so that three threads don't access Critical Section at the same time. So, for this in promela, i have done something like this:
proctype node (chan inp;byte ppid)
{
run recv_A()
run send_B()
run do_C()
}
So here recv_A, send_B and do_C are the three threads running parallelly at each node in the network. Now, the problem is, if i put lock in recv_A, send_B, do_C using atomic then it will put lock lock over all 3*N processes whereas i want a lock such that the lock is applied over groups of three. That is, if process1's(main node process from which recv_A is made to run) recv_A is in its CS then only process1's send_B and do_C should be prohibited to enter into CS and not process2's recv_A, send_B, do_C. Is there a way to do this?
Your have several options, and all revolve around implementing some kind of mutual exclusion algorithm among N processes:
Peterson Algorithm
Eisenberg & McGuire Algorithm
Lamport's bakery Algorithm
SzymaƄski's Algorithm
...
An implementation of the Black & White Bakery Algorithm is available here. Note, however, that these algorithms -maybe with the exception of Peterson's one- tend to be complicated and might make the verification of your system impractical.
A somewhat simple approach is to resort on the Test & Set Algorithm which, however, still uses atomic in the trying section. Here is an example implementation taken from here.
bool lock = false;
int counter = 0;
active [3] proctype mutex()
{
bool tmp = false;
trying:
do
:: atomic {
tmp = lock;
lock = true;
} ->
if
:: tmp;
:: else -> break;
fi;
od;
critical:
printf("Process %d entered critical section.\n", _pid);
counter++;
assert(counter == 1);
counter--;
exit:
lock = false;
printf("Process %d exited critical section.\n", _pid);
goto trying;
}
#define c0 (mutex[0]#critical)
#define c1 (mutex[1]#critical)
#define c2 (mutex[2]#critical)
#define t0 (mutex[0]#trying)
#define t1 (mutex[1]#trying)
#define t2 (mutex[2]#trying)
#define l0 (_last == 0)
#define l1 (_last == 1)
#define l2 (_last == 2)
#define f0 ([] <> l0)
#define f1 ([] <> l1)
#define f2 ([] <> l2)
ltl p1 { [] !(c0 && c1) && !(c0 && c2) && !(c1 && c2)}
ltl p2 { []((t0 || t1 || t2) -> <> (c0 || c1 || c2)) }
ltl p3 {
(f0 -> [](t0 -> <> c0))
&&
(f1 -> [](t1 -> <> c1))
&&
(f2 -> [](t2 -> <> c2))
};
In your code, you should use a different lock variable for every group of 3 related threads. The lock contention would still happen at a global level, but some process working inside the critical section would not cause other processes to wait other than those who belong to the same thread group.
Another idea is that to exploit channels to achieve mutual exclusion: have each group of threads share a common asynchronous channel which initially contains one token message. Whenever one of these threads wants to access the critical section, it reads from the channel. If the token is not inside the channel, it waits until it becomes available. Otherwise, it can go forward in the critical section and when it finishes it puts the token back inside the shared channel.
proctype node (chan inp; byte ppid)
{
chan lock = [1] of { bool };
lock!true;
run recv_A(lock);
run send_B(lock);
run do_C(lock);
};
proctype recv_A(chan lock)
{
bool token;
do
:: true ->
// non-critical section code
// ...
// acquire lock
lock?token ->
// critical section
// ...
// release lock
lock!token
// non-critical section code
// ...
od;
};
...
This approach might be the simplest to start with, so I would pick this one first. Note however that I have no idea on how that affects performance during verification time, and this might very well depend on how channels are internally handled by Spin. A complete code example of this solution can be found here in the file channel_mutex.pml.
To conclude, note that you might want to add mutual exclusion, progress and lockout-freedom LTL properties to your model to ensure that it behaves correctly. An example of the definition of these properties is available here and a code example is available here.

How to get a grandparents/ancestors process ID?

I would like to know - if possible - how to get the pid of a process' grandparent (or further).
To be more specific, I want for a process to print its depth in a process tree.
For example, when starting with the following:
int main() {
int creator_id = (int) getpid();
pid_t pid1 = fork();
pid_t pid2 = fork();
pid_t pid3 = fork();
//print depth in process tree of each process
return 0;
}
According to my theory, the tree will look like this:
0
/|\
/ | \
/ | \
0 0 0
/ \ |
0 0 0
/
0
So my first idea was to somehow see how often I have to go up until I find the creator's pid.
As a little sidenote:
I also wondered if it was possible to make the printing from bottom up, meaning that all processes in the deepest level would print first.
how to get the pid of a process' grandparent (or further).
This depends on which operating system you are using, since you use fork() to create new process in your example, I suppose you are using some Unix-like system.
If you are using Linux and know the pid of a process, you could get its parent process' pid from /proc/[pid]/stat, the fourth field in that file. Through this parent-child chain, you could find a process' all ancestors.
Following #Lee Duhem's hint, I made the following function that returns the nth ancestor of the current process (the 2nd ancestor is the grandparent).
/* Get the process ID of the calling process's nth ancestor. */
pid_t getapid(int n) {
pid_t pid = getpid();
while(n>0 && pid){ // process with pid 0 has no parent
// strlen("/proc/") == 6
// max [pid] for 64 bits is 4194304 then strlen("[pid]") < 7
// strlen("/stat") == 5
// then strlen("/proc/[pid]/stat") < 6 + 7 + 5
char proc_stat_path[6+7+5+1];
sprintf(proc_stat_path, "/proc/%d/stat", pid);
// open "/proc/<pid>/stat"
FILE *fh = fopen(proc_stat_path, "r");
if (fh == NULL) {
fprintf(stderr, "Failed opening %s: ", proc_stat_path);
perror("");
exit(1);
}
// seek to the last ')'
int c;
long pos = 0;
while ((c = fgetc(fh)) != EOF) {
if (c == ')')
pos = ftell(fh);
}
fseek(fh, pos, SEEK_SET);
// get parent
fscanf(fh, " %*c %d", &pid);
// close "/proc/<pid>/stat"
fclose(fh);
// decrement n
n--;
}
if(n>0)
return -1;
else
return pid;
}

How to receive message from 'any' channel in PROMELA/SPIN

I'm modeling an algorithm in Spin.
I have a process that has several channels and at some point, I know a message is going to come but don't know from which channel. So want to wait (block) the process until it a message comes from any of the channels. how can I do that?
I think you need Promela's if construct (see http://spinroot.com/spin/Man/if.html).
In the process you're referring to, you probably need the following:
byte var;
if
:: ch1?var -> skip
:: ch2?var -> skip
:: ch3?var -> skip
fi
If none of the channels have anything on them, then "the selection construct as a whole blocks" (quoting the manual), which is exactly the behaviour you want.
To quote the relevant part of the manual more fully:
"An option [each of the :: lines] can be selected for execution only when its guard statement is executable [the guard statement is the part before the ->]. If more than one guard statement is executable, one of them will be selected non-deterministically. If none of the guards are executable, the selection construct as a whole blocks."
By the way, I haven't syntax checked or simulated the above in Spin. Hopefully it's right. I'm quite new to Promela and Spin myself.
If you want to have your number of channels variable without having to change the implementation of the send and receive parts, you might use the approach of the following producer-consumer example:
#define NUMCHAN 4
chan channels[NUMCHAN];
init {
chan ch1 = [1] of { byte };
chan ch2 = [1] of { byte };
chan ch3 = [1] of { byte };
chan ch4 = [1] of { byte };
channels[0] = ch1;
channels[1] = ch2;
channels[2] = ch3;
channels[3] = ch4;
// Add further channels above, in
// accordance with NUMCHAN
// First let the producer write
// something, then start the consumer
run producer();
atomic { _nr_pr == 1 ->
run consumer();
}
}
proctype consumer() {
byte var, i;
chan theChan;
i = 0;
do
:: i == NUMCHAN -> break
:: else ->
theChan = channels[i];
if
:: skip // non-deterministic skip
:: nempty(theChan) ->
theChan ? var;
printf("Read value %d from channel %d\n", var, i+1)
fi;
i++
od
}
proctype producer() {
byte var, i;
chan theChan;
i = 0;
do
:: i == NUMCHAN -> break
:: else ->
theChan = channels[i];
if
:: skip;
:: theChan ! 1;
printf("Write value 1 to channel %d\n", i+1)
fi;
i++
od
}
The do loop in the consumer process non-deterministically chooses an index between 0 and NUMCHAN-1 and reads from the respective channel, if there is something to read, else this channel is always skipped. Naturally, during a simulation with Spin the probability to read from channel NUMCHAN is much smaller than that of channel 0, but this does not make any difference in model checking, where any possible path is explored.

Objective C debugging not taking the proper step over route

I am new to Objective C.In detail I am reading about objective c from past three days. The below mentioned method is to generate prime numbers till a particular mentioned number as per the Seive of Erastosthenes algorithm.I am trying to debug the program but when ever the code comes to the line
"if(product > size )"
the next step will immediately take it to the
"for(j=2 ; j<= size ; j++ )"
I dont know what is going wrong with the debug.It goes into the break when the product is greater than the size.But when the condition is false (product > size) why doesn't it go to the next if condition that is
if(array[product-1] != 1)
Do I need to recompile the code.I am using xcode to debug the code on mac os X 10.x
#interface SeiveofErastosthenes : NSObject
{
int* array;
int size;
}
-(SeiveofErastosthenes*) initMe: (int) ssize;
-(void) calculatePrimeNumbers;
-(void) print;
#end
-(void) calculatePrimeNumbers
{
int product=0;
int i=0;
int j;
memset(array,0,size);
array[0]=0;
array[1]=2;
for(i = 1 ; i < size ; i++)
{
if(array[i] == 1)
continue;
array[i] = i+1;
for(j = 2; j <= size ; j++ )
{
product = (i+1) * j;
if(product > size)
{
break;
}
if(array[product-1] != 1)
{
array[product] == 1;
}
}
}
}
Make sure 'Load symbols lazily' is unchecked in Xcode preferences -> debugging. It can sometimes wreak havoc.
Xcode projects are set up with -Os optimization (optimize for speed and space) by default, for both Debug and Release builds, bizarrely. This kind of optimization will make debugging difficult, as code may be reordered for performance. Check your project and target settings for the "Debug" configuration, and make sure Optimization Level is set to "None."
Ok guys I figured out the problem
Objective C debugger sucks
In my program
if(array[product-1] != 1)
{
array[product] == 1;
}
It doesn't execute a statement if it is not necessary according to it
"array[product] == 1;" this is wrong according to the algorithm but it is still a valid code
This is a valid statement according to c and it should execute it and the value returned is a boolean true or false.Objective C just ignores it and goes to the next loop.It is so intelligent that it even doesn't check the condition if( array[product] !=1 )