I have many LTL formulae that I am trying to test on the same .pml file. My issue is that when an error is found in any single ltl formula, the trail file is written (or overwrites) to the same trail file name. I have not been able to find a way to write to an trail file name of my choice. Does anyone know if this option exists?
If not, what is a strategy I could use for testing multiple ltl formulae from the same .pml file simultaneously without overwriting the same trail file every time?
I am aware of the SPIN runtime -x option, but that just prevents a trail file from being overwritten. It does not generate trail files with different names.
AFAIK, there is no such option.
WORKAROUND
For linux+bash, you can opt for the following, brutal, approach.
Define set_trail_name
function:
~$ function set_trail_name() { sed -i "s/^\\(char \\*TrailFile =\\)\\(.*\\)$/\\1 \"${1}\";/" "${2}"; }
~$ export -f set_trail_name
It takes two parameters: your preferred trail_file_nime
and the location of pan.c
.
Then use it as follows:
~$ spin -a test.pml
ltl p1: [] (<> (! (q0)))
ltl p2: [] (<> (q1))
the model contains 2 never claims: p2, p1
...
~$ set_trail_name my_p1_name pan.c
~$ gcc -o pan pan.c
~$ ./pan -a -N p1
pan: ltl formula p1
pan:1: acceptance cycle (at depth 4)
pan: wrote my_p1_name.trail
...
~$ ls *.trail
my_p1_name.trail
~$ set_trail_name my_p2_name pan.c
~$ gcc -o pan pan.c
~$ pan -a -N p2
pan: ltl formula p2
pan:1: acceptance cycle (at depth 2)
pan: wrote my_p2_name.trail
...
~$ ls *.trail
my_p1_name.trail my_p2_name.trail
WORKAROUND IMPROVEMENT #1
You can go one step further, e.g.
#!/bin/bash
function set_trail_name() {
sed -i "s/^\\(char \\*TrailFile =\\)\\(.*\\)$/\\1 \"${1}\";/" "${2}";
}
function check_property() {
set -e
spin -a "${1}" 1>/dev/null
set_trail_name "${2}" pan.c
gcc -o pan pan.c
./pan -a -N "${2}"
set +e
}
check_property "${@}"
Which makes it easier to run it:
~$ ./run_spin.sh test.pml p1
pan: ltl formula p1
pan:1: acceptance cycle (at depth 4)
pan: wrote p1.trail
...
~$ ~$ ./run_spin.sh test.pml p2
pan: ltl formula p2
pan:1: acceptance cycle (at depth 2)
pan: wrote p2.trail
WORKAROUND IMPROVEMENT #2
You can even go a couple of steps further, e.g.
#!/bin/bash
function set_trail_name()
{
sed -i "s/^\\(char \\*TrailFile =\\)\\(.*\\)$/\\1 \"${1}\";/" "${2}";
}
function check_property()
{
echo -e "\\n>>> Testing property ${1} ...\\n"
set_trail_name "${1}" pan.c
gcc -o pan pan.c
./pan -a -N "${1}"
}
function check_properties()
{
set -e
spin -a "${1}" 1>/dev/null
mapfile -t properties < <(gawk 'match($0, /^ltl ([^{]+) .*$/, a) { print a[1] }' "${1}")
for prop in "${properties[@]}"
do
check_property "${prop}"
done
set +e
}
check_properties "${@}"
Which makes it trivial to run it:
~$ ./run_spin.sh test.pml
>>> Testing property p1 ...
pan: ltl formula p1
pan:1: acceptance cycle (at depth 4)
pan: wrote p1.trail
...
>>> Testing property p2 ...
pan: ltl formula p2
pan:1: acceptance cycle (at depth 2)
pan: wrote p2.trail
...
NOTES
You might want to enrich the scripts with
pan, pan.*, _spin_nvr.tmp
Another completely legitimate solution could be to simply rename existing trail files after each call to the Spin model checker.