import spot
import spot.ltsmin
# The following line causes the notebook to exit with 77 if spins is not
# installed, therefore skipping this test in the test suite.
spot.ltsmin.require('spins')
spot.setup()
There are two ways to load a Promela model: from a file or from a cell.
Using the %%pml
magic will save the model in a temporary file, call spins
to compile it, load the resulting shared library, and store the result into an object whose name is passed as an argument to %%pml
.
%%pml model
active proctype P() {
int a = 0;
int b = 0;
x: if
:: d_step {a < 3 && b < 3; a = a + 1; } goto x;
:: d_step {a < 3 && b < 3; b = b + 1; } goto x;
fi;
}
Yes, the spins
compiler is quite verbose. Printing the resulting model
object will show information about the variables in that model.
model
To instantiate a Kripke structure, one should provide a list of atomic proposition to observe.
k = model.kripke(['P_0.a < 2', 'P_0.b > 1']); k
And then from this Kripke structure you can do some model checking using the same functions as illustrated in ltsmin-dve.ipynb
.
For displaying Kripke structures more compactly, it can be useful to use option 1
to move all state labels in tooltips (mouse over the state to see them):
k.show('.1')
Another option is to use option K
to disable to state-labeling (that is enabled by default for Kripke structure) and use transition-labeling instead. Combining with 1
, this will preserve the state's data as a tooltip.
k.show('.1K')
Since a kripke structure is a twa
, can be used on the right-hand side of contains
. Here we show that every path of k
contains a step where P_0.a < 2
.
spot.contains('F"P_0.a < 2"', k)
*.pml
file¶Another option is to use ltsmin.load()
to load a Promela file directly. In order for this test-case to be self-contained, we are going to write the Promela file first, but in practice you probably already have your model.
!rm -rf test1.pml
%%file test1.pml
active proctype P() {
int a = 0;
int b = 0;
x: if
:: d_step {a < 3 && b < 3; a = a + 1; } goto x;
:: d_step {a < 3 && b < 3; b = b + 1; } goto x;
fi;
}
Now load it:
model2 = spot.ltsmin.load('test1.pml')
model2
!rm -f test1.pml test1.pml.spins.c test1.pml.spins