Find the minimum value of a variable across all possible executions with an LTL formula - model-checking

Consider the following Promela model of two processes that manipulate a shared variable N:
byte N = 0;
active [2] proctype P(){
byte temp, i;
i = 1;
do
:: i < 10 ->
temp = N;
temp++;
N = temp;
i++;
:: else ->
break;
od
}
How can I use LTL formula to find out the minimum value that the variable N can have when both processes are over ?

In general, that's not possible. An LTL formula expresses a property that must hold over an execution path, whereas by definition of minimum, you want to express a property over multiple execution paths. In fact N is considered minimum only if there is no other execution trace in which it has a smaller value.
Work-around. You can, however, find the minimum value of N by running Spin multiple times over an LTL formula with an increasing value for N, and examine the output to determine the correct answer.
Consider this example:
byte N = 0;
short cend = 0;
active [2] proctype P(){
byte temp, i;
i = 1;
do
:: i < 10 ->
temp = N;
temp++;
N = temp;
i++;
:: else ->
break;
od
cend++;
}
ltl p0 { [] ((cend == 2) -> 2 <= N) };
ltl p1 { [] ((cend == 2) -> 3 <= N) };
We have two properties:
p0 states that it is globally true that when both processes terminate the value of N is at least 2. This formula is verified:
~$ spin -a -search -bfs -ltl p0 m.pml
...
Full statespace search for:
never claim + (p0)
assertion violations + (if within scope of claim)
cycle checks - (disabled by -DSAFETY)
invalid end states - (disabled by never claim)
State-vector 36 byte, depth reached 98, errors: 0
...
p1 states that it is globally true that when both processes terminate the value of N is at least 3. This formula is not verified:
~$ spin -a -search -bfs -ltl p1 m.pml
...
Full statespace search for:
never claim + (p1)
assertion violations + (if within scope of claim)
cycle checks - (disabled by -DSAFETY)
invalid end states - (disabled by never claim)
State-vector 36 byte, depth reached 95, errors: 1
...
So we know that the minimum value of N is equal to 2.
Let's see the counter-example:
~$ spin -l -g -p -t m.pml
ltl p0: [] ((! ((cend==2))) || ((2<=N)))
ltl p1: [] ((! ((cend==2))) || ((3<=N)))
starting claim 2
using statement merging
1: proc 1 (P:1) m.pml:7 (state 1) [i = 1]
P(1):i = 1
2: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
3: proc 0 (P:1) m.pml:7 (state 1) [i = 1]
P(0):i = 1
4: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
5: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 0
6: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 1
7: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 0
8: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 1
9: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 1
10: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 2
11: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
12: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 1
13: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 2
14: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 2
15: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 3
16: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
17: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 2
18: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 3
19: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 3
20: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 4
21: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
22: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 3
23: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 4
24: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 4
25: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 5
26: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
27: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 4
28: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 5
29: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 5
30: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 6
31: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
32: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 5
33: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 6
34: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 6
35: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 7
36: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
37: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 6
38: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 7
39: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 7
40: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 8
41: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
42: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 7
43: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 8
44: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 8
45: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 9
46: proc 1 (P:1) m.pml:9 (state 2) [((i<10))]
47: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 1
48: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 2
49: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
50: proc 1 (P:1) m.pml:10 (state 3) [temp = N]
P(1):temp = 1
51: proc 1 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(1):temp = 2
52: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 1
53: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 2
54: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 2
55: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 3
56: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
57: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 2
58: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 3
59: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 3
60: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 4
61: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
62: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 3
63: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 4
64: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 4
65: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 5
66: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
67: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 4
68: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 5
69: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 5
70: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 6
71: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
72: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 5
73: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 6
74: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 6
75: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 7
76: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
77: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 6
78: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 7
79: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 7
80: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 8
81: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
82: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 7
83: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 8
84: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 8
85: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 9
86: proc 0 (P:1) m.pml:9 (state 2) [((i<10))]
87: proc 0 (P:1) m.pml:10 (state 3) [temp = N]
P(0):temp = 8
88: proc 0 (P:1) m.pml:11 (state 4) [temp = (temp+1)]
P(0):temp = 9
89: proc 0 (P:1) m.pml:12 (state 5) [N = temp]
N = 9
90: proc 0 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(0):i = 10
91: proc 0 (P:1) m.pml:14 (state 7) [else]
92: proc 1 (P:1) m.pml:12 (state 5) [N = temp]
N = 2
93: proc 1 (P:1) m.pml:13 (state 6) [i = (i+1)]
P(1):i = 10
94: proc 1 (P:1) m.pml:14 (state 7) [else]
95: proc 0 (P:1) m.pml:17 (state 12) [cend = (cend+1)]
cend = 1
96: proc 1 (P:1) m.pml:17 (state 12) [cend = (cend+1)]
cend = 2
spin: trail ends after 96 steps
#processes: 2
N = 2
cend = 2
96: proc 1 (P:1) m.pml:18 (state 13) <valid end state>
96: proc 0 (P:1) m.pml:18 (state 13) <valid end state>
96: proc - (p1:1) _spin_nvr.tmp:11 (state 6)
2 processes created
As you can see, the counter-example corresponds to an execution in which:
proc0 stores the value N = 0 into temp and then stops executing any instruction
proc1 increments the value of N for 8 times
proc0 resets the value of N back to 1
proc1 copies N = 1 in temp and then stops executing any instruction
proc0 increments N up to 9 and then terminates
proc1 resets the value of N back to 2 and then terminates

