* src/tgbaalgos/se05.hh, src/tgbaalgos/tau03.hh: Typo.

* src/tgbaalgos/tau03.cc: Suppress optimisations, the algorithm is now
the original one.
* src/tgbaalgos/tau03opt.hh, src/tgbaalgos/tau03opt.cc: New files
implementing most of all the optimisations of tau03.
* src/tgbaalgos/Makefile.am: Add them.
* src/tgbatest/ltl2tgba.cc, src/tgbatest/randtgba.cc: Make them public.
* src/tgbatest/tba_samples_from_spin.test: Test them.
This commit is contained in:
Denis Poitrenaud 2004-11-18 16:09:41 +00:00
parent 321177331d
commit 121d582480
10 changed files with 635 additions and 77 deletions

View file

@ -19,6 +19,10 @@
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
/// FIXME: Add
/// - the computation of a counter example if detected.
/// - a bit-state hashing version.
//#define TRACE
#ifdef TRACE
@ -39,7 +43,7 @@ namespace spot
{
namespace
{
enum color {WHITE, CYAN, BLUE};
enum color {WHITE, BLUE};
/// \brief Emptiness checker on spot::tgba automata having at most one
/// accepting condition (i.e. a TBA).
@ -77,17 +81,16 @@ namespace spot
/// accepting path.
virtual emptiness_check_result* check()
{
if (!st_red.empty())
if (!st_blue.empty())
{
assert(!st_blue.empty());
return 0;
}
assert(st_blue.empty());
assert(st_red.empty());
nbn = nbt = 0;
sts = mdp = 0;
const state* s0 = a->get_init_state();
++nbn;
h.add_new_state(s0, CYAN);
h.add_new_state(s0, BLUE);
push(st_blue, s0, bddfalse, bddfalse);
if (dfs_blue())
return new emptiness_check_result;
@ -146,9 +149,6 @@ namespace spot
/// by the last dfs visiting it.
heap h;
/// State targeted by the red dfs.
const state* target;
/// The automata to check.
const tgba* a;
@ -175,24 +175,23 @@ namespace spot
<< a->format_state(s_prime) << std::endl;
#endif
f.it->next();
typename heap::color_ref c = h.get_color_ref(s_prime);
if (c.is_white())
typename heap::color_ref c_prime = h.get_color_ref(s_prime);
if (c_prime.is_white())
// Go down the edge (f.s, <label, acc>, s_prime)
{
++nbn;
#ifdef TRACE
std::cout << " It is white, go down" << std::endl;
#endif
h.add_new_state(s_prime, CYAN);
h.add_new_state(s_prime, BLUE);
push(st_blue, s_prime, label, acc);
}
else // Backtrack the edge (f.s, <label, acc>, s_prime)
{
#ifdef TRACE
std::cout << " It is cyan or blue, pop it"
<< std::endl;
std::cout << " It is blue, pop it" << std::endl;
#endif
h.pop_notify(s_prime);
h.pop_notify(s_prime);
}
}
else
@ -217,44 +216,35 @@ namespace spot
assert(!c_prime.is_white());
bdd acu = acc | c.get_acc();
#ifdef TRACE
std::cout << "DFS_BLUE rescanning from: "
<< a->format_state(f.s) << std::endl;
std::cout << " tests "
std::cout << "DFS_BLUE rescanning the arc from "
<< a->format_state(f.s) << " to "
<< a->format_state(s_prime) << std::endl;
std::cout << " if ";
bdd_print_acc(std::cout, a->get_dict(), acu);
std::cout << std::endl;
std::cout << " is not included in ";
bdd_print_acc(std::cout, a->get_dict(), c_prime.get_acc());
std::cout << std::endl;
#endif
if ((c_prime.get_acc() & acu) != acu)
{
#ifdef TRACE
std::cout << " that is true, starts a red dfs with "
std::cout << " ";
bdd_print_acc(std::cout, a->get_dict(), acu);
std::cout << " is not included in ";
bdd_print_acc(std::cout, a->get_dict(),
c_prime.get_acc());
std::cout << std::endl;
std::cout << " Start a red dfs from "
<< a->format_state(s_prime)
<< " propagating: ";
<< " propagating: ";
bdd_print_acc(std::cout, a->get_dict(), acu);
std::cout << std::endl;
#endif
target = f.s;
c_prime.cumulate_acc(acu);
push(st_red, s_prime, label, acc);
if (target->compare(s_prime) == 0 &&
c_prime.get_acc() == all_cond)
{
delete i;
return true;
}
if (dfs_red(acu) || c.get_acc() == all_cond)
{
delete i;
return true;
}
dfs_red(acu);
}
}
delete i;
c.set_color(BLUE);
if (c.get_acc() == all_cond)
{
return true;
}
delete f.it;
--sts;
h.pop_notify(f.s);
@ -264,7 +254,7 @@ namespace spot
return false;
}
bool dfs_red(const bdd& acu)
void dfs_red(const bdd& acu)
{
assert(!st_red.empty());
@ -287,31 +277,33 @@ namespace spot
#endif
f.it->next();
typename heap::color_ref c_prime = h.get_color_ref(s_prime);
if (!c_prime.is_white() &&
(c_prime.get_acc() & acu) != acu)
if (!c_prime.is_white())
{
if ((c_prime.get_acc() & acu) != acu)
{
#ifdef TRACE
std::cout << " It is blue and propagation "
<< "is needed, go down" << std::endl;
#endif
c_prime.cumulate_acc(acu);
push(st_red, s_prime, label, acc);
}
else
{
#ifdef TRACE
std::cout << " It is blue and no propagation "
<< "is needed, pop it" << std::endl;
#endif
h.pop_notify(s_prime);
}
}
else
{
#ifdef TRACE
std::cout << " It is cyan or blue and propagation "
<< "is nedded, go down"
<< std::endl;
std::cout << " It is white, pop it" << std::endl;
#endif
c_prime.cumulate_acc(acu);
push(st_red, s_prime, label, acc);
if (target->compare(s_prime) == 0 &&
c_prime.get_acc() == all_cond)
return true;
delete s_prime;
}
else
{
#ifdef TRACE
std::cout << " It is white or no propagation is needed "
<< ", pop it"
<< std::endl;
#endif
if (c_prime.is_white())
delete s_prime;
h.pop_notify(s_prime);
}
}
else // Backtrack
{
@ -325,7 +317,6 @@ namespace spot
st_red.pop_front();
}
}
return false;
}
};