Spin and Promela: never and cycle - spin

I'm running spin in validation mode with the code like below. Got a problem with function called 'never'. While execution it gives me an error that functions inc(), dec() and reset() have never been accomplished. But if i add a cycle, it works great. By documentation, 'never' checks the variables on every step. So, why it does not work without a cycle?
int x=0
proctype Inc(){
do
::true ->
if
::x<10->x=x+1
fi
od
}
proctype Dec(){
do
::true ->
if
::x>0->x=x-1
fi
od
}
proctype Reset(){
do
::true ->
if
::x==10->x=0
fi
od
}
never { // if I need this to work, i have to add
To_Init: // this line
if
:: (x<0) || (10<x) -> goto accept
:: else -> goto To_Init // and that line
fi;
accept:
}
init{
run Inc();
run Dec();
run Reset();
}
'Never' block, that gives me a warning
never {
if
:: (x<0) || (10<x) -> goto accept
fi;
accept:
}
actually, thats not an error, that's kind of warning, shows unreached in proctype Inc, Dec, Reset, Init. Full warning log is below.
warning: for p.o. reduction to be valid the never claim must be stutter-invariant
(never claims generated from LTL formulae are stutter-invariant)
(Spin Version 6.2.7 — 2 March 2014)
+ Partial Order Reduction
Full statespace search for:
never claim + (never_0)
assertion violations + (if within scope of claim)
acceptance cycles + (fairness disabled)
invalid end states - (disabled by never claim)
State-vector 28 byte, depth reached 0, errors: 0
1 states, stored
0 states, matched
1 transitions (= stored+matched)
0 atomic steps
hash conflicts: 0 (resolved)
Stats on memory usage (in Megabytes):
0.000 equivalent memory usage for states (stored*(State-vector + overhead))
0.289 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
unreached in proctype Inc
l31never-no-cycle:6, state 3, "x = (x+1)"
l31never-no-cycle:6, state 4, "((x<10))"
l31never-no-cycle:4, state 6, "(1)"
l31never-no-cycle:9, state 9, "-end-"
(4 of 9 states)
unreached in proctype Dec
l31never-no-cycle:15, state 3, "x = (x-1)"
l31never-no-cycle:15, state 4, "((x>0))"
l31never-no-cycle:13, state 6, "(1)"
l31never-no-cycle:18, state 9, "-end-"
(4 of 9 states)
unreached in proctype Reset
l31never-no-cycle:24, state 3, "x = 0"
l31never-no-cycle:24, state 4, "((x==10))"
l31never-no-cycle:22, state 6, "(1)"
l31never-no-cycle:27, state 9, "-end-"
(4 of 9 states)
unreached in claim never_0
l31never-no-cycle:35, state 6, "-end-"
(1 of 6 states)
unreached in init
l31never-no-cycle:39, state 2, "(run Dec())"
l31never-no-cycle:40, state 3, "(run Reset())"
l31never-no-cycle:41, state 4, "-end-"
(3 of 4 states)

A never claim reports an error in two case: 1) an 'accept' cycle is detected, or 2) the never claim completes. A third possibility is if the never claim cannot take a step; this third possibility is the one your code is producing
When your claim was:
never {
if
:: (x<0) || (10<x) -> goto accept
fi;
accept:
}
the initial state has no possible step. That is, the never claim start state is just before the if; from that state where x==0 there is no possible next step.
When there is no possible step in a never claim, the verifier backtracks to a state where a step can be taken. In your case, there is no place to back up to and your verification ends because there is nothing more to do. The verifier then notes that lots of code didn't execute (because, in fact, nothing executed in your model).
You can tell that this is not what you anticipated because of all the unexecuted code. But is it not reported as an error.
For your subsequent case, you added an else. In this case the verifier can take a step in the never claim and thus your verification proceeds.

Related

The problem of different result values ​due to capturing in Kotlin sequence

