byte x ; active proctype P1() { do /* repeat forever */ :: x = x+1 ; printf("Hello (%u)!\n", x) ; :: break ; od ; assert x<3 ; printf("\nBye!\n") ; }
[spoiler]
Note that when you run a program, you only produce one execution. This does NOT verify all possible executions.
[spoiler]
chan link = [2] of {byte} ; proctype sender(chan c) { byte x = 0 ; do /* repeat forever */ :: printf("Sending %u\n", x) ; c!x ; x = (x+1)%4 ; od ; } proctype receiver(chan c) { byte r ; byte trash ; bool corrupt = false ; do /* repeat forever */ :: c?r -> corrupt = false ; printf("Receiving %u\n", r) ; :: c?trash -> corrupt = true ; printf("CORRUPTED\n") ; (false) ; od ; } init { run sender(link) ; run receiver(link) ; }
[spoiler]
You can write your ltl formula in your model-file. Check the topic ltl in Promela Language Reference.
When you run pan to check an LTL formula, you need to turn on the -a option. If you need to impose process-level fairness, add -f option. Check the manual of pan's runtime options. If you have multiple ltl formulas, -N option allows to to select.
You would need a way to refer to a local variable from your LTL formula. Check the topic remote reference (remoterefs) in Promela Language Reference.
[spoiler]
(Challenging) What if we want to express a more general property: "if x is the value sent by the sender, this value will eventually be received". Note that now you want to quantify over the values of x. Unfortunately, SPIN does not allow quantifications to be expressed in LTL formulas. Can you find a way to get around this?
Questions:#define N 4 #define FREE N #define TRUE 1 #define FALSE 0 #define NEXT(i) (i+1)%N byte fork[N] ; bool eating[N] ; proctype Philosopher(byte i) { do :: atomic { ((fork[i]==FREE) && (fork[NEXT(i)]==FREE)) ; fork[i] = i ; fork[NEXT(i)] = i } /* prove that here we do indeed have the forks: */ assert (fork[i]==i) && (fork[NEXT(i)]==i) ; eating[i] = TRUE ; eating[i] = FALSE ; fork[i] = FREE ; fork[NEXT(i)] = FREE od } init { byte k = 0 ; /* initially, all forks are free */ do :: k<N -> fork[k] = FREE ; k++ :: k==N -> break od k = 0 ; /* create the philosophers and run them: */ atomic { do :: k<N -> run Philosopher(k) ; k++ :: k==N -> break od } }