From 18b22a5250d4c800057b7bc528965087a69f46c6 Mon Sep 17 00:00:00 2001 From: Alexandre Duret-Lutz Date: Wed, 24 Nov 2004 16:31:21 +0000 Subject: [PATCH] * src/tgbaalgos/bfssteps.hh (bfs_steps_with_path_conditions): New class. * src/tgbaalgos/bfssteps.cc: Remove includes that are now superfluous. --- ChangeLog | 4 ++ src/tgbaalgos/bfssteps.cc | 3 -- src/tgbaalgos/bfssteps.hh | 98 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 102 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index c2869ca09..8c8c32ff0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2004-11-24 Alexandre Duret-Lutz + * src/tgbaalgos/bfssteps.hh (bfs_steps_with_path_conditions): New + class. + * src/tgbaalgos/bfssteps.cc: Remove includes that are now superfluous. + * src/tgbaalgos/gtec/ce.cc (couvreur99_check_result::accepting_run, couvreur99_check_result::accepting_cycle): Rewrite the BFSs using the bfs_steps class. diff --git a/src/tgbaalgos/bfssteps.cc b/src/tgbaalgos/bfssteps.cc index b3fcff70e..83ece5dda 100644 --- a/src/tgbaalgos/bfssteps.cc +++ b/src/tgbaalgos/bfssteps.cc @@ -19,10 +19,7 @@ // Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. -#include -#include #include "bfssteps.hh" -#include "tgba/tgba.hh" namespace spot { diff --git a/src/tgbaalgos/bfssteps.hh b/src/tgbaalgos/bfssteps.hh index 8918248e5..e18917756 100644 --- a/src/tgbaalgos/bfssteps.hh +++ b/src/tgbaalgos/bfssteps.hh @@ -22,10 +22,20 @@ #ifndef SPOT_TGBAALGOS_BFSSTEPS_HH # define SPOT_TGBAALGOS_BFSSTEPS_HH +#include +#include +#include #include "emptiness.hh" +#include "tgba/tgba.hh" namespace spot { + /// \brief Make a BFS in a spot::tgba to compute a tgba_run::steps. + /// \ingroup tgba_misc + /// + /// This class should be used to compute the shortest path + /// between a state of a spot::tgba and the first transition or + /// state that matches some conditions. class bfs_steps { public: @@ -38,6 +48,94 @@ namespace spot const tgba* a_; }; + template + class bfs_steps_with_path_conditions + { + public: + bfs_steps_with_path_conditions(const tgba* a) + : a_(a) + { + } + + virtual + ~bfs_steps_with_path_conditions() + { + } + + virtual const state* filter(const state* s) = 0; + virtual bool match(tgba_run::step& step, const state* dest, + const T& src_cond, T& dest_cond) = 0; + + const state* + search(const state* start, tgba_run::steps& l) + { + // Records backlinks to parent state during the BFS. + // (This also stores the propositions of this link.) + std::map father; + // BFS queue. + std::deque > todo; + // Initial state. + todo.push_back(start); + + while (!todo.empty()) + { + const state* src = todo.front().first; + T cond = todo.front().second; + todo.pop_front(); + tgba_succ_iterator* i = a_->succ_iter(src); + for (i->first(); !i->done(); i->next()) + { + const state* dest = filter(i->current_state()); + + if (!dest) + continue; + + bdd cond = i->current_condition(); + bdd acc = i->current_acceptance_conditions(); + tgba_run::step s = { src, cond, acc }; + + std::pair next; + next.first = src; + + if (match(s, dest, cond, next.second)) + { + // Found it! + + tgba_run::steps p; + for (;;) + { + tgba_run::step tmp = s; + tmp.s = tmp.s->clone(); + p.push_front(tmp); + if (s.s == start) + break; + s = father[s.s]; + } + + l.splice(l.end(), p); + delete i; + return dest; + } + + // Common case: record backlinks and continue BFS + // for unvisited states. + if (father.find(dest) == father.end()) + { + todo.push_back(next); + father[dest] = s; + } + } + delete i; + } + return 0; + + } + + protected: + const tgba* a_; + }; + } #endif // SPOT_TGBAALGOS_BFSSTEPS_HH