If a value called prime is declared externally in the problem code, Capturing occurs, resulting in different results. Can someone tell me in detail why the result value is different when capturing occurs?
normal code
val primes: Sequence<Int> = sequence {
var numbers = generateSequence(2) { it + 1 }
while (true) {
val prime = numbers.first()
yield(prime)
numbers = numbers.drop(1)
.filter {
it % prime != 0
}
}
}
println(primes.take(10).toList()) // [2, 3, 5, 7. 11, 13, 17, 19, 23, 29]
problem code
val primes: Sequence<Int> = sequence {
var numbers = generateSequence(2) { it + 1 }
var prime: Int
while (true) {
prime = numbers.first()
yield(prime)
numbers = numbers.drop(1)
.filter {
it % prime != 0
}
}
}
println(primes.take(10).toList()) // [2, 3, 5, 6, 7, 8, 9, 10, 11, 12]
Lambda capture occurs when using sequences
When you call the method filter { it % prime != 0 } you permanently attach one filter, with its lambda function, to the numbers Sequence object. The value of prime in that lambda is captured from the enclosing code. With each loop, more and more filters are attached to the numbers Sequence.
In the first (working) example, each time a filter lambda is attached to the numbers Sequence, it gets its own unique version of the prime variable. Specifically, it gets the unique val prime that is defined at the start of the while loop in which that filter lambda is attached. That's just what you want.
In the second (broken) example, there is only one prime variable throughout the program: the var prime defined outside the loop. It changes every time the while loop runs. That means that every filter lambda is identical at any point in time: they all use the same prime value, being the last number taken off the front of the (chopped) numbers sequence. And prime keeps going up by one with each iteration. All in all, it means with each loop all the identical filter lambda functions also change and so have no discernible effect on the numbers sequence, or in turn the sequence printed to the screen.
Because the filter method is evaluated lazily, every iteration of the loop again and again. In the first code block, you define prime locally so that's what's captured. In the second block, it knows prime is reassigned every time, so it'll only look at the latest value.

How do you test a Require statement in a smartcontract using Mocha?

