NuSMV returns undefined operation - model-checking

I have written the following code:
MODULE main
VAR
status:{empty, no_empty};
x : 0..3;
ASSIGN
init(status):= empty;
init(x):=0;
next(status):= case
(status = empty): no_empty;
(status = no_empty) & (x=0): empty;
TRUE: status;
esac;
next(x):= case
(status = empty): x+3;
(status = no_empty) & (x>0): x-1;
TRUE: x;
esac;
However, when I execute the command "flatten_hierarchy" I get the following error: "x-1" undefined
I don't know why x-1 is undefined.

This is a known issue.
The parser is confusing x-1 for an identifier, when it is supposed to be an expression.
Replace
x-1
with
x - 1

Related

how to model a queue in promela?

Ok, so I'm trying to model a CLH-RW lock in Promela.
The way the lock works is simple, really:
The queue consists of a tail, to which both readers and writers enqueue a node containing a single bool succ_must_wait they do so by creating a new node and CAS-ing it with the tail.
The tail thereby becomes the node's predecessor, pred.
Then they spin-wait on pred.succ_must_wait until it is false.
Readers first increment a reader counter ncritR and then set their own flag to false, allowing multiple readers at in the critical section at the same time. Releasing a readlock simply means decrementing ncritR again.
Writers wait until ncritR reaches zero, then enter the critical section. They do not set their flag to false until the lock is released.
I'm kind of struggling to model this in promela, though.
My current attempt (see below) tries to make use of arrays, where each node basically consists of a number of array entries.
This fails because let's say A enqueues itself, then B enqueues itself. Then the queue will look like this:
S <- A <- B
Where S is a sentinel node.
The problem now is, that when A runs to completeness and re-enqueues, the queue will look like
S <- A <- B <- A'
In actual execution, this is absolutely fine because A and A' are distinct node objects. And since A.succ_must_wait will have been set to false when A first released the lock, B will eventually make progress, and therefore A' will eventually make progress.
What happens in the array-based promela model below, though, is that A and A' occupy the same array positions, causing B to miss the fact that A has released the lock, thereby creating a deadlock where B is (wrongly) waiting for A' instead of A and A' is waiting (correctly) for B.
A possible "solution" to this could be to have A wait until B acknowledges the release. But that would not be true to how the lock works.
Another "solution" would be to wait for a CHANGE in pred.succ_must_wait, where a release would increment succ_must_wait, rather than reset it to 0.
But I'm intending to model a version of the lock, where pred may change (i.e. where a node may be allowed to disregard some of its predecessors), and I'm not entirely convinced something like the increasing version wouldn't cause an issue with this change.
So what's the "smartest" way to model an implicit queue like this in promela?
/* CLH-RW Lock */
/*pid: 0 = init, 1-2 = reader, 3-4 = writer*/
ltl liveness{
([]<> reader[1]#progress_reader)
&& ([]<> reader[2]#progress_reader)
&& ([]<> writer[3]#progress_writer)
&& ([]<> writer[4]#progress_writer)
}
bool initialised = 0;
byte ncritR;
byte ncritW;
byte tail;
bool succ_must_wait[5]
byte pred[5]
init{
assert(_pid == 0);
ncritR = 0;
ncritW = 0;
/*sentinel node*/
tail =0;
pred[0] = 0;
succ_must_wait[0] = 0;
initialised = 1;
}
active [2] proctype reader()
{
assert(_pid >= 1);
(initialised == 1)
do
:: else ->
succ_must_wait[_pid] = 1;
atomic {
pred[_pid] = tail;
tail = _pid;
}
(succ_must_wait[pred[_pid]] == 0)
ncritR++;
succ_must_wait[_pid] = 0;
atomic {
/*freeing previous node for garbage collection*/
pred[_pid] = 0;
}
/*CRITICAL SECTION*/
progress_reader:
assert(ncritR >= 1);
assert(ncritW == 0);
ncritR--;
atomic {
/*necessary to model the fact that the next access creates a new queue node*/
if
:: tail == _pid -> tail = 0;
:: else ->
fi
}
od
}
active [2] proctype writer()
{
assert(_pid >= 1);
(initialised == 1)
do
:: else ->
succ_must_wait[_pid] = 1;
atomic {
pred[_pid] = tail;
tail = _pid;
}
(succ_must_wait[pred[_pid]] == 0)
(ncritR == 0)
atomic {
/*freeing previous node for garbage collection*/
pred[_pid] = 0;
}
ncritW++;
/* CRITICAL SECTION */
progress_writer:
assert(ncritR == 0);
assert(ncritW == 1);
ncritW--;
succ_must_wait[_pid] = 0;
atomic {
/*necessary to model the fact that the next access creates a new queue node*/
if
:: tail == _pid -> tail = 0;
:: else ->
fi
}
od
}
First of all, a few notes:
You don't need to initialize your variables to 0, since:
The default initial value of all variables is zero.
see the docs.
You don't need to enclose a single instruction inside an atomic {} statement, since any elementary statement is executed atomically. For better efficiency of the verification process, whenever possible, you should use d_step {} instead. Here you can find a related stackoverflow Q/A on the topic.
init {} is guaranteed to have _pid == 0 when one of the two following conditions holds:
no active proctype is declared
init {} is declared before any other active proctype appearing in the source code
Active Processes, includig init {}, are spawned in order of appearance inside the source code. All other processes are spawned in order of appearance of the corresponding run ... statement.
I identified the following issues on your model:
the instruction pred[_pid] = 0 is useless because that memory location is only read after the assignment pred[_pid] = tail
When you release the successor of a node, you set succ_must_wait[_pid] to 0 only and you don't invalidate the node instance onto which your successor is waiting for. This is the problem that you identified in your question, but was unable to solve. The solution I propose is to add the following code:
pid j;
for (j: 1..4) {
if
:: pred[j] == _pid -> pred[j] = 0;
:: else -> skip;
fi
}
This should be enclosed in an atomic {} block.
You correctly set tail back to 0 when you find that the node that has just left the critical section is also the last node in the queue. You also correctly enclose this operation in an atomic {} block. However, it may happen that --when you are about to enter this atomic {} block-- some other process --who was still waiting in some idle state-- decides to execute the initial atomic block and copies the current value of tail --which corresponds to the node that has just expired-- into his own pred[_pid] memory location. If now the node that has just exited the critical section attempts to join it once again, setting his own value of succ_must_wait[_pid] to 1, you will get another instance of circular wait among processes. The correct approach is to merge this part with the code releasing the successor.
The following inline function can be used to release the successor of a given node:
inline release_succ(i)
{
d_step {
pid j;
for (j: 1..4) {
if
:: pred[j] == i ->
pred[j] = 0;
:: else ->
skip;
fi
}
succ_must_wait[i] = 0;
if
:: tail == _pid -> tail = 0;
:: else -> skip;
fi
}
}
The complete model, follows:
byte ncritR;
byte ncritW;
byte tail;
bool succ_must_wait[5];
byte pred[5];
init
{
skip
}
inline release_succ(i)
{
d_step {
pid j;
for (j: 1..4) {
if
:: pred[j] == i ->
pred[j] = 0;
:: else ->
skip;
fi
}
succ_must_wait[i] = 0;
if
:: tail == _pid -> tail = 0;
:: else -> skip;
fi
}
}
active [2] proctype reader()
{
loop:
succ_must_wait[_pid] = 1;
d_step {
pred[_pid] = tail;
tail = _pid;
}
trying:
(succ_must_wait[pred[_pid]] == 0)
ncritR++;
release_succ(_pid);
// critical section
progress_reader:
assert(ncritR > 0);
assert(ncritW == 0);
ncritR--;
goto loop;
}
active [2] proctype writer()
{
loop:
succ_must_wait[_pid] = 1;
d_step {
pred[_pid] = tail;
tail = _pid;
}
trying:
(succ_must_wait[pred[_pid]] == 0) && (ncritR == 0)
ncritW++;
// critical section
progress_writer:
assert(ncritR == 0);
assert(ncritW == 1);
ncritW--;
release_succ(_pid);
goto loop;
}
I added the following properties to the model:
p0: the writer with _pid equal to 4 goes through its progress state infinitely often, provided that it is given the chance to execute some instruction infinitely often:
ltl p0 {
([]<> (_last == 4)) ->
([]<> writer[4]#progress_writer)
};
This property should be true.
p1: there is never more than one reader in the critical section:
ltl p1 {
([] (ncritR <= 1))
};
Obviously, we expect this property to be false in a model that matches your specification.
p2: there is never more than one writer in the critical section:
ltl p2 {
([] (ncritW <= 1))
};
This property should be true.
p3: there isn't any node that is the predecessor of two other nodes at the same time, unless such node is node 0:
ltl p3 {
[] (
(((pred[1] != 0) && (pred[2] != 0)) -> (pred[1] != pred[2])) &&
(((pred[1] != 0) && (pred[3] != 0)) -> (pred[1] != pred[3])) &&
(((pred[1] != 0) && (pred[4] != 0)) -> (pred[1] != pred[4])) &&
(((pred[2] != 0) && (pred[3] != 0)) -> (pred[2] != pred[3])) &&
(((pred[2] != 0) && (pred[4] != 0)) -> (pred[2] != pred[4])) &&
(((pred[3] != 0) && (pred[4] != 0)) -> (pred[3] != pred[4]))
)
};
This property should be true.
p4: it is always true that whenever writer with _pid equal to 4 tries to access the critical section then it will eventually get there:
ltl p4 {
[] (writer[4]#trying -> <> writer[4]#progress_writer)
};
This property should be true.
The outcome of the verification matches our expectations:
~$ spin -search -ltl p0 -a clhrw_lock.pml
...
Full statespace search for:
never claim + (p0)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 68 byte, depth reached 3305, errors: 0
...
~$ spin -search -ltl p1 -a clhrw_lock.pml
...
Full statespace search for:
never claim + (p1)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 68 byte, depth reached 1692, errors: 1
...
~$ spin -search -ltl p2 -a clhrw_lock.pml
...
Full statespace search for:
never claim + (p2)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 68 byte, depth reached 3115, errors: 0
...
~$ spin -search -ltl p3 -a clhrw_lock.pml
...
Full statespace search for:
never claim + (p3)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 68 byte, depth reached 3115, errors: 0
...
~$ spin -search -ltl p4 -a clhrw_lock.pml
...
Full statespace search for:
never claim + (p4)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 68 byte, depth reached 3115, errors: 0
...

How to check for unknown registers in verilog

When getting three inputs from the console, I am wondering how to check and 'warn' the user that a register may not have been initialized.
to do this I am trying:
flag = $value$plusargs("a=%b", a);
if (flag != 0 && flag != 1) begin
$display("a might not be initialized");
end
flag = $value$plusargs("b=%b", b);
flag = $value$plusargs("c=%b", c);
#1 $display("a=%b b=%b c=%b z=%b", a, b, c, z);
However with my limited knowledge I am having a difficult time figuring out what to do. When I run my compiled code with no paramaters I get:
a = x, b = x, c = x, z = x;
but no warning, even though the flag(a) is clearly not 1 and not 0
flag returns true(1) if $value$plusargs finds +a=value on the command line and sets the value of a. So you want
if (flag == 0) begin
$display("a might not be initialized");
You can do this in one step
if ( !$value$plusargs("a=%b", a) ) begin
$display("a might not be initialized");
And if you use SystemVerilog, you can use $warning() instead of $display().
To compare with unknown value, you should use !== or === instead of != and ==

Why am I not getting an expected output using logical operators and indexing?

I am having trouble achieving an expected output. I am trying to create a byte adder using logical operators such as AND, XOR and OR. I have taken the minimal code required to reproduce the problem out of code, so assume that finalfirstvalue = "1010" and finalsecondvalue = "0101".
secondvalueindex = (len(finalsecondvalue) - 1)
carry, finalans = False, []
for i in range(-1, -len(finalfirstvalue) - 1, -1):
andone = (bool(finalfirstvalue[i])) & (bool(finalsecondvalue[secondvalueindex]))
xorone = (bool(finalfirstvalue[i])) ^ (bool(finalsecondvalue[secondvalueindex]))
andtwo = (bool(carry)) & (bool(xorone))
xortwo = (bool(carry)) ^ (bool(xorone))
orone = (bool(andone)) | (bool(andtwo))
carry = (bool(orone))
finalans.append(xortwo)
secondvalueindex -= 1
answer = ''.join(str(e) for e in finalans)
print (answer)
Actual Output: FalseTrueTrueTrue
Expected Output: TrueTrueTrueTrue
The code then follows to change back into zeroes and ones.
Because its missing a single boolean I feel like the issue is with my indexing. Although I've played around with it a bit and not had any luck.
I need to carry out these operations on the two variables mentioned at the start, but for the right most elements, and then move to the left by one for the next loop and so on.
First mistake is You are representing your binary numbers as string values.
finalfirstvalue = "1010"
finalsecondvalue = "0101"
secondvalueindex = (len(finalsecondvalue) - 1) == 3
So in second for loop you will get the result as
(finalsecondvalue[secondvalueindex]) == '0'
If you check in your Idle
>>> bool('0')
True
>>>
Because '0' is not actual 0 it is an non-empty string so it return True.
You need to cast your result to int before checking them with bool
Like this
(bool(int(finalsecondvalue[secondvalueindex])))
EDIT 2 Adding with variable lenghts
Full adder with verification using bin() function
a="011101"
b="011110"
if a>b:
b=b.zfill(len(a))
if a<b:
a=a.zfill(len(b))
finalfirstvalue = a
finalsecondvalue = b
carry, finalans = 0, []
secondvalueindex = (len(finalsecondvalue))
for i in reversed(range(0, len(finalfirstvalue))):
xorone = (bool(int(finalfirstvalue[i]))) ^ (bool(int(finalsecondvalue[i])))
andone = (bool(int(finalfirstvalue[i]))) & (bool(int(finalsecondvalue[i])))
xortwo = (carry) ^ (xorone)
andtwo = (carry) & (xorone)
orone = (andone) | (andtwo)
carry = (orone)
finalans.append(xortwo)
finalans.reverse()
answer=(''.join(str(e) for e in finalans))
print(str(carry)+answer)
print(bin(int(a,2) + int(b,2))) #verification
So I found the issue was to do with carry. I changed my code to look like the following. Prior to this code below, is code to convert binary values to boolean. For instance, all ones will equal True and all zeroes will equal False.
carry, finalans = False, []
indexvalue = (len(finalfirstvalue)-1)
while indexvalue >= 0:
andone = (firstvaluelist[indexvalue]) & (secondvaluelist[indexvalue])
xorone = (firstvaluelist[indexvalue]) ^ (secondvaluelist[indexvalue])
andtwo = (carry) & (xorone)
xortwo = (carry) ^ (xorone)
orone = (andone) | (andtwo)
carry = (orone)
if (carry == True) & (indexvalue == 0):
finalans.append(xortwo)
finalans.append(True)
else:
finalans.append(xortwo)
indexvalue -= 1
for n, i in enumerate(finalans):
if i == False:
finalans[n] = "0"
if i == True:
finalans[n] = "1"
finalans.reverse()
answer = ''.join(str(e) for e in finalans)
print (answer)
So if there was a single value missing, it was still stored in carry from the final loop but did not get the opportunity to be appended to the final result. To fix this, I added in an if statement to check if carry is containing anything (True) and if the loop is on its final loop by checking if indexvalue is at 0. This way, if the inputs are 32 and 32, rather than getting [False, False, False, False, False, False] as the output, the newly entered if statement will add the missing value in.

DP states in SPOJ SERVICES

I am having a problem in the question SERVICES on SPOJ. I tried to solve it and came up with the following DP states [posofA][posofB][posofC][NextToMove]. But looking at the constraints, I think It will Give MLE. After trying for a day, I googled it and found blogs regarding a symmetry in the question. Despite my best efforts, I am unable to understand it. Can someone Please help and spare his time to help me. Thanks.
Observe that you can drop posOfC and always denote posOfC by the last requested position. When you are processing a request , you can easily get the previous position. Now you have all the positions of the 3 partners. Send one of them to the new requested position checking that all of them will be in different location.
int f(int pos,int a,int b)
{
if(pos == req.sz)
return 0;
// last position
int c = req[pos-1];
// current position we are sending one of them
int to = req[pos];
if( dp[pos][a][b] != -1)
return dp[pos][a][b];
int ans = inf;
// a goes to current request position
if(b != c && b != to && c != to)
ans = min(ans,f(pos+1,b,c) + cost[a][to]);
// b goes to current request position
if(a != c && a != to && c != to)
ans = min(ans,f(pos+1,a,c) + cost[b][to]);
// c goes to current request position
if(a != b && a != to && b != to)
ans = min(ans , f(pos+1,a,b) + cost[c][to]);
return dp[pos][a][b] = ans;
}
First 3 elements of req will be 1,2,3 . Get the answer by calling f(3,1,2).

Default return value of a function in BASIC

Following is an example program in BASIC. Can someone tell me what this function returns if the marked condition is not true? I have to port the program to C++ and need to understand it. I have no BASIC knowledge - please bear with simple question.
FUNCTION CheckPoss (u)
tot = tot + 1
f = 0
SELECT CASE u
CASE 2
f = f + CheckIntersection(1, 3, 2, 1) 'A
CASE 3
f = f + CheckIntersection(2, 3, 3, 1) 'B
END SELECT
IF f = 0 THEN <============== This condition if true,
CheckPoss = 1 <============== then return value is 1
IF u = 9 THEN
PrintSolution
END IF
END IF
END FUNCTION
This is a good example of bad programming. First some unknown global variable is changed in this function. "tot = tot + 1"! Second line "F" is another unknown global variable is assigned "0". Or is this the only place this variable is used? In that case it is a variant implicitly declared here. Use a dim to declare it. It is legal in basic to do this. Globals should be passed as arguments to the function like this:
function CheckPoss(u as integer, tot as integer) as integer
dim f as integer
f=0
It is all about good practice so the input is clear and output is clear and all variable assignments should be through arguments passed to the function.
The return type is not declared either. Is this visual basic? or is it some older basic? Anyway the return type is a variant in case of visual basic. Older basic would be an integer type.
The output from this function will mostly likely be a zero if the condition is not met! That should also be clear in the code and it is not clear as it is, and I understand why you ask. I am amazed this piece of code comes from a working program.
Good luck with your project!
I don't know exactly that this function do.
On VB.net, the function follow the structure:
Public function CheckPoss(Byval u as integer)
... ' Just commands
return u ' Or other variable
end function
If not exist the 'return' command, the return of function will be 'null' character.
On C, The function will be:
int CheckPoss(int u){
tot++; // Increment tot variable (need be declared)
int f = 0;
switch(u){
case 2:
f += CheckIntersection(1, 3, 2, 1); // A
break;
case 3:
f += CheckIntersection(2, 3, 3, 1); // B
break;
}
if (f == 0){
if (u == 9){
PrintSolution();
}
return 1;
}
}
The return command need be the last command of this function. At case f != 0, the function must return trash (some value or character).
My suggestion is:
int CheckPoss(int u){
tot++; // I think that this must count how times you call this function
int f;
if(u == 2){
f = CheckIntersection(1, 3, 2, 1); // A
}else if(u == 3){
f = CheckIntersection(2, 3, 3, 1); // B
}else{
f = 1; // Case else
}
if (f == 0){
if (u == 9)
PrintSolution();
return 1;
}
}

Resources