I'm wondering whether it's possible to verify an LTL property in a program with a fairness constraint that states that multiple statements must be executed infinitely often.
E.g.:
bool no_flip;
bool flag;
active[1] proctype node()
{
do
:: skip -> progress00: no_flip = 1
:: skip -> progress01: flag = 1
:: !no_flip -> flag = 0
od;
}
// eventually we have flag==1 forever
ltl p0 { <> ([] (flag == 1)) }
This program is correct iff eventually the no_flip flag becomes true and flag becomes true.
However, running both 'pan -a' and 'pan -a -f' (weak fairness) yields a cycle through the no_flip=1 statement and the acceptance state (from LTL formula).
I thought the progress labels would enforce that the execution passed through them infinitely often, but that doesn't seem to be the case.
So, is it possible to add such kind of fairness constraints?
Thanks,
Nuno
Just the inclusion of a progress label itself does not guarantee that the execution will be limited to non-progress cases. You need to add 'non-progress' somewhere in your ltl or never claim.
As a never claim you enforce progress with <>[](np_) (using spin -p '<>[](np_)' to generate the never claim itself). A possible ltl form for your verification is:
ltl { []<>!(np_) && <>[](flag==1) }
Also note that making 'progress' does not mean visiting each progress label infinitely often; it means visiting any progress label infinitely often. So, when enforcing progress, a viable path through your code is the first do option - which is not what you expect.
Answering my own question, for this simple example, I can split each loop branch into separate processes. Then by running pan in weak fairness mode, I have the guarantee that each process will be scheduled eventually.
However, this "solution" is not very interesting for my case, since I have a model with dozens of branches in each process.. Any other ideas?
bool no_flip;
bool flag;
active[1] proctype n1()
{
do
:: skip -> no_flip = 1
od;
}
active[1] proctype n2()
{
do
:: skip -> flag = 1
od;
}
active[1] proctype n3()
{
do
:: !no_flip -> flag = 0
od;
}
// eventually we have flag==1 forever
ltl p0 { <>[] (flag == 1) }
Related
Is it safe, to share an array between promises like I did it in the following code?
#!/usr/bin/env perl6
use v6;
sub my_sub ( $string, $len ) {
my ( $s, $l );
if $string.chars > $len {
$s = $string.substr( 0, $len );
$l = $len;
}
else {
$s = $string;
$l = $s.chars;
}
return $s, $l;
}
my #orig = <length substring character subroutine control elements now promise>;
my $len = 7;
my #copy;
my #length;
my $cores = 4;
my $p = #orig.elems div $cores;
my #vb = ( 0..^$cores ).map: { [ $p * $_, $p * ( $_ + 1 ) ] };
#vb[#vb.end][1] = #orig.elems;
my #promise;
for #vb -> $r {
#promise.push: start {
for $r[0]..^$r[1] -> $i {
( #copy[$i], #length[$i] ) = my_sub( #orig[$i], $len );
}
};
}
await #promise;
It depends how you define "array" and "share". So far as array goes, there are two cases that need to be considered separately:
Fixed size arrays (declared my #a[$size]); this includes multi-dimensional arrays with fixed dimensions (such as my #a[$xs, $ys]). These have the interesting property that the memory backing them never has to be resized.
Dynamic arrays (declared my #a), which grow on demand. These are, under the hood, actually using a number of chunks of memory over time as they grow.
So far as sharing goes, there are also three cases:
The case where multiple threads touch the array over its lifetime, but only one can ever be touching it at a time, due to some concurrency control mechanism or the overall program structure. In this case the arrays are never shared in the sense of "concurrent operations using the arrays", so there's no possibility to have a data race.
The read-only, non-lazy case. This is where multiple concurrent operations access a non-lazy array, but only to read it.
The read/write case (including when reads actually cause a write because the array has been assigned something that demands lazy evaluation; note this can never happen for fixed size arrays, as they are never lazy).
Then we can summarize the safety as follows:
| Fixed size | Variable size |
---------------------+----------------+---------------+
Read-only, non-lazy | Safe | Safe |
Read/write or lazy | Safe * | Not safe |
The * indicating the caveat that while it's safe from Perl 6's point of view, you of course have to make sure you're not doing conflicting things with the same indices.
So in summary, fixed size arrays you can safely share and assign to elements of from different threads "no problem" (but beware false sharing, which might make you pay a heavy performance penalty for doing so). For dynamic arrays, it is only safe if they will only be read from during the period they are being shared, and even then if they're not lazy (though given array assignment is mostly eager, you're not likely to hit that situation by accident). Writing, even to different elements, risks data loss, crashes, or other bad behavior due to the growing operation.
So, considering the original example, we see my #copy; and my #length; are dynamic arrays, so we must not write to them in concurrent operations. However, that happens, so the code can be determined not safe.
The other posts already here do a decent job of pointing in better directions, but none nailed the gory details.
Just have the code that is marked with the start statement prefix return the values so that Perl 6 can handle the synchronization for you. Which is the whole point of that feature.
Then you can wait for all of the Promises, and get all of the results using an await statement.
my #promise = do for #vb -> $r {
start
do # to have the 「for」 block return its values
for $r[0]..^$r[1] -> $i {
$i, my_sub( #orig[$i], $len )
}
}
my #results = await #promise;
for #results -> ($i,$copy,$len) {
#copy[$i] = $copy;
#length[$i] = $len;
}
The start statement prefix is only sort-of tangentially related to parallelism.
When you use it you are saying, “I don't need these results right now, but probably will later”.
That is the reason it returns a Promise (asynchrony), and not a Thread (concurrency)
The runtime is allowed to delay actually running that code until you finally ask for the results, and even then it could just do all of them sequentially in the same thread.
If the implementation actually did that, it could result in something like a deadlock if you instead poll the Promise by continually calling it's .status method waiting for it to change from Planned to Kept or Broken, and only then ask for its result.
This is part of the reason the default scheduler will start to work on any Promise codes if it has any spare threads.
I recommend watching jnthn's talk “Parallelism, Concurrency,
and Asynchrony in Perl 6”.
slides
This answer applies to my understanding of the situation on MoarVM, not sure what the state of art is on the JVM backend (or the Javascript backend fwiw).
Reading a scalar from several threads can be done safely.
Modifying a scalar from several threads can be done without having to fear for a segfault, but you may miss updates:
$ perl6 -e 'my $i = 0; await do for ^10 { start { $i++ for ^10000 } }; say $i'
46785
The same applies to more complex data structures like arrays (e.g. missing values being pushed) and hashes (missing keys being added).
So, if you don't mind missing updates, changing shared data structures from several threads should work. If you do mind missing updates, which I think is what you generally want, you should look at setting up your algorithm in a different way, as suggested by #Zoffix Znet and #raiph.
No.
Seriously. Other answers seem to make too many assumptions about the implementation, none of which are tested by the spec.
A: if
:: q?a -> ...
:: else -> ...
fi
Note that a race condition is built-in to this type of code. How long
should the process wait, for instance, before deciding that the
message receive operation will not be executable? The problem can be
avoided by using message poll operations, for instance, as follows:
The above citation comes from http://spinroot.com/spin/Man/else.html
I cannot understand that argumentation. Just Spin can decide on q?a:
if q is empty then it is executable. Otherwise, it is blocking.
The given argument raised a race condition.
But, I can make the same argument:
byte x = 1;
A: if
:: x == 2 -> ...
:: else -> ...
fi
It is ok from point of Spin's view. But, I am asking, How long should the process wait, for instance, before deciding that the value of x will not be incremented by other process?
The argumentation is sound with respect to the semantics of Promela and the selection construct. Note that for selection, if multiple guard statements are executable, one of them will be selected non-deterministically. This in turns implies the semantics such that selection (even though it can non-deterministally execute guards) needs to determine which guards are executable at the point of invocation of the selection statement.
The question about the race condition might make more sense when considering the semantics of selection and message receives. Note that race condition in this case means that the output of the selection might depend on the time for which it needs to invoke the receive (i.e. whether it finishes at a point at which there is a message in the channel or not).
More specifically, for the selection statement, there should be no ambiguity in terms of feasible guards. Now, the message receive gets the message from the channel only if the channel is not empty (otherwise, it cannot finish executing and waits). Therefore, with respect to the semantics of receive, it is not clear whether it is executable before it is actually executed. In turn, else should execute if the receive is not executable. However, since else should execute only if ? is not executable, so to know if else is executable the program needs to know the future (or determine how much should it wait to know this, thus incurring the race condition).
Note that the argument does not apply to your second example:
byte x = 1;
A: if
:: x == 2 -> ...
:: else -> ...
fi
since here, to answer whether else is eligible no waiting is required (nor knowing the future), since the program can at any point determine if x == 2.
Consider this simple PROMELA model:
#define p (x!=4)
int x = 0;
init {
do
:: x < 10 ->
x++;
od
}
I wanted to verify this model with this simple claim, which was generated by using spin -f:
never { /* []p */
accept_init:
T0_init:
do
:: ((p)) -> goto T0_init
od;
}
However, the verification using
spin -a model.pml
cc -o pan pan.c
./pan
yields no result. Trying the -a option also does not deliver results.
Any random simulation shows, that obviously p is false at some point, so why does the never claim not work, despite I generated it with spin?
Am I missing something fundamental?
If you want to check []p, you will need to construct a never claim for ![]p.
From the reference:
To translate an LTL formula into a never claim, we have to consider first whether the formula expresses a positive or a negative property. A positive property expresses a good behavior that we would like our system to have. A negative property expresses a bad behavior that we claim the system does not have. A never claim is normally only used to formalize negative properties (behaviors that should never happen), which means that positive properties must be negated before they are translated into a claim.
put the claim in the source code (say, check.pml)
int x = 0;
init {
do
:: x < 10 ->
x++;
od
}
ltl { [] (x != 4) }
then
spin -a check.pml
cc pan.c -o pan
./pan -a
this gives
pan:1: assertion violated !( !((x!=4))) (at depth 16)
pan: wrote check.pml.trail
you can watch the trail with
./pan -r -v
IMHO, using an extra tool to construct the automaton from the claim is terribly inconvenient and often confusing.
I read the spin guide yet there is no answer for the following question:
I have a line in my code as following:
Ch?x
where Ch is a channel and x is channel type (to receive MSG)
What happens if Ch is empty? will it wait for MSG to arrive or not?
Do i need to check first if Ch is not empty?
basically all I want is that if Ch is empty then wait till MSG arrives and when it's arrive continue...
Bottom line: the semantics of Promela guarantee your desired behaviour, namely, that the receive-operation blocks until a message can be received.
From the receive man page
EXECUTABILITY
The first and the third form of the statement, written with a single
question mark, are executable if the first message in the channel
matches the pattern from the receive statement.
This tells you when a receive-operation is executable.
The semantics of Promela then tells you why executability matters:
As long as there are executable transitions (corresponding to the
basic statements of Promela), the semantics engine will select one of
them at random and execute it.
Granted, the quote doesn't make it very explicit, but it means that a statement that is currently not executable will block the executing process until it becomes executable.
Here is a small program that demonstrates the behaviour of the receive-operation.
chan ch = [1] of {byte};
/* Must be a buffered channel. A non-buffered, i.e., rendezvous channel,
* won't work, because it won't be possible to execute the atomic block
* around ch ! 0 atomically since sending over a rendezvous channel blocks
* as well.
*/
short n = -1;
proctype sender() {
atomic {
ch ! 0;
n = n + 1;
}
}
proctype receiver() {
atomic {
ch ? 0;
n = -n;
}
}
init {
atomic {
run sender();
run receiver();
}
_nr_pr == 1;
assert n == 0;
/* Only true if both processes are executed and if sending happened
* before receiving.
*/
}
Yes, the current proctype will block until a message arrives on Ch. This behavior is described in the Promela Manual under the receive statement. [Because you are providing a variable x (as in Ch?x) any message in Ch will cause the statement to be executable. That is, the pattern matching aspect of receive does not apply.]
Why do some people use while(true){} blocks in their code? How does it work?
It's an infinite loop. At each iteration, the condition will be evaluated. Since the condition is true, which is always... true... the loop will run forever. Exiting the loop is done by checking something inside the loop, and then breaking if necessary.
By placing the break check inside the loop, instead of using it as the condition, this can make it more clear that you're expecting this to run until some event occurs.
A common scenario where this is used is in games; you want to keep processing the action and rendering frames until the game is quit.
It's just a loop that never ends on its own, known as an infinite-loop. (Often times, that's a bad thing.)
When it's empty, it serves to halt the program indefinitely*; otherwise there's typically some condition in the loop that, when true, breaks the loop:
while (true)
{
// ...
if (stopLoop)
break;
// ...
}
This is often cleaner than an auxiliary flag:
bool run = true;
while (run)
{
// ...
if (stopLoop)
{
run = false;
continue; // jump to top
}
// ...
}
Also note some will recommend for (;;) instead, for various reasons. (Namely, it might get rid of a warning akin to "conditional expression is always true".)
*In most languages.
Rather than stuff all possible conditions in the while statement,
// Always tests all conditions in loop header:
while( (condition1 && condition2) || condition3 || conditionN_etc ) {
// logic...
if (notable_condition)
continue; // skip remainder, go direct to evaluation portion of loop
// more logic
// maybe more notable conditions use keyword: continue
}
Some programmers might argue it's better to put the conditions throughough the logic, (i.e. not just inside the loop header) and to employ break statements to get out at appropriate places. This approach will usually negate the otherwise original conditions to determine when to leave the loop (i.e. instead of when to keep looping).
// Always tests all conditions in body of loop logic:
while(true) {
//logic...
if (!condition1 || !condition2)
break; // Break out for good.
// more logic...
if (!condition3)
break;
// even more logic ...
}
In real life it's often a more gray mixture, a combination of all these things, instead of a polarized decision to go one way or another.
Usage will depend on the complexity of the logic and the preferences of the programmer .. and maybe on the accepted answer of this thread :)
Also don't forget about do..while. The ultimate solution may use that version of the while construct to twist conditional logic to their liking.
do {
//logic with possible conditional tests and break or continue
} while (true); /* or many conditional tests */
In summary it's just nice to have options as a programmer. So don't forget to thank your compiler authors.
When Edsger W. Dijkstra was young, this was equivalent to:
Do loop initialization
label a:
Do some code
If (Loop is stoppable and End condition is met) goto label b
/* nowadays replaced by some kind of break() */
Do some more code, probably incrementing counters
go to label a
label b:
Be happy and continue
After Dijkstra decided to become Antigotoist, and convinced hordes of programmers to do so, a religious faith came upon earth and the truthiness of code was evident.
So the
Do loop initialization
While (true){
some code
If (Loop is stoppable and End condition is met) break();
Do some more code, probably incrementing counters
}
Be happy and continue
Replaced the abomination.
Not happy with that, fanatics went above and beyond. Once proved that recursion was better, clearer and more general that looping, and that variables are just a diabolic incarnation, Functional Programming, as a dream, came true:
Nest[f[.],x, forever[May God help you break]]
And so, loops recursion became really unstoppable, or at least undemonstratively stoppable.
while (the condition){do the function}
when the condition is true.. it will do the function.
so while(true)
the condition is always true
it will continue looping.
the coding will never proceed.
It's a loop that runs forever, unless there's a break statement somewhere inside the body.
The real point to have while (true) {..} is when semantics of exit conditions have no strong single preference, so its nice way to say to reader, that "well, there are actually break conditions A, B, C .., but calculations of conditions are too lengthy, so they were put into inner blocks independently in order of expected probability of appearance".
This code refers to that inside of it will run indefinitely.
i = 0
while(true)
{
i++;
}
echo i; //this code will never be reached
Unless inside of curly brackets is something like:
if (i > 100) {
break; //this will break the while loop
}
or this is another possibility how to stop while loop:
if (i > 100) {
return i;
}
It is useful to use during some testing. Or during casual coding. Or, like another answer is pointing out, in videogames.
But what I consider as bad practice is using it in production code.
For example, during debugging I want to know immediately what needs to be done in order to stop while. I don't want to search in the function for some hidden break or return.
Or the programmer can easily forget to add it there and data in a database can be affected before the code is stopped by other manners.
So ideal would be something like this:
i = 0
while(i < 100)
{
i++;
}
echo i; //this code will be reached in this scenario