I am fairly new to developing smartcontracts and have run into an issue while testing. My intention is to ensure the smartcontract cannot mint more than 13 ERC721 tokens. My understanding is that a require function can have a second string argument that will revert a string as an error if the require condition is not met. Is this correct?
The following is my smart contract code:
contract TheCondemned_Episode is ERC721Enumerable {
string[] public episodes;
constructor() ERC721("TheCondemned_e1", "TCe1") public {
}
function mint(string memory _episode) public {
require(episodes.length <= 13, "Cannot make more than 13 episodes");
episodes.push(_episode);
uint _id= episodes.length;
_mint(msg.sender, _id);
}
}
And the test I am running is as follows:
it('Cannot create more than 13 episodes', async() => {
for(var i=0; i===13; i++){
var episode= `Episode ${i}`
await contract.mint(episode)
}
try {
await contract.mint('Episode 14');
assert(true);
}
catch (err) {
return;
}
assert(false, "The contract did not throw.");
The test fails and returns "The contract did not throw". What is the best practice in regards to catching a revert string from a failed require condition when testing?
My understanding is that a require function can have a second string argument that will revert a string as an error if the require condition is not met. Is this correct?
That's correct. Here's an example of an always failing require() condition that throws an exception with the error message.
require(false, 'Error message');
However, you have a logical error in the Solidity require() condition, as well as in the JS test snippet.
First, let's uncover the Solidity code. For simplicity, let's assume you're allowing to mint only 1 episode.
require(episodes.length <= 1, "Cannot make more than 1 episode");
First iteration (expected to pass)
episodes.length is 0, that's <= 1. Condition passes, you mint the first token, and then push to the episodes array, so its length becomes 1 after the condition.
Second iteration (expected to fail)
episodes.length is 1, that's still <= 1. So the condition passes as well.
Solution: Replace the <= (less than or equal) to just < (less than).
require(episodes.length < 1, "Cannot make more than 1 episode");
First iteration (expected to pass)
episodes.length is 0, that's < 1. Condition passes, you mint the first token, and then push to the episodes array, so its length becomes 1 after the condition.
Second iteration (expected to fail)
episodes.length is 1, which fails the condition 1 < 1, as you expect.
I'm assuming that your intention in the JS snippet is to call the mint() function 13 times in the loop, and then 14th time in the try/catch block.
However, the loop currently doesn't perform any iteration. So in fact, you're only executing the mint() function once (in the try/catch block).
The second parameter in the for loop is a condition stating "this loop will keep iterating for as long as this condition is met". But since you set the value of i to 0 in the first parameter, the loop condition (i===13) is not met, and the loop doesn't perform even the first iteration.
Solution: Check whether the i is "less than 13" instead of just "equals 13".
for(var i = 0; i < 13; i++) {
This way, the loop will iterate 13 times.

Solidity transaction error when transfer ether

env: mac, truffle, ganache
Is there anyone can tell me that why I can't transfer ether from one account to another? below is the test code and debug info.
truffle(develop)> web3.eth.getBalance(web3.eth.accounts[2])
{ [String: '80999999999999440773'] s: 1, e: 19, c: [ 809999, 99999999440773 ] }
truffle(develop)> web3.eth.getBalance(web3.eth.accounts[4])
{ [String: '98999999999999979000'] s: 1, e: 19, c: [ 989999, 99999999979000 ] }
truffle(develop)> web3.eth.sendTransaction({from: web3.eth.accounts[4], to: web3.eth.accounts[2], value: web3.toWei(1, "ether")})
'0xc56c7982006ed5bd9f47523c5f38e3e86185b389a02b7e7c4d23b1e33bd07224'
truffle(develop)> debug 0xc56c7982006ed5bd9f47523c5f38e3e86185b389a02b7e7c4d23b1e33bd07224
Gathering transaction data...
Addresses affected:
0xc5fdf4076b8f3a5357c5e395ab970b5b54098fef(UNKNOWN)
Warning: The source code for one or more contracts could not be found.
Commands:
(enter) last command entered (step next)
(o) step over, (i) step into, (u) step out, (n) step next
(;) step instruction, (p) print instruction, (h) print this help, (q) quit
(b) toggle breakpoint, (c) continue until breakpoint
(+) add watch expression (`+:<expr>`), (-) remove watch expression (-:<expr>)
(?) list existing watch expressions
(v) print variables and values, (:) evaluate expression - see `v`
?:
(node:10530) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 4): TypeError: Cannot read property 'gasCost' of undefined
The debugger is used to step through a smart contract. You're just doing a simple ether transfer between two addresses. If you output the balances of your accounts after doing the transfer, you should see the transfer was successful.

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.

Threads and clocked threads in SystemC

While reading about the threads in SystemC, it is said that while(true) loop must be used inside the functions. Why is it so?
Can you please see the example code given below and explain why the while loop is used for threads and wait() command is used along with the loop:
1 //-----------------------------------------------------
2 // This is my second Systemc Example
3 // Design Name : first_counter
4 // File Name : first_counter.cpp
5 // Function : This is a 4 bit up-counter with
6 // Synchronous active high reset and
7 // with active high enable signal
8 //-----------------------------------------------------
9 #include "systemc.h"
10
11 SC_MODULE (first_counter) {
12 sc_in_clk clock ; // Clock input of the design
13 sc_in<bool> reset ; // active high, synchronous Reset input
14 sc_in<bool> enable; // Active high enable signal for counter
15 sc_out<sc_uint<4> > counter_out; // 4 bit vector output of the counter
16
17 //------------Local Variables Here---------------------
18 sc_uint<4> count;
19
20 //------------Code Starts Here-------------------------
21 // Below function implements actual counter logic
22 void incr_count () {
23 // For threads, we need to have while true loop
24 while (true) {
25 // Wait for the event in sensitivity list to occure
26 // In this example - positive edge of clock
27 wait();
28 if (reset.read() == 1) {
29 count = 0;
30 counter_out.write(count);
31 // If enable is active, then we increment the counter
32 } else if (enable.read() == 1) {
33 count = count + 1;
34 counter_out.write(count);
35 }
36 }
37 } // End of function incr_count
38
39 // Below functions prints value of count when ever it changes
40 void print_count () {
41 while (true) {
42 wait();
43 cout<<"#" << sc_time_stamp() <<
44 " :: Counter Value "<<counter_out.read()<<endl;
45 }
46 }
47
48 // Constructor for the counter
49 // Since this counter is a positive edge trigged one,
50 // We trigger the below block with respect to positive
51 // edge of the clock
52 SC_CTOR(first_counter) {
53 // Edge sensitive to clock
54 SC_THREAD(incr_count);
55 sensitive << clock.pos();
56 // Level Sensitive to change in counter output
57 SC_THREAD(print_count);
58 sensitive << counter_out;
59 } // End of Constructor
60
61 }; // End of Module counter
SC_THREAD or SC_CTHREAD should have infinite loop to keep the thread not being terminated. If you don't put for(;;) or while(true) in the function body, when the execution reaches the end of function scope, the thread is terminated. In such case, your thread will never be waken up by the sensitive list for processing something. Or you can it transform to equivalent SC_METHOD, then you can have no infinite loop.
SystemC is using non-preemptive thread, so if you don't use wait() to wait for something listed in static or dynamic sensitive list to happen, it causes a infinite execution in your thread. And CPU execution of your process won't get out of the function scope. Such that SystemC kernel won't able to continue to process other methods/threads and events to continue the simulation. And in the event-based simulation, the thread should only be run when the specified condition (events in the sensitive list) occur. So the wait() function can wait until the next event occurs and hand over the CPU execution to other threads/methods and SystemC kernel. Next time the event occurs, for example the positive edge of clock, wait() statement will return and continue your process.
In your example, your program is waiting for clock's positive edge trigger to increase the counter's value by 1. So, if you don't put wait() in your code, then incr_count will always increase the counter's value infinitely no matter the clock's status, and it won't stop. By using wait(), your thread will be blocked and wait for next clock positive edge trigger.
while(true) --> makes thread infinite, so that it can keep executing when it gets context
wait() --> forces the thread to lose context and allows something else to be executed