Related

How to get the first number in each line of a file in python?

inputFile = open(filename, "r")
with open(filename) as f:
content = f.readlines()
li = [x.strip() for x in content]
print(li)
Output:
['4', '0 1 2 3', '1 0 2 3', '2 0 1 3', '3 0 1 2']
Expected Output:
The number of total vertices is 4
Vertex 0: (0, 1) (0, 2) (0, 3)
Vertex 1: (1, 0) (1, 2) (1, 3)
Vertex 2: (2, 0) (2, 1) (2, 3)
Vertex 3: (3, 0) (3, 1) (3, 2)
I know how to convert a element into an integer but each line is different and the txt file is in this format:
4
0 1 2 3
1 0 2 3
2 0 1 3
3 0 1 2
should I need to separated by.split() method?
Try:
with open("your_file.txt", "r") as f:
total_vertices = int(next(f))
vertices = []
for _ in range(total_vertices):
row = list(map(int, next(f).split()))
vertices.append([(row[0], v) for v in row[1:]])
print("The number of total vertices is", total_vertices)
for i, v in enumerate(vertices):
print(f"Vertex {i}:", *v)
Prints:
The number of total vertices is 4
Vertex 0: (0, 1) (0, 2) (0, 3)
Vertex 1: (1, 0) (1, 2) (1, 3)
Vertex 2: (2, 0) (2, 1) (2, 3)
Vertex 3: (3, 0) (3, 1) (3, 2)

Recover solution from dynamic programming memo table

My goal is to find the longest sub-list of a list of numbers such that each element is at most 1 away from each other, e.g., a list of [0,1,2,2,3,3] from the list [0,4,1,2,2,3,3,1]. I create the memo table as follows:
def memoizeLSS(a):
T = {}
n = len(a)
for j in range(-1, n):
T[(n, j)] = 0 # i = n and j
for i in range(0, n+1):
for j in range(-1, n+1):
T[(i, j)] = 0
for i in range(n-1, -1, -1):
for j in range(n-1, -1, -1):
aj = a[j] if 0 <= j < len(a) else None
if aj != None and abs(a[i] - a[j]) > 1:
T[(i, j)] = T[(i + 1, j)]
elif aj == None or abs(a[i] - a[j]) <= 1:
T[(i, j)] = max(T[(i + 1, i)] + 1, T[(i + 1, j)])
for i in range(n-2, -1, -1):
T[(i, -1)] = max(T[(i+1, -1)], T[(i+1, 0)], T[(i, 0)], 0)
return T
I can figure out the maximum length, however I'm having trouble reconstructing the subsequence from the memo table. I tried creating a list of paired indices where the numbers are <= 1 away from and building it up from there, but there are pairs of indices which are not part of the sub-sequence and I'm stumped on what to do from here or even if creating this list is useful:
def computeLSS(a):
T = {}
Y_list = []
# Now populate the entries for the base case
n = len(a)
for j in range(-1, n):
T[(n, j)] = 0 # i = n and j
for i in range(0, n+1):
for j in range(-1, n+1):
T[(i, j)] = 0
for i in range(n-1, -1, -1):
for j in range(n-1, -1, -1):
aj = a[j] if 0 <= j < len(a) else None
if aj != None and abs(a[i] - a[j]) > 1:
T[(i, j)] = T[(i + 1, j)]
elif aj == None or abs(a[i] - a[j]) <= 1:
T[(i, j)] = max(T[(i + 1, i)] + 1, T[(i + 1, j)])
if T[(i, j)] == T[(i + 1, i)] + 1 and a[i] != a[j]:
Y_list.append((i, j))
for i in range(n-2, -1, -1):
T[(i, -1)] = max(T[(i+1, -1)], T[(i+1, 0)], T[(i, 0)], 0)
Y_list_new = []
for x,y in Y_list:
if x==y:
pass
if (y,x) in Y_list_new:
pass
else:
Y_list_new.append((x,y))
print(Y_list_new)
#print(T)
return
Any help is appreciated. Thank you!

