acc_cond::mark_t now relies on bitset
This allows to represent more than 32 acceptance marks. * configure.ac: add an option to specify the number of marks * spot/twa/acc.hh: implement it * tests/python/acc_cond.ipynb, tests/core/acc.cc, tests/core/ltlcross3.test: update tests * NEWS: document it * bin/randltl.cc: fix an include
This commit is contained in:
parent
d77d046d26
commit
d7ee23ed2f
7 changed files with 51 additions and 172 deletions
5
NEWS
5
NEWS
|
|
@ -17,6 +17,11 @@ New in spot 2.5.3.dev (not yet released)
|
||||||
|
|
||||||
Library:
|
Library:
|
||||||
|
|
||||||
|
- You can now specify to Spot the number of acceptance marks you
|
||||||
|
wish to use. This is a compile-time option, accessible through
|
||||||
|
option --with-nb-acc of the configure script. The default is
|
||||||
|
still 32, but this limit is no longer hardcoded.
|
||||||
|
|
||||||
- Option "a" of print_dot(), for printing the acceptance condition,
|
- Option "a" of print_dot(), for printing the acceptance condition,
|
||||||
is now enabled by default. Option "A", introduced in Spot 2.4,
|
is now enabled by default. Option "A", introduced in Spot 2.4,
|
||||||
can be used to hide the acceptance condition in case you do not
|
can be used to hide the acceptance condition in case you do not
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@
|
||||||
#include "common_cout.hh"
|
#include "common_cout.hh"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <spot/tl/defaultenv.hh>
|
||||||
#include <spot/tl/randomltl.hh>
|
#include <spot/tl/randomltl.hh>
|
||||||
#include <spot/tl/simplify.hh>
|
#include <spot/tl/simplify.hh>
|
||||||
#include <spot/misc/random.hh>
|
#include <spot/misc/random.hh>
|
||||||
|
|
|
||||||
13
configure.ac
13
configure.ac
|
|
@ -59,6 +59,19 @@ AC_ARG_ENABLE([doxygen],
|
||||||
[enable_doxygen=yes], [enable_doxygen=no])
|
[enable_doxygen=yes], [enable_doxygen=no])
|
||||||
AM_CONDITIONAL([ENABLE_DOXYGEN], [test "x${enable_doxygen:-no}" = xyes])
|
AM_CONDITIONAL([ENABLE_DOXYGEN], [test "x${enable_doxygen:-no}" = xyes])
|
||||||
|
|
||||||
|
# Option to indicate the maximal number of acceptance marks
|
||||||
|
AC_COMPUTE_INT([default_nb_acc], [8*sizeof(unsigned)])
|
||||||
|
AC_ARG_ENABLE([nb-acc],
|
||||||
|
[AC_HELP_STRING([--enable-nb-acc=N],
|
||||||
|
[Use up to N acceptance marks])],
|
||||||
|
[enable_nb_acc=$enableval], [enable_nb_acc=$default_nb_acc])
|
||||||
|
if (( $enable_nb_acc % $default_nb_acc == 0 ))
|
||||||
|
then
|
||||||
|
AC_DEFINE_UNQUOTED([NB_ACC], [$enable_nb_acc], [The number of acceptance marks])
|
||||||
|
else
|
||||||
|
AC_ERROR([The argument of --enable-nb-acc must be a multiple of $default_nb_acc])
|
||||||
|
fi
|
||||||
|
|
||||||
# Activate C11 for gnulib tests
|
# Activate C11 for gnulib tests
|
||||||
AX_CHECK_COMPILE_FLAG([-std=c11], [CFLAGS="$CFLAGS -std=c11"])
|
AX_CHECK_COMPILE_FLAG([-std=c11], [CFLAGS="$CFLAGS -std=c11"])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,13 +20,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <unordered_map>
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <spot/tl/defaultenv.hh>
|
|
||||||
#include <spot/misc/trival.hh>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <spot/misc/_config.h>
|
||||||
|
#include <spot/misc/bitset.hh>
|
||||||
|
#include <spot/misc/trival.hh>
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
namespace internal
|
namespace internal
|
||||||
|
|
@ -39,19 +40,22 @@ namespace spot
|
||||||
public:
|
public:
|
||||||
struct mark_t
|
struct mark_t
|
||||||
{
|
{
|
||||||
typedef unsigned value_t;
|
// configure guarantees that SPOT_NB_ACC % (8*sizeof(unsigned)) == 0
|
||||||
|
typedef bitset<SPOT_NB_ACC / (8*sizeof(unsigned))> value_t;
|
||||||
value_t id;
|
value_t id;
|
||||||
|
|
||||||
mark_t() = default;
|
private:
|
||||||
|
|
||||||
mark_t(value_t id) noexcept
|
mark_t(value_t id) noexcept
|
||||||
: id(id)
|
: id(id)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
mark_t() = default;
|
||||||
|
|
||||||
template<class iterator>
|
template<class iterator>
|
||||||
mark_t(const iterator& begin, const iterator& end) noexcept
|
mark_t(const iterator& begin, const iterator& end) noexcept
|
||||||
: mark_t(0U)
|
: mark_t(value_t::zero())
|
||||||
{
|
{
|
||||||
for (iterator i = begin; i != end; ++i)
|
for (iterator i = begin; i != end; ++i)
|
||||||
set(*i);
|
set(*i);
|
||||||
|
|
@ -123,12 +127,12 @@ namespace spot
|
||||||
|
|
||||||
void set(unsigned u)
|
void set(unsigned u)
|
||||||
{
|
{
|
||||||
id |= (1U << u);
|
id |= (value_t::one() << u);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear(unsigned u)
|
void clear(unsigned u)
|
||||||
{
|
{
|
||||||
id &= ~(1U << u);
|
id &= ~(value_t::one() << u);
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_t& operator&=(mark_t r)
|
mark_t& operator&=(mark_t r)
|
||||||
|
|
@ -238,18 +242,7 @@ namespace spot
|
||||||
// Number of bits sets.
|
// Number of bits sets.
|
||||||
unsigned count() const
|
unsigned count() const
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
return id.count();
|
||||||
return __builtin_popcount(id);
|
|
||||||
#else
|
|
||||||
unsigned c = 0U;
|
|
||||||
auto v = id;
|
|
||||||
while (v)
|
|
||||||
{
|
|
||||||
++c;
|
|
||||||
v &= v - 1;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of the highest set used plus one.
|
// Return the number of the highest set used plus one.
|
||||||
|
|
@ -257,18 +250,10 @@ namespace spot
|
||||||
// If the sets {1,3,8} are used, this returns 9.
|
// If the sets {1,3,8} are used, this returns 9.
|
||||||
unsigned max_set() const
|
unsigned max_set() const
|
||||||
{
|
{
|
||||||
#ifdef __GNUC__
|
if (id)
|
||||||
return (id == 0) ? 0 : (sizeof(unsigned) * 8 - __builtin_clz(id));
|
return id.highest()+1;
|
||||||
#else
|
else
|
||||||
auto i = id;
|
return 0;
|
||||||
int res = 0;
|
|
||||||
while (i)
|
|
||||||
{
|
|
||||||
++res;
|
|
||||||
i >>= 1;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the number of the lowest set used plus one.
|
// Return the number of the lowest set used plus one.
|
||||||
|
|
@ -276,20 +261,10 @@ namespace spot
|
||||||
// If the sets {1,3,8} are used, this returns 2.
|
// If the sets {1,3,8} are used, this returns 2.
|
||||||
unsigned min_set() const
|
unsigned min_set() const
|
||||||
{
|
{
|
||||||
if (id == 0)
|
if (id)
|
||||||
|
return id.lowest()+1;
|
||||||
|
else
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef __GNUC__
|
|
||||||
return __builtin_ctz(id) + 1;
|
|
||||||
#else
|
|
||||||
auto i = id;
|
|
||||||
int res = 1;
|
|
||||||
while ((i & 1) == 0)
|
|
||||||
{
|
|
||||||
++res;
|
|
||||||
i >>= 1;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the lowest acceptance mark
|
// Return the lowest acceptance mark
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
#include <spot/twa/acc.hh>
|
#include <spot/twa/acc.hh>
|
||||||
|
|
||||||
static void check(spot::acc_cond& ac, spot::acc_cond::mark_t m)
|
static void check(spot::acc_cond& ac, spot::acc_cond::mark_t m)
|
||||||
|
|
@ -178,4 +179,14 @@ int main()
|
||||||
std::cout << c1 << '\n';
|
std::cout << c1 << '\n';
|
||||||
std::cout << c2 << '\n';
|
std::cout << c2 << '\n';
|
||||||
assert(c1 == c2);
|
assert(c1 == c2);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
spot::acc_cond a{SPOT_NB_ACC+1};
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& e)
|
||||||
|
{
|
||||||
|
return std::strcmp(e.what(), "Too many acceptance sets used.");
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -318,63 +318,3 @@ ltlcross --color --products=0 ltl2tgba -f GFa -f FGa --csv=out.csv
|
||||||
grep product out.csv && exit 1
|
grep product out.csv && exit 1
|
||||||
check_csv out.csv
|
check_csv out.csv
|
||||||
|
|
||||||
#
|
|
||||||
cat >fake <<\EOF
|
|
||||||
case $1 in
|
|
||||||
"foo")
|
|
||||||
cat <<\END
|
|
||||||
HOA: v1
|
|
||||||
name: "foo"
|
|
||||||
States: 1
|
|
||||||
Start: 0
|
|
||||||
AP: 5 "p0" "p1" "p2" "p3" "p4"
|
|
||||||
acc-name: parity min odd 32
|
|
||||||
Acceptance: 32 Fin(0) & (Inf(1) | (Fin(2) & (Inf(3) | (Fin(4) &
|
|
||||||
(Inf(5) | (Fin(6) & (Inf(7) | (Fin(8) & (Inf(9) | (Fin(10) & (Inf(11)
|
|
||||||
| (Fin(12) & (Inf(13) | (Fin(14) & (Inf(15) | (Fin(16) & (Inf(17) |
|
|
||||||
(Fin(18) & (Inf(19) | (Fin(20) & (Inf(21) | (Fin(22) & (Inf(23) |
|
|
||||||
(Fin(24) & (Inf(25) | (Fin(26) & (Inf(27) | (Fin(28) & (Inf(29) |
|
|
||||||
(Fin(30) & Inf(31)))))))))))))))))))))))))))))))
|
|
||||||
--BODY--
|
|
||||||
State: 0
|
|
||||||
0 { 0} 0 { 1} 0 { 2} 0 { 3} 0 { 4} 0 { 5} 0 { 6} 0 { 7} 0 { 8} 0 { 9}
|
|
||||||
0 {10} 0 {11} 0 {12} 0 {13} 0 {14} 0 {15} 0 {16} 0 {17} 0 {18} 0 {19}
|
|
||||||
0 {20} 0 {21} 0 {22} 0 {23} 0 {24} 0 {25} 0 {26} 0 {27} 0 {28} 0 {29}
|
|
||||||
0 {30} 0 {31}
|
|
||||||
--END--
|
|
||||||
END
|
|
||||||
;;
|
|
||||||
"!(foo)")
|
|
||||||
cat <<\END
|
|
||||||
HOA: v1
|
|
||||||
name: "foo"
|
|
||||||
States: 1
|
|
||||||
Start: 0
|
|
||||||
AP: 5 "p0" "p1" "p2" "p3" "p4"
|
|
||||||
acc-name: parity min even 32
|
|
||||||
Acceptance: 32 Inf(0) | (Fin(1) & (Inf(2) | (Fin(3) & (Inf(4) |
|
|
||||||
(Fin(5) & (Inf(6) | (Fin(7) & (Inf(8) | (Fin(9) & (Inf(10) | (Fin(11)
|
|
||||||
& (Inf(12) | (Fin(13) & (Inf(14) | (Fin(15) & (Inf(16) | (Fin(17) &
|
|
||||||
(Inf(18) | (Fin(19) & (Inf(20) | (Fin(21) & (Inf(22) | (Fin(23) &
|
|
||||||
(Inf(24) | (Fin(25) & (Inf(26) | (Fin(27) & (Inf(28) | (Fin(29) &
|
|
||||||
(Inf(30) | Fin(31)))))))))))))))))))))))))))))))
|
|
||||||
--BODY--
|
|
||||||
State: 0
|
|
||||||
0 { 0} 0 { 1} 0 { 2} 0 { 3} 0 { 4} 0 { 5} 0 { 6} 0 { 7} 0 { 8} 0 { 9}
|
|
||||||
0 {10} 0 {11} 0 {12} 0 {13} 0 {14} 0 {15} 0 {16} 0 {17} 0 {18} 0 {19}
|
|
||||||
0 {20} 0 {21} 0 {22} 0 {23} 0 {24} 0 {25} 0 {26} 0 {27} 0 {28} 0 {29}
|
|
||||||
0 {30} 0 {31}
|
|
||||||
--END--
|
|
||||||
END
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
EOF
|
|
||||||
|
|
||||||
chmod +x fake
|
|
||||||
ltlcross './fake %f >%O' -f foo --verbose --csv=out.csv 2>stderr
|
|
||||||
cat stderr
|
|
||||||
test 2 = `grep -c 'info:.*-> failed (Too many .* used.)' stderr`
|
|
||||||
check_csv out.csv
|
|
||||||
ltlcross --color=never './fake %f >%O' -f foo --csv=out.csv 2>stderr
|
|
||||||
cat stderr
|
|
||||||
test 2 = `grep -c 'info: preproc.* failed (Too many .* used.)' stderr`
|
|
||||||
|
|
|
||||||
|
|
@ -245,72 +245,6 @@
|
||||||
"x << 2"
|
"x << 2"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"Internally, the `mark_t` stores the bit-vector as an integer. This implies that we currently do not support more than 32 acceptance sets. The underlying integer can be retrieved using `.id`. Note that this implementation may evolve in the future, so relying on it is not recommended."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 10,
|
|
||||||
"metadata": {
|
|
||||||
"collapsed": false
|
|
||||||
},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"{0,2,5}\n",
|
|
||||||
"37\n",
|
|
||||||
"0b100101\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"print(x)\n",
|
|
||||||
"print(x.id)\n",
|
|
||||||
"print(bin(x.id))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"`mark_t` can also be initialized using an integer: in that case the integer is interpreted as a bit vector.\n",
|
|
||||||
"\n",
|
|
||||||
"A frequent error is to use `mark_t(n)` when we really mean `mark_t([n])` or `mark_t((n,))`.\n",
|
|
||||||
"\n",
|
|
||||||
"As the underlying implementation of `mark_t` may change in the future, it is not recommended to rely on this interface."
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 11,
|
|
||||||
"metadata": {
|
|
||||||
"collapsed": false
|
|
||||||
},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"name": "stdout",
|
|
||||||
"output_type": "stream",
|
|
||||||
"text": [
|
|
||||||
"{5}\n",
|
|
||||||
"{0,2}\n",
|
|
||||||
"{0,2,4}\n"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"# compare\n",
|
|
||||||
"print(spot.mark_t([5]))\n",
|
|
||||||
"# with\n",
|
|
||||||
"print(spot.mark_t(5))\n",
|
|
||||||
"print(spot.mark_t(0b10101))"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"cell_type": "markdown",
|
"cell_type": "markdown",
|
||||||
"metadata": {},
|
"metadata": {},
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue