Spin random error, bakery lock - spin

I've created a bakery lock using Spin
1 int n=3;
2 int choosing[4] ; // initially 0
3 int number[4]; // initially 0
4
5 active [3] proctype p()
6 {
7
8 choosing[_pid] = 1;
9 int max = 0;
10 int i=0;
11
12 do
13 ::(number[i] > max) -> max=number[i];
14 ::i++;
15 :: (i == n) -> break;
16 od;
17
18 number[_pid] = max + 1;
19 choosing[_pid] = 0;
20
21 int j=0;
22
23 do
24 ::(j==n) -> break;
25 :: do
26 ::(choosing[j] == 0)-> break;
27 od;
28 :: if
29 ::(number[j] ==0) -> j++;
30 ::(number[j] > number[_pid]) -> j++;
31 ::((number[j] == number[_pid]) && ( j> _pid)) -> j++;
32 fi;
33 od;
34
35 number[_pid]=0
36
37 }
when I test it I get an error: pan:1: assertion violated - invalid array index (at depth 5)
when I run the trail I get this back
1: proc 2 (p) Bakery_lock.pml:8 (state 1) [choosing[_pid] = 1]
2: proc 2 (p) Bakery_lock.pml:10 (state 2) [max = 0]
2: proc 2 (p) Bakery_lock.pml:12 (state 3) [i = 0]
3: proc 2 (p) Bakery_lock.pml:14 (state 6) [i = (i+1)]
4: proc 2 (p) Bakery_lock.pml:14 (state 6) [i = (i+1)]
5: proc 2 (p) Bakery_lock.pml:14 (state 6) [i = (i+1)]
spin: indexing number[3] - size is 3
spin: Bakery_lock.pml:13, Error: indexing array 'number'
6: proc 2 (p) Bakery_lock.pml:13 (state 4) [((number[i]>max))]
Can anyone tell me why it skips this line (i == n) -> break; ?

It doesn't 'skip' that line. Spin executes every line that is executable. In your do the line i++ is always executable and therefore, because Spin explores all possible executions, the i++ line will be executed even when (i == n). The fix is:
do
:: (number[i] > max) -> max=number[i];
:: (i < n) -> i++
:: (i == n) -> break;
od;

Related

How to print optimal tours of a vehicle routing problem in CPLEX?

I modeled a Vehicle Routing Problem in CPLEX and now I'd like to print the optimal tours it found using post-processing.
My decision variable looks like this:
dvar boolean x[vehicles][edges];
1, if the edge is traversed by the vehicle, 0 otherwise.
Edge is a tuple containg two customers as follows:
tuple edge {
string i;
string j;
}
with customers being:
{string} customers = {"0", "1", "2", "3", "4", "5", "6"}
where 0 and 6 represent the depot where all tours start and end.
My post-processing right now looks the following:
execute {
writeln("Optimal value: ", cplex.getObjValue());
writeln("The following tours should be driven:");
for (var k in vehicles) {
write("Vehicle ", k, ": ");
var y = 0;
write(y);
for (var a in edges) {
if (x[k][a] == 1 && a.i == y) {
write(" - ", a.j);
y = a.j;
}
}
writeln();
}
}
Sadly it doesn't work the intented way.
you need to turn boolean values for edges into tours.
See MTZ from How to with OPL
// What is better and relies on CPLEX is the MTZ model ( Miller-Tucker-Zemlin formulation )
// Cities
int n = ...;
range Cities = 1..n;
// Edges -- sparse set
tuple edge {int i; int j;}
setof(edge) Edges = {<i,j> | ordered i,j in Cities};
int dist[Edges] = ...;
setof(edge) Edges2 = {<i,j> | i,j in Cities : i!=j};
int dist2[<i,j> in Edges2] = (<i,j> in Edges)?dist[<i,j>]:dist[<j,i>];
// Decision variables
dvar boolean x[Edges2];
dvar int u[1..n] in 1..n;
/*****************************************************************************
*
* MODEL
*
*****************************************************************************/
// Objective
minimize sum (<i,j> in Edges2) dist2[<i,j>]*x[<i,j>];
subject to {
// Each city is linked with two other cities
forall (j in Cities)
{
sum (<i,j> in Edges2) x[<i,j>]==1;
sum (<j,k> in Edges2) x[<j,k>] == 1;
}
// MTZ
u[1]==1;
forall(i in 2..n) 2<=u[i]<=n;
forall(e in Edges2:e.i!=1 && e.j!=1) (u[e.j]-u[e.i])+1<=(n-1)*(1-x[e]);
};
{edge} solution={e | e in Edges2 : x[e]==1};
int follower[Cities];
{int} sol;
execute
{
//writeln("path ",solution);
for(var e in solution) follower[e.i]=e.j;
var k=1;
for(var i in Cities)
{
sol.add(k);
k=follower[k];
}
writeln("sol = ",sol);
}
/*
which gives
// solution (optimal) with objective 7542
sol = {1 22 31 18 3 17 21 42 7 2 30 23 20 50 29 16 46 44 34 35 36 39 40 37 38 48
24 5 15 6 4 25 12 28 27 26 47 13 14 52 11 51 33 43 10 9 8 41 19 45 32
49}
*/