Dynamic Programming, create a memo table longest stable subsequence

I have worked on a dynamic programming problem for quite some time now and am stuck, so any help is much appreciated.
Here is the first part of the problem which I was able to get the tests to pass.
def lssLength(a, i, j):
aj = a[j] if 0 <= j < len(a) else None
# Implement the recurrence below. Use recursive calls back to lssLength
assert 0 <= i <= len(a)
if i >= len(a) or j >= len(a):
return 0
if aj and abs(a[i] - a[j]) > 1:
return lssLength(a, i+1, j)
if aj is None or (abs(a[i] - a[j]) <= 1 and i != j):
return max(lssLength(a, i+1, j), lssLength(a, i+1, i) + 1)
else:
return lssLength(a, i+1, j)
Here are my test cases for the first problem:
def test_lss_length(self):
# test 1
n1 = lssLength([1, 4, 2, -2, 0, -1, 2, 3], 0, -1)
print(n1)
self.assertEqual(4, n1)
# test 2
n2 = lssLength([1, 2, 3, 4, 0, 1, -1, -2, -3, -4, 5, -5, -6], 0, -1)
print(n2)
self.assertEqual(8, n2)
# test 3
n3 = lssLength([0, 2, 4, 6, 8, 10, 12], 0, -1)
print(n3)
self.assertEqual(1, n3)
# test 4
n4 = lssLength(
[4, 8, 7, 5, 3, 2, 5, 6, 7, 1, 3, -1, 0, -2, -3, 0, 1, 2, 1, 3, 1, 0, -1, 2, 4, 5, 0, 2, -3, -9, -4, -2, -3,
-1], 0, -1)
print(n4)
self.assertEqual(14, n4)
Now I need to take the recursive solution and convert it to dynamic programming, and this is where I am stuck. I am using the same tests as before, but the tests are failing.
def memoizeLSS(a):
T = {} # Initialize the memo table to empty dictionary
# Now populate the entries for the base case
# Now fill out the table : figure out the two nested for loops
# It is important to also figure out the order in which you iterate the indices i and j
# Use the recurrence structure itself as a guide: see for instance that T[(i,j)] will depend on T[(i+1, j)]
n = len(a)
for i in range(0, n+1):
for j in range(-1, n+1):
T[(i, j)] = 0
for i in range(n-1, -1, -1):
for j in range(n-1, -1, -1):
if abs(a[i] - a[j]) > 1:
try:
T[(i, j)] = max(0, T[(i, j+1)], T[(i+1, j)])
except Exception:
T[(i, j)] = 0
elif abs(a[i] - a[j]) <= 1 and i != j:
T[(i, j)] = T[(i+1, j+1)] + 1
else:
T[(i, j)] = max(0, T[(i+1, j+1)])
for i in range(n-2, -1, -1):
T[(i, -1)] = max(T[(i+1, -1)], T[(i+1, 0)], T[(i, 0)], 0)
return T
If you've read all of this, thank you so much. I know it is a lot and really appreciate your time. Any pointers to reading materials, etc. is much appreciated.
If there are more details required, please let me know. Thanks.
Your solution only worked for the first test case. Below is a corrected version:
def memoizeLSS(a):
T = {} # Initialize the memo table to empty dictionary
n = len(a)
for j in range(-1, n):
T[(n, j)] = 0 # i = n and j
# Now populate the entries for the base case
# Now fill out the table : figure out the two nested for loops
# It is important to also figure out the order in which you iterate the indices i and j
# Use the recurrence structure itself as a guide: see for instance that T[(i,j)] will depend on T[(i+1, j)]
n = len(a)
for i in range(0, n + 1):
for j in range(-1, n + 1):
T[(i, j)] = 0
for i in range(n-1, -1, -1):
for j in range(n-1, -1, -1):
aj = a[j] if 0 <= j < len(a) else None
if aj != None and abs(a[i] - a[j]) > 1:
T[(i, j)] = T[(i+1, j)]
elif aj == None or abs(a[i] - a[j]) <= 1:
T[(i, j)] = max(T[(i+1, i)] + 1, T[(i + 1, j)])
for i in range(n-2, -1, -1):
T[(i, -1)] = max(T[(i+1, -1)], T[(i+1, 0)], T[(i, 0)], 0)
return T

