Commit 1eb5be54 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

acc: implement min_set() and max_set() using gcc builtins

Fixes #238.

* spot/twa/acc.hh (max_set): Add a version using __builtin_clz().
(min_set): New method.
* tests/core/acc.cc, tests/core/acc.test: Add some tests.
parent 22a3d1c3
...@@ -230,10 +230,13 @@ namespace spot ...@@ -230,10 +230,13 @@ namespace spot
} }
// Return the number of the highest set used plus one. // Return the number of the highest set used plus one.
// So if no set is used, this returns 0, // If no set is used, this returns 0,
// but 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__
return (id == 0) ? 0 : (sizeof(unsigned) * 8 - __builtin_clz(id));
#else
auto i = id; auto i = id;
int res = 0; int res = 0;
while (i) while (i)
...@@ -242,6 +245,28 @@ namespace spot ...@@ -242,6 +245,28 @@ namespace spot
i >>= 1; i >>= 1;
} }
return res; return res;
#endif
}
// Return the number of the lowest set used plus one.
// If no set is used, this returns 0.
// If the sets {1,3,8} are used, this returns 2.
unsigned min_set() const
{
if (id == 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
......
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-x
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement // Copyright (C) 2014, 2015, 2017 Laboratoire de Recherche et
// de l'Epita (LRDE). // Développement de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
...@@ -63,6 +63,10 @@ int main() ...@@ -63,6 +63,10 @@ int main()
auto m2 = spot::acc_cond::mark_t({0, 3}); auto m2 = spot::acc_cond::mark_t({0, 3});
auto m3 = spot::acc_cond::mark_t({2, 1}); auto m3 = spot::acc_cond::mark_t({2, 1});
spot::acc_cond::mark_t m0 = 0U;
std::cout << m0.max_set() << ' ' << m0.min_set() << '\n';
std::cout << m3.max_set() << ' ' << m3.min_set() << '\n';
check(ac, m1); check(ac, m1);
check(ac, m2); check(ac, m2);
check(ac, m3); check(ac, m3);
...@@ -92,6 +96,9 @@ int main() ...@@ -92,6 +96,9 @@ int main()
std::cout << ac.num_sets() << " + " std::cout << ac.num_sets() << " + "
<< ac2.num_sets() << " = " << ac3.num_sets() << '\n'; << ac2.num_sets() << " = " << ac3.num_sets() << '\n';
auto m5 = m2 | (m3 << ac.num_sets()); auto m5 = m2 | (m3 << ac.num_sets());
std::cout << m5.max_set() << ' ' << m5.min_set() << '\n';
check(ac3, m5); check(ac3, m5);
auto m6 = ac.comp(m2 & m3) | (m3 << ac.num_sets()); auto m6 = ac.comp(m2 & m3) | (m3 << ac.num_sets());
check(ac3, m6); check(ac3, m6);
......
#!/bin/sh #!/bin/sh
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement # Copyright (C) 2014, 2015, 2017 Laboratoire de Recherche et
# de l'Epita (LRDE). # Développement de l'Epita (LRDE).
# #
# This file is part of Spot, a model checking library. # This file is part of Spot, a model checking library.
# #
...@@ -25,6 +25,8 @@ set -e ...@@ -25,6 +25,8 @@ set -e
cat >expect <<EOF cat >expect <<EOF
Inf(0)&Inf(1)&Inf(2)&Inf(3) Inf(0)&Inf(1)&Inf(2)&Inf(3)
0 0
3 2
#2: {0,2} #2: {0,2}
#2: {0,3} #2: {0,3}
#2: {1,2} #2: {1,2}
...@@ -41,6 +43,7 @@ Inf(0)&Inf(1)&Inf(2)&Inf(3) ...@@ -41,6 +43,7 @@ Inf(0)&Inf(1)&Inf(2)&Inf(3)
#5: {0,1,2,3,4} accepting #5: {0,1,2,3,4} accepting
#2: {1,2} #2: {1,2}
5 + 5 = 10 5 + 5 = 10
8 1
#4: {0,3,6,7} #4: {0,3,6,7}
#7: {0,1,2,3,4,6,7} #7: {0,1,2,3,4,6,7}
#10: {0,1,2,3,4,5,6,7,8,9} accepting #10: {0,1,2,3,4,5,6,7,8,9} accepting
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment