Adding support for promela models via SpinS.
* configure.ac, iface/Makefile.am: Adjust. * iface/dve2/finite.test, iface/dve2/.gitignore, iface/dve2/Makefile.am, iface/dve2/README, iface/dve2/beem-peterson.4.dve, iface/dve2/dve2check.test, iface/dve2/defs.in, iface/dve2/finite.dve, iface/ltsmin/finite.test, iface/dve2/kripke.test, iface/dve2/dve2.cc, iface/dve2/dve2.hh, iface/dve2/dve2check.cc: Move to iface/ltsmin. * iface/ltsmin/.gitignore, iface/ltsmin/Makefile.am, iface/ltsmin/README, iface/ltsmin/beem-peterson.4.dve, iface/ltsmin/check.test, iface/ltsmin/defs.in, iface/ltsmin/finite.dve, iface/ltsmin/finite.test, iface/ltsmin/kripke.test, iface/ltsmin/ltsmin.cc, iface/ltsmin/ltsmin.hh, iface/ltsmin/modelcheck.cc: Factorize dve2 and spins interface in iface/ltsmin/ * iface/ltsmin/elevator2.1.pm, iface/ltsmin/finite.pm: Test promela models. * README: Document iface/ltsmin/ directory.
This commit is contained in:
parent
6dd2749c25
commit
dd4b821d93
18 changed files with 396 additions and 232 deletions
2
README
2
README
|
|
@ -180,7 +180,7 @@ wrap/ Wrappers for other languages.
|
|||
tests/ Tests for these bindings
|
||||
ajax/ LTL-to-TGBA translator with web interface, using Ajax.
|
||||
iface/ Interfaces to other libraries.
|
||||
dve2/ Interface with DiVinE2.
|
||||
ltsmin/ Interface with DiVinE2 and SpinS.
|
||||
|
||||
Third party software
|
||||
--------------------
|
||||
|
|
|
|||
|
|
@ -169,8 +169,8 @@ AC_CONFIG_FILES([
|
|||
doc/Makefile
|
||||
doc/tl/Makefile
|
||||
doc/org/init.el
|
||||
iface/dve2/defs
|
||||
iface/dve2/Makefile
|
||||
iface/ltsmin/defs
|
||||
iface/ltsmin/Makefile
|
||||
iface/Makefile
|
||||
lib/Makefile
|
||||
src/bin/Makefile
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@
|
|||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
SUBDIRS = dve2
|
||||
SUBDIRS = ltsmin
|
||||
|
|
|
|||
|
|
@ -1,57 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Copyright (C) 2011, 2013 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
divine compile > output 2>&1
|
||||
|
||||
if grep -i ltsmin output; then
|
||||
:
|
||||
else
|
||||
echo "divine not installed, or no ltsmin interface"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
set -e
|
||||
run 0 ../dve2check -gm $srcdir/finite.dve '"P.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 25
|
||||
test `grep 'P.a=' stdout | wc -l` = 15
|
||||
|
||||
run 0 ../dve2check -dtrue -gm $srcdir/finite.dve '"P.a < 10"' > stdout2
|
||||
cmp stdout stdout2
|
||||
|
||||
run 0 ../dve2check -dfalse -gm $srcdir/finite.dve '"P.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 19
|
||||
test `grep 'P.a=' stdout | wc -l` = 15
|
||||
|
||||
# the same with compressed states
|
||||
run 0 ../dve2check -z -dfalse -gm $srcdir/finite.dve '"P.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 19
|
||||
test `grep 'P.a=' stdout | wc -l` = 15
|
||||
|
||||
run 0 ../dve2check -ddead -E $srcdir/finite.dve \
|
||||
'!(G(dead -> ("P.a==3" | "P.b==3")))'
|
||||
|
||||
run 0 ../dve2check -ddead -e $srcdir/finite.dve \
|
||||
'!(G(dead -> ("P.a==2" | "P.b==3")))'
|
||||
|
||||
# This used to segfault because of a bug in
|
||||
# tgba_product::transition_annotation.
|
||||
run 0 ../dve2check -gp $srcdir/finite.dve true
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
*.dve2C
|
||||
*.dve.cpp
|
||||
dve2check
|
||||
defs
|
||||
*.dir
|
||||
*.spins
|
||||
*.c
|
||||
check
|
||||
|
|
@ -18,26 +18,26 @@
|
|||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/src -I$(top_builddir)/src \
|
||||
$(BUDDY_CPPFLAGS) -I$(top_srcdir)/ltdl
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS)
|
||||
AM_CXXFLAGS = $(WARNING_CXXFLAGS) -lpthread
|
||||
|
||||
dve2dir = $(pkgincludedir)/iface/dve2
|
||||
ltsmindir = $(pkgincludedir)/iface/ltsmin
|
||||
|
||||
dve2_HEADERS = dve2.hh
|
||||
ltsmin_HEADERS = ltsmin.hh
|
||||
|
||||
lib_LTLIBRARIES = libspotdve2.la
|
||||
libspotdve2_la_LIBADD = \
|
||||
lib_LTLIBRARIES = libspotltsmin.la
|
||||
libspotltsmin_la_LIBADD = \
|
||||
$(top_builddir)/src/libspot.la \
|
||||
$(top_builddir)/ltdl/libltdlc.la
|
||||
libspotdve2_la_SOURCES = dve2.cc
|
||||
libspotltsmin_la_SOURCES = ltsmin.cc
|
||||
|
||||
noinst_PROGRAMS = dve2check
|
||||
noinst_PROGRAMS = modelcheck
|
||||
|
||||
dve2check_SOURCES = dve2check.cc
|
||||
dve2check_LDADD = libspotdve2.la
|
||||
modelcheck_SOURCES = modelcheck.cc
|
||||
modelcheck_LDADD = libspotltsmin.la
|
||||
|
||||
check_SCRIPTS = defs
|
||||
|
||||
TESTS = dve2check.test finite.test kripke.test
|
||||
TESTS = check.test finite.test kripke.test
|
||||
EXTRA_DIST = $(TESTS) beem-peterson.4.dve finite.dve
|
||||
|
||||
kripke.test: $(top_builddir)/src/kripketest/parse_print$(EXEEXT)
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
This directory contains an interface that presents DiVinE models as
|
||||
kripke* objects for Spot.
|
||||
This directory contains an interface that presents DiVinE and PROMELA
|
||||
models as kripke* objects for Spot.
|
||||
|
||||
The DiVinE model checker [http://anna.fi.muni.cz/divine/] has a
|
||||
specification language called DVE that makes it easy to model
|
||||
|
|
@ -9,16 +9,12 @@ processes synchonizing through channels
|
|||
A lot of models can be found in the BEEM database at
|
||||
http://anna.fi.muni.cz/models/
|
||||
|
||||
For efficient generation of the state space of the model, DiVinE
|
||||
compiles the DVE input into a dynamic library that contains anything
|
||||
needed to generate the state-space.
|
||||
|
||||
The LTSmin people [http://fmt.cs.utwente.nl/tools/ltsmin/] have made a
|
||||
patched version of DiVinE that compiles a dynamic library with a very
|
||||
simple C interface (no C++) and extra information about state
|
||||
variables (name, type, possible values). We are using this interface,
|
||||
therefore you need to install their version of DiVinE in order to use
|
||||
Spot's DVE interface.
|
||||
The LTSmin people [http://fmt.cs.utwente.nl/tools/ltsmin/] patched
|
||||
DiVinE and SpinJa to compile models as dynamic libraries. This dynamic
|
||||
library provides a very simple C interface (no C++) and extra
|
||||
information about state variables (name, type, possible values). We
|
||||
use this interface so you will need to install their version of these
|
||||
tools to use Spot with DVE or PROMELA models.
|
||||
|
||||
|
||||
|
||||
|
|
@ -47,14 +43,32 @@ model.dve2C (which is a dynamic library).
|
|||
divine compile --ltsmin model.dve
|
||||
|
||||
|
||||
Installation of SpinS
|
||||
======================
|
||||
|
||||
The extended version of SpinJa is called SpinS and should be included
|
||||
with LTSmin.
|
||||
You can download LTSmin from their website:
|
||||
[http://fmt.cs.utwente.nl/tools/ltsmin/] and install it following the
|
||||
INSTALL instructions.
|
||||
|
||||
To compile a promela model, simply run the following command:
|
||||
spins model.pm
|
||||
|
||||
It should create a dynamic library called model.pm.spins in the
|
||||
current directory.
|
||||
|
||||
|
||||
Usage with Spot
|
||||
===============
|
||||
|
||||
The function load_dve2() defined in dve2.hh in this directory
|
||||
will accept "model.dve" or "model.dve2C" as file argument.
|
||||
In the former case, it will call "divine compile --ltsmin"
|
||||
if "model.dve2C" does not exist or is older. Then it will
|
||||
load "model.dve2C" dynamically.
|
||||
The function load_dve2() defined in dve2.hh in this directory will
|
||||
accept either a model or its compiled version as file argument. In
|
||||
the former case, it will call "divine compile --ltsmin model.dve" or
|
||||
"spins model.pm" depending on the file extension, only if a compiled
|
||||
model with the corresponding file extension (.dve2C or .spins) does
|
||||
not exist or is older. Then it will load the compiled model
|
||||
dynamically.
|
||||
|
||||
load_dve2() also requires a set of atomic propositions that should
|
||||
be observed in the model. These are usually the atomic propositions
|
||||
|
|
@ -89,15 +103,15 @@ Usage with Spot
|
|||
"P_0.j >= 2" Process P_0's variable j is greater or equal to 2.
|
||||
P_0.j This is equivalent to "P_0.j != 0".
|
||||
|
||||
Comparisons operators available are "<", ">", ">=", "<=", "==", and
|
||||
"!=". The left operant should always be a variable and the right
|
||||
Comparison operators available are "<", ">", ">=", "<=", "==", and
|
||||
"!=". The left operand should always be a variable and the right
|
||||
operand should always be a number, so you cannot write something
|
||||
like "P_0.j <= P_0.i".
|
||||
|
||||
Because the LTL parser knows nothing about the details of the
|
||||
languages we interface with, every atomic proposition that cannot be
|
||||
express using only alphanumeric characters (plus `_' and `.') should
|
||||
be enclosed in double quote.
|
||||
expressed using only alphanumeric characters (plus `_' and `.')
|
||||
should be enclosed in double quote.
|
||||
|
||||
Caveat: "P_0.j >= 2" and " P_0.j>=2" (watch the spaces!) are
|
||||
considered to be two distinct atomic propositions with the same
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
#!/bin/sh
|
||||
# Copyright (C) 2011, 2012 Laboratoire de Recherche et Développement
|
||||
# Copyright (C) 2011, 2012, 2014 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
|
|
@ -29,32 +29,47 @@ else
|
|||
exit 77
|
||||
fi
|
||||
|
||||
if ! test -x "$(which spins)"; then
|
||||
echo "spins not installed."
|
||||
exit 77
|
||||
fi
|
||||
|
||||
set -e
|
||||
|
||||
# Promela
|
||||
for opt in '' '-z'; do
|
||||
|
||||
run 0 ../modelcheck $opt -E $srcdir/elevator2.1.pm \
|
||||
'!G("req[1]==1" -> (F("p==1" && "cabin_0._pc==2")))'
|
||||
run 0 ../modelcheck $opt -e $srcdir/elevator2.1.pm \
|
||||
'F("p==2")'
|
||||
done
|
||||
|
||||
# dve2
|
||||
for opt in '' '-z'; do
|
||||
# The three examples from the README.
|
||||
# (Don't run the first one using "run 0" because it would take too much
|
||||
# time with valgrind.).
|
||||
|
||||
../dve2check $opt -E $srcdir/beem-peterson.4.dve \
|
||||
../modelcheck $opt -E $srcdir/beem-peterson.4.dve \
|
||||
'!GF(P_0.CS|P_1.CS|P_2.CS|P_3.CS)' \
|
||||
| grep -v pages > stdout1
|
||||
# same formula, different syntax.
|
||||
../dve2check $opt -E $srcdir/beem-peterson.4.dve \
|
||||
../modelcheck $opt -E $srcdir/beem-peterson.4.dve \
|
||||
'!GF("P_0==CS"|"P_1 == CS"|"P_2 ==CS"|"P_3== CS")' \
|
||||
| grep -v pages > stdout2
|
||||
cmp stdout1 stdout2
|
||||
run 0 ../dve2check $opt -e $srcdir/beem-peterson.4.dve \
|
||||
run 0 ../modelcheck $opt -e $srcdir/beem-peterson.4.dve \
|
||||
'!G(P_0.wait -> F P_0.CS)'
|
||||
run 0 ../dve2check $opt -e $srcdir/beem-peterson.4.dve '!G("pos[1] < 3")'
|
||||
run 0 ../modelcheck $opt -e $srcdir/beem-peterson.4.dve '!G("pos[1] < 3")'
|
||||
done
|
||||
|
||||
# Now check some error messages.
|
||||
run 1 ../dve2check foo.dve "F(P_0.CS)" 2>stderr
|
||||
run 1 ../modelcheck foo.dve "F(P_0.CS)" 2>stderr
|
||||
cat stderr
|
||||
grep 'Cannot open' stderr
|
||||
# the dve2C file was generated in the current directory
|
||||
run 1 ../dve2check beem-peterson.4.dve2C \
|
||||
run 1 ../modelcheck beem-peterson.4.dve2C \
|
||||
'Xfoo | P_0.f & X"P_0.k < 2xx" | G"pos[0]"' 2>stderr
|
||||
cat stderr
|
||||
grep 'variable `foo' stderr
|
||||
61
iface/ltsmin/elevator2.1.pm
Normal file
61
iface/ltsmin/elevator2.1.pm
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
byte req[4];
|
||||
int t=0;
|
||||
int p=0;
|
||||
byte v=0;
|
||||
|
||||
|
||||
active proctype cabin() {
|
||||
|
||||
idle: if
|
||||
:: v>0; goto mov;
|
||||
|
||||
fi;
|
||||
mov: if
|
||||
:: t==p; goto open;
|
||||
|
||||
:: d_step {t<p;p = p-1;} goto mov;
|
||||
|
||||
:: d_step {t>p;p = p+1;} goto mov;
|
||||
|
||||
fi;
|
||||
open: if
|
||||
:: d_step {req[p] = 0;v = 0;} goto idle;
|
||||
|
||||
fi;
|
||||
}
|
||||
|
||||
active proctype environment() {
|
||||
|
||||
read: if
|
||||
:: d_step {req[0]==0;req[0] = 1;} goto read;
|
||||
|
||||
:: d_step {req[1]==0;req[1] = 1;} goto read;
|
||||
|
||||
:: d_step {req[2]==0;req[2] = 1;} goto read;
|
||||
|
||||
:: d_step {req[3]==0;req[3] = 1;} goto read;
|
||||
|
||||
fi;
|
||||
}
|
||||
|
||||
active proctype controller() {
|
||||
byte ldir=0;
|
||||
|
||||
wait: if
|
||||
:: d_step {v==0;t = t+(2*ldir)-1;} goto work;
|
||||
|
||||
fi;
|
||||
work: if
|
||||
:: d_step {t<0 || t==4;ldir = 1-ldir;} goto wait;
|
||||
|
||||
:: t>=0 && t<4 && req[t]==1; goto done;
|
||||
|
||||
:: d_step {t>=0 && t<4 && req[t]==0;t = t+(2*ldir)-1;} goto work;
|
||||
|
||||
fi;
|
||||
done: if
|
||||
:: v = 1; goto wait;
|
||||
|
||||
fi;
|
||||
}
|
||||
|
||||
8
iface/ltsmin/finite.pm
Normal file
8
iface/ltsmin/finite.pm
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
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;
|
||||
}
|
||||
90
iface/ltsmin/finite.test
Executable file
90
iface/ltsmin/finite.test
Executable file
|
|
@ -0,0 +1,90 @@
|
|||
#!/bin/sh
|
||||
# Copyright (C) 2011, 2013 Laboratoire de Recherche et Développement
|
||||
# de l'Epita (LRDE).
|
||||
#
|
||||
# This file is part of Spot, a model checking library.
|
||||
#
|
||||
# Spot is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Spot is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
. ./defs
|
||||
|
||||
divine compile > output 2>&1
|
||||
|
||||
if grep -i ltsmin output; then
|
||||
:
|
||||
else
|
||||
echo "divine not installed, or no ltsmin interface"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if ! test -x "$(which spins)"; then
|
||||
echo "spins not installed."
|
||||
exit 77
|
||||
fi
|
||||
|
||||
set -e
|
||||
run 0 ../modelcheck -gm $srcdir/finite.dve '"P.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 25
|
||||
test `grep 'P.a=' stdout | wc -l` = 15
|
||||
|
||||
run 0 ../modelcheck -dtrue -gm $srcdir/finite.dve '"P.a < 10"' > stdout2
|
||||
cmp stdout stdout2
|
||||
|
||||
run 0 ../modelcheck -dfalse -gm $srcdir/finite.dve '"P.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 19
|
||||
test `grep 'P.a=' stdout | wc -l` = 15
|
||||
|
||||
# the same with compressed states
|
||||
run 0 ../modelcheck -z -dfalse -gm $srcdir/finite.dve '"P.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 19
|
||||
test `grep 'P.a=' stdout | wc -l` = 15
|
||||
|
||||
run 0 ../modelcheck -ddead -E $srcdir/finite.dve \
|
||||
'!(G(dead -> ("P.a==3" | "P.b==3")))'
|
||||
|
||||
run 0 ../modelcheck -ddead -e $srcdir/finite.dve \
|
||||
'!(G(dead -> ("P.a==2" | "P.b==3")))'
|
||||
|
||||
# This used to segfault because of a bug in
|
||||
# tgba_product::transition_annotation.
|
||||
run 0 ../modelcheck -gp $srcdir/finite.dve true
|
||||
|
||||
# Same tests with finite.pm.
|
||||
# Compile it beforehand to avoid compiler's output interference.
|
||||
spins $srcdir/finite.pm
|
||||
run 0 ../modelcheck -gm $srcdir/finite.pm.spins '"P_0.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 25
|
||||
test `grep 'P_0.a=' stdout | wc -l` = 15
|
||||
|
||||
run 0 ../modelcheck -dtrue -gm $srcdir/finite.pm.spins '"P_0.a < 10"' > stdout2
|
||||
diff stdout stdout2
|
||||
|
||||
run 0 ../modelcheck -dfalse -gm $srcdir/finite.pm.spins '"P_0.a < 10"' > stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 19
|
||||
test `grep 'P_0.a=' stdout | wc -l` = 15
|
||||
|
||||
# the same with compressed states
|
||||
run 0 ../modelcheck -z -dfalse -gm $srcdir/finite.pm.spins '"P_0.a < 10"' \
|
||||
> stdout
|
||||
test `grep ' -> ' stdout | wc -l` = 19
|
||||
test `grep 'P_0.a=' stdout | wc -l` = 15
|
||||
|
||||
run 0 ../modelcheck -ddead -E $srcdir/finite.pm.spins \
|
||||
'!(G(dead -> ("P_0.a==3" | "P_0.b==3")))'
|
||||
|
||||
run 0 ../modelcheck -ddead -e $srcdir/finite.pm.spins \
|
||||
'!(G(dead -> ("P_0.a==2" | "P_0.b==3")))'
|
||||
|
||||
run 0 ../modelcheck -gp $srcdir/finite.pm.spins true
|
||||
|
|
@ -33,10 +33,10 @@ fi
|
|||
|
||||
set -e
|
||||
|
||||
run 0 ../dve2check -gK ${srcdir}/finite.dve 'F("P.a > 5")' > output
|
||||
run 0 ../modelcheck -gK ${srcdir}/finite.dve 'F("P.a > 5")' > output
|
||||
run 0 ${top_builddir}/src/kripketest/parse_print output | tr -d '"' > output2
|
||||
tr -d '"' < output >outputF
|
||||
cmp outputF output2
|
||||
|
||||
../dve2check -gK $srcdir/beem-peterson.4.dve '!G("pos[1] < 3")' > outputP
|
||||
../modelcheck -gK $srcdir/beem-peterson.4.dve '!G("pos[1] < 3")' > outputP
|
||||
${top_builddir}/src/tgbatest/ltl2tgba -e -KPoutputP '!G("pos[1] < 3")'
|
||||
|
|
@ -30,21 +30,20 @@
|
|||
# define WEXITSTATUS(x) ((x) & 0xff)
|
||||
#endif
|
||||
|
||||
#include "dve2.hh"
|
||||
#include "ltsmin.hh"
|
||||
#include "misc/hashfunc.hh"
|
||||
#include "misc/fixpool.hh"
|
||||
#include "misc/mspool.hh"
|
||||
#include "misc/intvcomp.hh"
|
||||
#include "misc/intvcmp2.hh"
|
||||
|
||||
|
||||
namespace spot
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// DVE2 --ltsmin interface
|
||||
// spins interface
|
||||
|
||||
typedef struct transition_info {
|
||||
int* labels; // edge labels, NULL, or pointer to the edge label(s)
|
||||
|
|
@ -55,29 +54,27 @@ namespace spot
|
|||
transition_info_t *transition_info,
|
||||
int *dst);
|
||||
|
||||
struct dve2_interface
|
||||
struct spins_interface
|
||||
{
|
||||
lt_dlhandle handle; // handle to the dynamic library
|
||||
void (*get_initial_state)(void *to);
|
||||
int (*have_property)();
|
||||
int (*get_successors)(void* m, int *in, TransitionCB, void *arg);
|
||||
|
||||
int (*get_state_variable_count)();
|
||||
int (*get_state_size)();
|
||||
const char* (*get_state_variable_name)(int var);
|
||||
int (*get_state_variable_type)(int var);
|
||||
int (*get_state_variable_type_count)();
|
||||
const char* (*get_state_variable_type_name)(int type);
|
||||
int (*get_state_variable_type_value_count)(int type);
|
||||
const char* (*get_state_variable_type_value)(int type, int value);
|
||||
int (*get_transition_count)();
|
||||
int (*get_type_count)();
|
||||
const char* (*get_type_name)(int type);
|
||||
int (*get_type_value_count)(int type);
|
||||
const char* (*get_type_value_name)(int type, int value);
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// STATE
|
||||
|
||||
struct dve2_state: public state
|
||||
struct spins_state: public state
|
||||
{
|
||||
dve2_state(int s, fixed_size_pool* p)
|
||||
spins_state(int s, fixed_size_pool* p)
|
||||
: pool(p), size(s), count(1)
|
||||
{
|
||||
}
|
||||
|
|
@ -89,10 +86,10 @@ namespace spot
|
|||
hash_value = wang32_hash(hash_value ^ vars[i]);
|
||||
}
|
||||
|
||||
dve2_state* clone() const
|
||||
spins_state* clone() const
|
||||
{
|
||||
++count;
|
||||
return const_cast<dve2_state*>(this);
|
||||
return const_cast<spins_state*>(this);
|
||||
}
|
||||
|
||||
void destroy() const
|
||||
|
|
@ -111,7 +108,7 @@ namespace spot
|
|||
{
|
||||
if (this == other)
|
||||
return 0;
|
||||
const dve2_state* o = down_cast<const dve2_state*>(other);
|
||||
const spins_state* o = down_cast<const spins_state*>(other);
|
||||
assert(o);
|
||||
if (hash_value < o->hash_value)
|
||||
return -1;
|
||||
|
|
@ -122,7 +119,7 @@ namespace spot
|
|||
|
||||
private:
|
||||
|
||||
~dve2_state()
|
||||
~spins_state()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -134,9 +131,9 @@ namespace spot
|
|||
int vars[0];
|
||||
};
|
||||
|
||||
struct dve2_compressed_state: public state
|
||||
struct spins_compressed_state: public state
|
||||
{
|
||||
dve2_compressed_state(int s, multiple_size_pool* p)
|
||||
spins_compressed_state(int s, multiple_size_pool* p)
|
||||
: pool(p), size(s), count(1)
|
||||
{
|
||||
}
|
||||
|
|
@ -148,10 +145,10 @@ namespace spot
|
|||
hash_value = wang32_hash(hash_value ^ vars[i]);
|
||||
}
|
||||
|
||||
dve2_compressed_state* clone() const
|
||||
spins_compressed_state* clone() const
|
||||
{
|
||||
++count;
|
||||
return const_cast<dve2_compressed_state*>(this);
|
||||
return const_cast<spins_compressed_state*>(this);
|
||||
}
|
||||
|
||||
void destroy() const
|
||||
|
|
@ -170,8 +167,8 @@ namespace spot
|
|||
{
|
||||
if (this == other)
|
||||
return 0;
|
||||
const dve2_compressed_state* o =
|
||||
down_cast<const dve2_compressed_state*>(other);
|
||||
const spins_compressed_state* o =
|
||||
down_cast<const spins_compressed_state*>(other);
|
||||
assert(o);
|
||||
if (hash_value < o->hash_value)
|
||||
return -1;
|
||||
|
|
@ -188,7 +185,7 @@ namespace spot
|
|||
|
||||
private:
|
||||
|
||||
~dve2_compressed_state()
|
||||
~spins_compressed_state()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -223,8 +220,8 @@ namespace spot
|
|||
{
|
||||
callback_context* ctx = static_cast<callback_context*>(arg);
|
||||
fixed_size_pool* p = static_cast<fixed_size_pool*>(ctx->pool);
|
||||
dve2_state* out =
|
||||
new(p->allocate()) dve2_state(ctx->state_size, p);
|
||||
spins_state* out =
|
||||
new(p->allocate()) spins_state(ctx->state_size, p);
|
||||
memcpy(out->vars, dst, ctx->state_size * sizeof(int));
|
||||
out->compute_hash();
|
||||
ctx->transitions.push_back(out);
|
||||
|
|
@ -238,9 +235,9 @@ namespace spot
|
|||
size_t csize = ctx->state_size * 2;
|
||||
ctx->compress(dst, ctx->state_size, ctx->compressed, csize);
|
||||
|
||||
void* mem = p->allocate(sizeof(dve2_compressed_state)
|
||||
void* mem = p->allocate(sizeof(spins_compressed_state)
|
||||
+ sizeof(int) * csize);
|
||||
dve2_compressed_state* out = new(mem) dve2_compressed_state(csize, p);
|
||||
spins_compressed_state* out = new(mem) spins_compressed_state(csize, p);
|
||||
memcpy(out->vars, ctx->compressed, csize * sizeof(int));
|
||||
out->compute_hash();
|
||||
ctx->transitions.push_back(out);
|
||||
|
|
@ -249,11 +246,11 @@ namespace spot
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
// SUCC_ITERATOR
|
||||
|
||||
class dve2_succ_iterator: public kripke_succ_iterator
|
||||
class spins_succ_iterator: public kripke_succ_iterator
|
||||
{
|
||||
public:
|
||||
|
||||
dve2_succ_iterator(const callback_context* cc,
|
||||
spins_succ_iterator(const callback_context* cc,
|
||||
bdd cond)
|
||||
: kripke_succ_iterator(cond), cc_(cc)
|
||||
{
|
||||
|
|
@ -266,7 +263,7 @@ namespace spot
|
|||
kripke_succ_iterator::recycle(cond);
|
||||
}
|
||||
|
||||
~dve2_succ_iterator()
|
||||
~spins_succ_iterator()
|
||||
{
|
||||
delete cc_;
|
||||
}
|
||||
|
|
@ -327,14 +324,14 @@ namespace spot
|
|||
|
||||
int
|
||||
convert_aps(const ltl::atomic_prop_set* aps,
|
||||
const dve2_interface* d,
|
||||
const spins_interface* d,
|
||||
bdd_dict_ptr dict,
|
||||
const ltl::formula* dead,
|
||||
prop_set& out)
|
||||
{
|
||||
int errors = 0;
|
||||
|
||||
int state_size = d->get_state_variable_count();
|
||||
int state_size = d->get_state_size();
|
||||
typedef std::map<std::string, var_info> val_map_t;
|
||||
val_map_t val_map;
|
||||
|
||||
|
|
@ -346,14 +343,14 @@ namespace spot
|
|||
val_map[name] = v;
|
||||
}
|
||||
|
||||
int type_count = d->get_state_variable_type_count();
|
||||
int type_count = d->get_type_count();
|
||||
typedef std::map<std::string, int> enum_map_t;
|
||||
std::vector<enum_map_t> enum_map(type_count);
|
||||
for (int i = 0; i < type_count; ++i)
|
||||
{
|
||||
int enum_count = d->get_state_variable_type_value_count(i);
|
||||
int enum_count = d->get_type_value_count(i);
|
||||
for (int j = 0; j < enum_count; ++j)
|
||||
enum_map[i].emplace(d->get_state_variable_type_value(i, j), j);
|
||||
enum_map[i].emplace(d->get_type_value_name(i, j), j);
|
||||
}
|
||||
|
||||
for (ltl::atomic_prop_set::const_iterator ap = aps->begin();
|
||||
|
|
@ -600,15 +597,15 @@ namespace spot
|
|||
////////////////////////////////////////////////////////////////////////
|
||||
// KRIPKE
|
||||
|
||||
class dve2_kripke: public kripke
|
||||
class spins_kripke: public kripke
|
||||
{
|
||||
public:
|
||||
|
||||
dve2_kripke(const dve2_interface* d, const bdd_dict_ptr& dict,
|
||||
spins_kripke(const spins_interface* d, const bdd_dict_ptr& dict,
|
||||
const prop_set* ps, const ltl::formula* dead, int compress)
|
||||
: kripke(dict),
|
||||
d_(d),
|
||||
state_size_(d_->get_state_variable_count()),
|
||||
state_size_(d_->get_state_size()),
|
||||
dict_(dict), ps_(ps),
|
||||
compress_(compress == 0 ? 0
|
||||
: compress == 1 ? int_array_array_compress
|
||||
|
|
@ -618,8 +615,8 @@ namespace spot
|
|||
: int_array_array_decompress2),
|
||||
uncompressed_(compress ? new int[state_size_ + 30] : 0),
|
||||
compressed_(compress ? new int[state_size_ * 2] : 0),
|
||||
statepool_(compress ? sizeof(dve2_compressed_state) :
|
||||
(sizeof(dve2_state) + state_size_ * sizeof(int))),
|
||||
statepool_(compress ? sizeof(spins_compressed_state) :
|
||||
(sizeof(spins_state) + state_size_ * sizeof(int))),
|
||||
state_condition_last_state_(0), state_condition_last_cc_(0)
|
||||
{
|
||||
vname_ = new const char*[state_size_];
|
||||
|
|
@ -632,7 +629,7 @@ namespace spot
|
|||
// output.
|
||||
int type = d->get_state_variable_type(i);
|
||||
format_filter_[i] =
|
||||
(d->get_state_variable_type_value_count(type) != 1);
|
||||
(d->get_type_value_count(type) != 1);
|
||||
}
|
||||
|
||||
// Register the "dead" proposition. There are three cases to
|
||||
|
|
@ -666,7 +663,7 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
~dve2_kripke()
|
||||
~spins_kripke()
|
||||
{
|
||||
if (iter_cache_)
|
||||
{
|
||||
|
|
@ -704,10 +701,10 @@ namespace spot
|
|||
|
||||
multiple_size_pool* p =
|
||||
const_cast<multiple_size_pool*>(&compstatepool_);
|
||||
void* mem = p->allocate(sizeof(dve2_compressed_state)
|
||||
void* mem = p->allocate(sizeof(spins_compressed_state)
|
||||
+ sizeof(int) * csize);
|
||||
dve2_compressed_state* res = new(mem)
|
||||
dve2_compressed_state(csize, p);
|
||||
spins_compressed_state* res = new(mem)
|
||||
spins_compressed_state(csize, p);
|
||||
memcpy(res->vars, compressed_, csize * sizeof(int));
|
||||
res->compute_hash();
|
||||
return res;
|
||||
|
|
@ -715,7 +712,7 @@ namespace spot
|
|||
else
|
||||
{
|
||||
fixed_size_pool* p = const_cast<fixed_size_pool*>(&statepool_);
|
||||
dve2_state* res = new(p->allocate()) dve2_state(state_size_, p);
|
||||
spins_state* res = new(p->allocate()) spins_state(state_size_, p);
|
||||
d_->get_initial_state(res->vars);
|
||||
res->compute_hash();
|
||||
return res;
|
||||
|
|
@ -828,8 +825,8 @@ namespace spot
|
|||
const int* vars;
|
||||
if (compress_)
|
||||
{
|
||||
const dve2_compressed_state* s =
|
||||
down_cast<const dve2_compressed_state*>(st);
|
||||
const spins_compressed_state* s =
|
||||
down_cast<const spins_compressed_state*>(st);
|
||||
assert(s);
|
||||
|
||||
decompress_(s->vars, s->size, uncompressed_, state_size_);
|
||||
|
|
@ -837,7 +834,7 @@ namespace spot
|
|||
}
|
||||
else
|
||||
{
|
||||
const dve2_state* s = down_cast<const dve2_state*>(st);
|
||||
const spins_state* s = down_cast<const spins_state*>(st);
|
||||
assert(s);
|
||||
vars = s->vars;
|
||||
}
|
||||
|
|
@ -846,7 +843,7 @@ namespace spot
|
|||
|
||||
|
||||
virtual
|
||||
dve2_succ_iterator*
|
||||
spins_succ_iterator*
|
||||
succ_iter(const state* st) const
|
||||
{
|
||||
// This may also compute successors in state_condition_last_cc
|
||||
|
|
@ -870,13 +867,13 @@ namespace spot
|
|||
|
||||
if (iter_cache_)
|
||||
{
|
||||
dve2_succ_iterator* it =
|
||||
down_cast<dve2_succ_iterator*>(iter_cache_);
|
||||
spins_succ_iterator* it =
|
||||
down_cast<spins_succ_iterator*>(iter_cache_);
|
||||
it->recycle(cc, scond);
|
||||
iter_cache_ = nullptr;
|
||||
return it;
|
||||
}
|
||||
return new dve2_succ_iterator(cc, scond);
|
||||
return new spins_succ_iterator(cc, scond);
|
||||
}
|
||||
|
||||
virtual
|
||||
|
|
@ -920,7 +917,7 @@ namespace spot
|
|||
}
|
||||
|
||||
private:
|
||||
const dve2_interface* d_;
|
||||
const spins_interface* d_;
|
||||
int state_size_;
|
||||
bdd_dict_ptr dict_;
|
||||
const char** vname_;
|
||||
|
|
@ -952,13 +949,32 @@ namespace spot
|
|||
// LOADER
|
||||
|
||||
|
||||
// Call divine to compile "foo.dve" as "foo.dve2C" if the latter
|
||||
// Call spins to compile "foo.prom" as "foo.prom.spins" if the latter
|
||||
// does not exist already or is older.
|
||||
bool
|
||||
compile_dve2(std::string& filename, bool verbose)
|
||||
compile_model(std::string& filename, std::string& ext, bool verbose)
|
||||
{
|
||||
std::string command;
|
||||
std::string compiled_ext;
|
||||
|
||||
std::string command = "divine compile --ltsmin " + filename;
|
||||
if (ext == ".prom" || ext == ".pm" || ext == ".pml")
|
||||
{
|
||||
command = "spins " + filename;
|
||||
compiled_ext = ".spins";
|
||||
}
|
||||
else if (ext == ".dve")
|
||||
{
|
||||
command = "divine compile --ltsmin " + filename;
|
||||
compiled_ext = "2C";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "Unknown extension `" << ext
|
||||
<< "'. Use `.prom', `.pm', `.pml', `.dve', `.dve2C' or"\
|
||||
"`.prom.spins'." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct stat s;
|
||||
if (stat(filename.c_str(), &s) != 0)
|
||||
|
|
@ -971,7 +987,7 @@ namespace spot
|
|||
}
|
||||
|
||||
std::string old = filename;
|
||||
filename += "2C";
|
||||
filename += compiled_ext;
|
||||
|
||||
// Remove any directory, because the new file will
|
||||
// be compiled in the current directory.
|
||||
|
|
@ -982,7 +998,7 @@ namespace spot
|
|||
struct stat d;
|
||||
if (stat(filename.c_str(), &d) == 0)
|
||||
if (s.st_mtime < d.st_mtime)
|
||||
// The dve2C is up-to-date, no need to recompile it.
|
||||
// The .prom.spins is up-to-date, no need to recompile it.
|
||||
return false;
|
||||
|
||||
int res = system(command.c_str());
|
||||
|
|
@ -997,9 +1013,8 @@ namespace spot
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
kripke_ptr
|
||||
load_dve2(const std::string& file_arg, const bdd_dict_ptr& dict,
|
||||
load_model(const std::string& file_arg, const bdd_dict_ptr& dict,
|
||||
const ltl::atomic_prop_set* to_observe,
|
||||
const ltl::formula* dead,
|
||||
int compress,
|
||||
|
|
@ -1012,22 +1027,15 @@ namespace spot
|
|||
file = "./" + file_arg;
|
||||
|
||||
std::string ext = file.substr(file.find_last_of("."));
|
||||
if (ext == ".dve")
|
||||
if (ext != ".spins" && ext != ".dve2C")
|
||||
{
|
||||
if (compile_dve2(file, verbose))
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "Failed to compile `" << file_arg
|
||||
<< "'." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if (ext != ".dve2C")
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "Unknown extension `" << ext
|
||||
<< "'. Use `.dve' or `.dve2C'." << std::endl;
|
||||
return 0;
|
||||
if (compile_model(file, ext, verbose))
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "Failed to compile `" << file_arg
|
||||
<< "'." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (lt_dlinit())
|
||||
|
|
@ -1046,43 +1054,66 @@ namespace spot
|
|||
return 0;
|
||||
}
|
||||
|
||||
dve2_interface* d = new dve2_interface;
|
||||
spins_interface* d = new spins_interface;
|
||||
d->handle = h;
|
||||
|
||||
d->get_initial_state = (void (*)(void*))
|
||||
lt_dlsym(h, "get_initial_state");
|
||||
d->have_property = (int (*)())
|
||||
lt_dlsym(h, "have_property");
|
||||
d->get_successors = (int (*)(void*, int*, TransitionCB, void*))
|
||||
lt_dlsym(h, "get_successors");
|
||||
d->get_state_variable_count = (int (*)())
|
||||
lt_dlsym(h, "get_state_variable_count");
|
||||
d->get_state_variable_name = (const char* (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_name");
|
||||
d->get_state_variable_type = (int (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_type");
|
||||
d->get_state_variable_type_count = (int (*)())
|
||||
lt_dlsym(h, "get_state_variable_type_count");
|
||||
d->get_state_variable_type_name = (const char* (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_type_name");
|
||||
d->get_state_variable_type_value_count = (int (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_type_value_count");
|
||||
d->get_state_variable_type_value = (const char* (*)(int, int))
|
||||
lt_dlsym(h, "get_state_variable_type_value");
|
||||
d->get_transition_count = (int (*)())
|
||||
lt_dlsym(h, "get_transition_count");
|
||||
// SpinS interface.
|
||||
if ((d->get_initial_state = (void (*)(void*))
|
||||
lt_dlsym(h, "spins_get_initial_state")))
|
||||
{
|
||||
d->have_property = nullptr;
|
||||
d->get_successors = (int (*)(void*, int*, TransitionCB, void*))
|
||||
lt_dlsym(h, "spins_get_successor_all");
|
||||
d->get_state_size = (int (*)())
|
||||
lt_dlsym(h, "spins_get_state_size");
|
||||
d->get_state_variable_name = (const char* (*)(int))
|
||||
lt_dlsym(h, "spins_get_state_variable_name");
|
||||
d->get_state_variable_type = (int (*)(int))
|
||||
lt_dlsym(h, "spins_get_state_variable_type");
|
||||
d->get_type_count = (int (*)())
|
||||
lt_dlsym(h, "spins_get_type_count");
|
||||
d->get_type_name = (const char* (*)(int))
|
||||
lt_dlsym(h, "spins_get_type_name");
|
||||
d->get_type_value_count = (int (*)(int))
|
||||
lt_dlsym(h, "spins_get_type_value_count");
|
||||
d->get_type_value_name = (const char* (*)(int, int))
|
||||
lt_dlsym(h, "spins_get_type_value_name");
|
||||
}
|
||||
// dve2 interface.
|
||||
else
|
||||
{
|
||||
d->get_initial_state = (void (*)(void*))
|
||||
lt_dlsym(h, "get_initial_state");
|
||||
d->have_property = (int (*)())
|
||||
lt_dlsym(h, "have_property");
|
||||
d->get_successors = (int (*)(void*, int*, TransitionCB, void*))
|
||||
lt_dlsym(h, "get_successors");
|
||||
d->get_state_size = (int (*)())
|
||||
lt_dlsym(h, "get_state_variable_count");
|
||||
d->get_state_variable_name = (const char* (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_name");
|
||||
d->get_state_variable_type = (int (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_type");
|
||||
d->get_type_count = (int (*)())
|
||||
lt_dlsym(h, "get_state_variable_type_count");
|
||||
d->get_type_name = (const char* (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_type_name");
|
||||
d->get_type_value_count = (int (*)(int))
|
||||
lt_dlsym(h, "get_state_variable_type_value_count");
|
||||
d->get_type_value_name = (const char* (*)(int, int))
|
||||
lt_dlsym(h, "get_state_variable_type_value");
|
||||
}
|
||||
|
||||
if (!(d->get_initial_state
|
||||
&& d->have_property
|
||||
if (!(
|
||||
d->get_initial_state
|
||||
&& d->get_successors
|
||||
&& d->get_state_variable_count
|
||||
&& d->get_state_size
|
||||
&& d->get_state_variable_name
|
||||
&& d->get_state_variable_type
|
||||
&& d->get_state_variable_type_count
|
||||
&& d->get_state_variable_type_name
|
||||
&& d->get_state_variable_type_value_count
|
||||
&& d->get_state_variable_type_value
|
||||
&& d->get_transition_count))
|
||||
&& d->get_type_count
|
||||
&& d->get_type_name
|
||||
&& d->get_type_value_count
|
||||
&& d->get_type_value_name))
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "Failed to resolve some symbol while loading `"
|
||||
|
|
@ -1092,14 +1123,14 @@ namespace spot
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (d->have_property())
|
||||
if (d->have_property && d->have_property())
|
||||
{
|
||||
if (verbose)
|
||||
std::cerr << "Model with an embedded property are not supported."
|
||||
<< std::endl;
|
||||
delete d;
|
||||
lt_dlexit();
|
||||
return 0;
|
||||
if (verbose)
|
||||
std::cerr << "Model with an embedded property are not supported."
|
||||
<< std::endl;
|
||||
delete d;
|
||||
lt_dlexit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
prop_set* ps = new prop_set;
|
||||
|
|
@ -1113,6 +1144,6 @@ namespace spot
|
|||
return 0;
|
||||
}
|
||||
|
||||
return std::make_shared<dve2_kripke>(d, dict, ps, dead, compress);
|
||||
return std::make_shared<spins_kripke>(d, dict, ps, dead, compress);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,8 +17,8 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef SPOT_IFACE_DVE2_DVE2_HH
|
||||
# define SPOT_IFACE_DVE2_DVE2_HH
|
||||
#ifndef SPOT_IFACE_PROMELA_PROMELA_HH
|
||||
# define SPOT_IFACE_PROMELA_PROMELA_HH
|
||||
|
||||
#include "kripke/kripke.hh"
|
||||
#include "ltlvisit/apcollect.hh"
|
||||
|
|
@ -28,11 +28,11 @@
|
|||
namespace spot
|
||||
{
|
||||
|
||||
// \brief Load a DVE model.
|
||||
// \brief Load a PROMELA model.
|
||||
//
|
||||
// The filename given can be either a *.dve source or a *.dve2C
|
||||
// dynamic library compiled with "divine compile --ltsmin file".
|
||||
// When the *.dve source is supplied, the *.dve2C will be updated
|
||||
// The filename given can be either a *.prom source or a *.spins
|
||||
// dynamic library compiled with "spins file".
|
||||
// When the *.prom source is supplied, the *.spins will be updated
|
||||
// only if it is not newer.
|
||||
//
|
||||
// The dead parameter is used to control the behavior of the model
|
||||
|
|
@ -48,8 +48,7 @@ namespace spot
|
|||
//
|
||||
// This function returns 0 on error.
|
||||
//
|
||||
// \a file the name of the *.dve source file or of the *.dve2C
|
||||
// dynamic library
|
||||
// \a file the name of the *.prom source file or the dynamic library
|
||||
// \a to_observe the list of atomic propositions that should be observed
|
||||
// in the model
|
||||
// \a dict the BDD dictionary to use
|
||||
|
|
@ -57,10 +56,10 @@ namespace spot
|
|||
// dead states
|
||||
// \a verbose whether to output verbose messages
|
||||
SPOT_API kripke_ptr
|
||||
load_dve2(const std::string& file, const bdd_dict_ptr& dict,
|
||||
load_model(const std::string& file, const bdd_dict_ptr& dict,
|
||||
const ltl::atomic_prop_set* to_observe,
|
||||
const ltl::formula* dead = ltl::constant::true_instance(),
|
||||
int compress = 0, bool verbose = true);
|
||||
}
|
||||
|
||||
#endif // SPOT_IFACE_DVE2_DVE2_HH
|
||||
#endif // SPOT_IFACE_PROMELA_PROMELA_HH
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "dve2.hh"
|
||||
#include "ltsmin.hh"
|
||||
#include "tgbaalgos/dotty.hh"
|
||||
#include "ltlenv/defaultenv.hh"
|
||||
#include "ltlast/allnodes.hh"
|
||||
|
|
@ -217,9 +217,10 @@ checked_main(int argc, char **argv)
|
|||
|
||||
if (output != DotFormula)
|
||||
{
|
||||
tm.start("loading dve2");
|
||||
model = spot::load_dve2(argv[1], dict, &ap, deadf, compress_states, true);
|
||||
tm.stop("loading dve2");
|
||||
tm.start("loading spins");
|
||||
model = spot::load_model(argv[1], dict, &ap, deadf,
|
||||
compress_states, true);
|
||||
tm.stop("loading spins");
|
||||
|
||||
if (!model)
|
||||
{
|
||||
Loading…
Add table
Add a link
Reference in a new issue