Iterate over list of lists appending each item into new lists based on index [duplicate]

This question already has answers here:
Transpose nested list in python
(4 answers)
Closed 2 years ago.
I want to take a list of lists that contain 6 items each and append each item into 6 new lists based on index location.
Here's what I've tried so far:
pos1 = []
pos2 = []
pos3 = []
pos4 = []
pos5 = []
pos6 = []
numbers = [[2,3,4,5,6,7][12,34,65,34,76,78][1,2,3,4,5,6][21,34,5,87,45,76][76,45,34,23,5,24]]
index_count = 0
while True:
index_count < 6
print(index_count)
for l in numbers:
for item in l:
time.sleep(1)
print(pos1)
if index_count == 0:
pos1.append(item)
index_count = index_count + 1
elif index_count == 1:
pos2.append(item)
index_count = index_count + 1
elif index_count == 2:
pos3.append(item)
index_count = index_count + 1
elif index_count == 3:
pos4.append(item)
index_count = index_count + 1
elif index_count == 4:
pos5.append(item)
index_count = index_count + 1
elif index_count == 5:
pos6.append(item)
index_count = index_count + 1
else:
break
print('working...')
I'm trying to get data lists that look like this:
pos1 = [2,12,1,21,76]
pos2 = [3,34,2,34,45]
pos3 = [4,65,3,5,34]
pos4 = [5,34,4,87,23]
pos5 = [6,76,5,45,5]
pos6 = [7,78,6,76,24]
Use zip() with *:
numbers = [[2,3,4,5,6,7], [12,34,65,34,76,78], [1,2,3,4,5,6], [21,34,5,87,45,76], [76,45,34,23,5,24]]
pos1,pos2,pos3,pos4,pos5,pos6 = map(list, zip(*numbers))
print(pos1)
print(pos2)
print(pos3)
print(pos4)
print(pos5)
print(pos6)
Prints:
[2, 12, 1, 21, 76]
[3, 34, 2, 34, 45]
[4, 65, 3, 5, 34]
[5, 34, 4, 87, 23]
[6, 76, 5, 45, 5]
[7, 78, 6, 76, 24]

Why is this read blocking when O_NONBLOCK is set?

Strace excerpt (please ignore sending xml to ssh):
dup(12) = 13
getsockname(13, {sa_family=AF_INET, sin_port=htons(46811), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getsockopt(13, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
fstat(13, {st_mode=S_IFSOCK|0777, st_size=0, ...}) = 0
getsockname(13, {sa_family=AF_INET, sin_port=htons(46811), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
getsockopt(13, SOL_SOCKET, SO_TYPE, [1], [4]) = 0
fcntl(13, F_SETFD, FD_CLOEXEC) = 0
fcntl(13, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(13, F_SETFL, O_RDWR|O_NONBLOCK) = 0
setsockopt(13, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
setsockopt(13, SOL_SOCKET, SO_REUSEPORT, [0], 4) = 0
setsockopt(13, SOL_TCP, TCP_NODELAY, [0], 4) = 0
setsockopt(13, SOL_TCP, TCP_CORK, [0], 4) = 0
fcntl(12, F_GETFL) = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(12, F_SETFL, O_RDWR) = 0
close(12) = 0
getpeername(13, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("127.0.0.1")}, [16]) = 0
sendto(13, "<stream:stream xmlns:stream='htt"..., 133, MSG_NOSIGNAL, NULL, 0) = 133
read(13, "SSH-2.0-OpenSSH_6.6.1\r\n", 4096) = 23
read(13, <unfinished ...>
(At the end I kill -9 it.)
The read() at the end was blocking; even though O_NONBLOCK was set via fcntl().
How is this possible?
Version info:
$ uname -r
3.16.4-1-ARCH
Because FD 13 is a dup() of FD 12, this line removes your O_NONBLOCK:
fcntl(12, F_SETFL, O_RDWR) = 0

Resources