Fastest way to eliminate consecutive duplicates from array in objective-C

Prepping for interview. Trying to work out a solution for the question "Fastest way to eliminate consecutive duplicates from array" using objective-C. I.e input =[1,2,2,1,2,3,3,4] output =[1,2,1,2,3,4]
For in-array approach: Loop through element in array, if element == previous element, remove it and readjust all other elements to move step down.
For approach where we can use another array. If element == previous element, don't add it to new "Unique array", else add it to Unique array.
Are there any better solutions? Code is below. Any optimizations possible?
Using another array
//Pseudocode for sucessive dup elimination when using another array
//
//duplicateLessArray = empty array
//previous element = not set
//
//for (loop through each element in origArray)
// if(previous element == not set or element != previous element)
// set previousElement = element
// add element to duplicateLessArray
//
NSMutableArray *duplicateLessArray ;
duplicateLessArray = [[NSMutableArray alloc] init] ;
for (NSNumber *nextNumber in origArray)
{
if ([nextNumber intValue] != [[duplicateLessArray lastObject] intValue])
{
[duplicateLessArray addObject:nextNumber] ;
}
}
NSLog(#"Duplicate less array = %#",duplicateLessArray) ;
Using same array
//Pseudocode for in array sucessive dup elimination
//
//previous element = not set
//
//for (loop through each element in origArray)
// if(previous element == not set or element != previous element)
// set previousElement = element
// else
// delete it from origArray
// move back all elements by 1
NSInteger numElementsInDupLessArray = 0 ;
NSNumber *prevElement ;
for (NSNumber *nextNumber in [origArray copy])
{
if (numElementsInDupLessArray == 0 || [nextNumber intValue] != [prevElement intValue])
{
prevElement=nextNumber ;
numElementsInDupLessArray++;
}
else
{
[origArray removeObjectAtIndex:numElementsInDupLessArray] ;
}
}
NSLog(#"Duplicate less array = %#",origArray) ;
There is optimization for in-array approach:
Instead of removing elements one-by-one (this may cause O(n^2) complexity) just shift single elements.
Pseudocode:
numOfRemoved = 0
GoodValue = A[0]
for i = 1 to arrayEnd //note start from 2nd element
if A[i] = GoodValue then
numOfRemoved++
else
GoodValue = A[i]
A[i-numOfRemoved] = A[i]
Resize array once to (Length - numOfRemoved)
Example (' denotes current element, nr is numOfRemoved)
[5 5 1 7 7 7 4] nr = 0 ; 5 stays at index 0
[5 '5 1 7 7 7 4] nr = 0->1
[5 5 '1 7 7 7 4] nr = 1 ; 1 goes to index 2-1 = 1
[5 1 1 '7 7 7 4] nr = 1 ; 7 goes to index 2
[5 1 7 7 '7 7 4] nr = 1->2
[5 1 7 7 7 '7 4] nr = 2->3
[5 1 7 4 7 7 '4] nr = 3 ; 4 goes to index 6-3 = 3
[5 1 7 4] resize

TWIN PRIMES BETWEEN 2 VALUES wrong results

I've been working on this program to count how many twin primes between two values and it's been specified that twin primes come in the (6n-1, 6n+1) format, with the exception of (3, 5). My code seems to work fine, but it keeps giving me the wrong result....1 less couple of twin primes than i should get. Between 1 and 40, we should have 5 twin primes, but I'm always getting 4. é
What am I doing wrong? Am I not taking into account (3, 5)?
Here's my code:
#include <stdio.h>
int prime (int num) {
int div;
if (num == 2) return 1;
if (num % 2 == 0) return 0;
div = 3;
while (div*div <= num && num%div != 0)
div = div + 2;
if (num%div == 0)
return 0;
else
return 1;
}
int main(void) {
int low, high, i, count, n, m;
printf("Please enter the values for the lower and upper limits of the interval\n");
scanf("%d%d", &low, &high);
printf("THIS IS THE LOW %d\n AND THIS IS THE HIGH %d\n", low, high);
i = low;
count = 0;
while (6*i-1>=low && 6*i+1<=high) {
n = 6*i-1;
m = 6*i+1;
if (prime(n) && prime(m)) ++count;
i = i + 1;
}
printf("Number of twin primes is %d\n", count);
return 0;
}
Your program misses (3 5) because 3 is not trapped as a prime number, and because 4 is not a multiple of 6. Rather than the main loop stepping by (effectively) 6, this answer steps by 1.
#include <stdio.h>
int prime (int num) {
int div;
if (num == 1) return 0; // excluded 1
if (num == 2 || num == 3) return 1; // included 3 too
if (num % 2 == 0) return 0;
div = 3;
while (div*div <= num) {
if (num % div == 0) // moved to within loop
return 0;
div += 2;
}
return 1;
}
int main(void) {
int low, high, i, count, n, m;
printf("Please enter the values for the lower and upper limits of the interval\n");
scanf("%d%d", &low, &high);
printf("THIS IS THE LOW %d\n AND THIS IS THE HIGH %d\n", low, high);
count = 0;
for (i=low; i<=high; i++) {
n = i-1;
m = i+1;
if (prime(n) && prime(m)) {
printf ("%2d %2d\n", n, m);
++count;
}
}
printf("Number of twin primes is %d\n", count);
return 0;
}
Program output
1
40
THIS IS THE LOW 1
AND THIS IS THE HIGH 40
3 5
5 7
11 13
17 19
29 31
Number of twin primes is 5
Next run:
3
10
THIS IS THE LOW 3
AND THIS IS THE HIGH 10
3 5
5 7
Number of twin primes is 2
https://primes.utm.edu/lists/small/100ktwins.txt
The five twin primes under forty are (3,5), (5,7), (11,13), (17,19), (29,31) so if you know that your code isn't counting (3,5) then it is working correctly, counting (5,7), (11,13), (17,19), and (29,31).
A possible fix would be to add an if-statement which adds 1 to "count" if the starting number is less than 4. I'm not really that used to reading C syntax so I had trouble getting my head around your formulas, sorry.
edit: since comments don't format code snippets:
i = low;
count = 0;
if (low <= 3 && high >= 3){
count ++; // accounts for (3,5) twin primes if the range includes 3
}
You have a problem in your prime function, this is the output of your prime function for the first ten prime evaluations
for(i=1;i<=10;i++) printf("%d\t%d",i,prime(i));
1 1
2 1
3 0
4 0
5 1
6 0
7 1
8 0
Note the prime() function from Weather Vane, you should include 3 as prime (and exclude 1).
From [1], twin primes are the ones that have a prime gap of two, differing by two from another prime.
Examples are (3,5) , (5,7), (11,13). The format (6n-1,6n+1) is true but for (3,5) as you stated. Your program runs almost ok since it shows the number of twin primes that are in the interval AND follows the rule mentioned above. This doesn't include (3,5). You can make a kind of exception (like if low<=3 add 1 to total count), or use another algorithm to count twin primes (like verify if i is prime, then count distance from i to next prime, if distance=2 then they are twin primes)
[1] http://en.wikipedia.org/wiki/Twin_prime

SPIN verifier: cannot prove LTL formulae

I have quite simpe sender-receiver protocol:
#define SZ 4
int sent = 0;
int received = 0;
chan ch = [SZ] of {int};
int varch;
init {
do
:: ((len(ch) < SZ) && (received != 1)) ->
d_step {
ch ! 1; sent = 1; printf("sent\n");
}
:: ((len(ch) == SZ) || ((received == 1) && (len(ch) > 0))) ->
d_step {
ch ? varch; received = 1; printf("received\n");
}
:: 1 -> /* simulates ramdomness */
atomic {
printf("timeout1\n");/*break; */
}
od;
}
which sends four packets and then receives them. Then I try to prove property: always send implies eventually receive:
ltl pr { [] ( (sent == 1) -> (<> (received == 1)) ) }
...and nothing happens: SPIN does not find both this property prove and its negation.
Why?
So, upon quick inspection, the LTL property cannot possibly be satisfied. The LTL property includes always but one viable execution is for the do::od statement to take the /* simulates randomness */ option forever. In that case, no queue will be 'received' and the LTL fails.
My SPIN run confirms the above (I put your code into a file 'sr.pml')
$ spin -a sr.pml
$ gcc -o pan pan.c
$ ./pan -a
pan:1: acceptance cycle (at depth 16)
pan: wrote sr.pml.trail
(Spin Version 6.3.2 -- 17 May 2014)
Warning: Search not completed
+ Partial Order Reduction
Full statespace search for:
never claim + (pr)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 60 byte, depth reached 20, errors: 1
12 states, stored (14 visited)
0 states, matched
14 transitions (= visited+matched)
0 atomic steps
hash conflicts: 0 (resolved)
Stats on memory usage (in Megabytes):
0.001 equivalent memory usage for states (stored*(State-vector + overhead))
0.290 actual memory usage for states
128.000 memory used for hash table (-w24)
0.534 memory used for DFS stack (-m10000)
128.730 total actual memory usage
pan: elapsed time 0 seconds
And then we can see the path with:
$ spin -p -t sr.pml
ltl pr: [] ((! ((sent==1))) || (<> ((received==1))))
starting claim 1
using statement merging
Never claim moves to line 4 [(1)]
2: proc 0 (:init::1) sr.pml:8 (state 1) [(((len(ch)<4)&&(received!=1)))]
4: proc 0 (:init::1) sr.pml:9 (state 5) [ch!1]
4: proc 0 (:init::1) sr.pml:10 (state 3) [sent = 1]
sent
4: proc 0 (:init::1) sr.pml:10 (state 4) [printf('sent\\n')]
Never claim moves to line 3 [((!(!((sent==1)))&&!((received==1))))]
6: proc 0 (:init::1) sr.pml:8 (state 1) [(((len(ch)<4)&&(received!=1)))]
Never claim moves to line 8 [(!((received==1)))]
8: proc 0 (:init::1) sr.pml:9 (state 5) [ch!1]
8: proc 0 (:init::1) sr.pml:10 (state 3) [sent = 1]
sent
8: proc 0 (:init::1) sr.pml:10 (state 4) [printf('sent\\n')]
10: proc 0 (:init::1) sr.pml:8 (state 1) [(((len(ch)<4)&&(received!=1)))]
12: proc 0 (:init::1) sr.pml:9 (state 5) [ch!1]
12: proc 0 (:init::1) sr.pml:10 (state 3) [sent = 1]
sent
12: proc 0 (:init::1) sr.pml:10 (state 4) [printf('sent\\n')]
14: proc 0 (:init::1) sr.pml:8 (state 1) [(((len(ch)<4)&&(received!=1)))]
16: proc 0 (:init::1) sr.pml:9 (state 5) [ch!1]
16: proc 0 (:init::1) sr.pml:10 (state 3) [sent = 1]
sent
16: proc 0 (:init::1) sr.pml:10 (state 4) [printf('sent\\n')]
<<<<<START OF CYCLE>>>>>
18: proc 0 (:init::1) sr.pml:16 (state 11) [(1)]
timeout1
20: proc 0 (:init::1) sr.pml:18 (state 12) [printf('timeout1\\n')]
spin: trail ends after 20 steps
#processes: 1
sent = 1
received = 0
queue 1 (ch): [1][1][1][1]
varch = 0
20: proc 0 (:init::1) sr.pml:7 (state 14)
20: proc - (pr:1) _spin_nvr.tmp:7 (state 10)
1 processes created
The <<<<<START OF CYCLE>>>> shows sr.pml at line 16 (:: 1 -> ...) executed forever. Also, there are other failures of the LTL. Run the SPIN search with './pan -a -i' to find the shortest trail; it indicates that your LTL isn't finding what you intend to find.

Whats causing timeout in Promela/SPIN?

I have the following promela code:
chan level = [0] of {int};
proctype Sensor (chan levelChan) {
int x;
do
:: true ->
levelChan ? x;
if
:: (x < 2) -> printf("low %d", x);
:: (x > 8) -> printf("high %d", x);
:: else -> printf("normal %d", x);
fi
od
}
init {
run Sensor(level);
int lvl = 5;
level ! lvl;
lvl = 0;
do
:: true ->
level ! lvl;
lvl++;
(lvl > 9) -> break;
od
}
I am expecting to send level (0-9) information into a channel and have the sensor output low|normal|high depending on this level. Its quite simple. But why SPIN saying its timeout all the time?
0: proc - (:root:) creates proc 0 (:init:)
Starting Sensor with pid 1
1: proc 0 (:init:) creates proc 1 (Sensor)
1: proc 0 (:init:) 1.pml:18 (state 1) [(run Sensor(level))]
2: proc 1 (Sensor) 1.pml:6 (state 11) [(1)]
3: proc 0 (:init:) 1.pml:20 (state 2) [lvl = 5]
4: proc 0 (:init:) 1.pml:20 (state 3) [level!lvl]
4: proc 1 (Sensor) 1.pml:8 (state 2) [levelChan?x]
5: proc 1 (Sensor) 1.pml:9 (state 9) [else]
6: proc 0 (:init:) 1.pml:21 (state 4) [lvl = 0]
normal 5 8: proc 1 (Sensor) 1.pml:12 (state 8) [printf('normal %d',x)]
9: proc 0 (:init:) 1.pml:22 (state 10) [(1)]
12: proc 1 (Sensor) 1.pml:6 (state 11) [(1)]
13: proc 0 (:init:) 1.pml:24 (state 6) [level!lvl]
13: proc 1 (Sensor) 1.pml:8 (state 2) [levelChan?x]
14: proc 1 (Sensor) 1.pml:9 (state 9) [((x<2))]
low 0 15: proc 1 (Sensor) 1.pml:10 (state 4) [printf('low %d',x)]
17: proc 0 (:init:) 1.pml:25 (state 7) [lvl = (lvl+1)]
19: proc 1 (Sensor) 1.pml:6 (state 11) [(1)]
timeout
#processes: 2
19: proc 1 (Sensor) 1.pml:8 (state 2)
19: proc 0 (:init:) 1.pml:26 (state 8)
2 processes created
It seem to only do 1 iteration of the do loop why?
The statements in the init process's do loop are run in sequence.
do
:: true ->
level ! lvl;
lvl++;
(lvl > 9) -> break;
od
The very first time the do loop is run it will send lvl over the level channel, increase the lvl (so it is now 1) and then test (lvl > 9). This is false so will block and causes the timeout.
To have multiple options in a do loop you need :: to define the start of each option:
do
:: true ->
level ! lvl;
lvl++;
:: (lvl > 9) -> break;
od
However this will still not perform as expected. When lvl is greater than 9 both options of the do loop are valid and either one can be chosen, so the loop will not necessarily break when lvl > 9 it could choose to continue to send the lvl over the level channel and increase lvl.
You need to have a condition on the first do option as well as the second:
do
:: (lvl <= 9) ->
level ! lvl;
lvl++;
:: (lvl > 9) -> break;
od
It might be nicer to use the for loop syntax for this example:
init {
run Sensor(level);
int lvl = 5;
level ! lvl;
for (lvl : 0..9){
level ! lvl;
}
}
Note that this example will still have a timeout error caused by Sensor's do loop, when the init process has finished Sensor will still try to read from the level channel and timeout.