Commit fb5ff901 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

* src/tgba/bddprint.hh (bdd_format_set): New function.

* src/tgba/bddprint.cc (bdd_format_set): Likewise.
* src/tgba/state.hh: Add Doxygen comments.
(state::compare): Take a state*, not a state&.
(state_ptr_less_than): New functor.
* src/tgba/statebdd.hh (state_bdd::compare): Take a state*, not a
state&.
* src/tgba/statebdd.cc (state_bdd::compare): Likewise.
* src/tgba/succiter.hh: Add Doxygen comments.
* src/tgba/tgba.hh: Mention promises.
(tgba::formate_state): New pure virtual method.
* src/tgba/tgbabddconcrete.hh (tgba_bdd_concrete::formate_state):
New method.
* src/tgba/tgbabddconcrete.cc (tgba_bdd_concrete::formate_state):
Likewise.
* src/tgbaalgos/dotty.cc: Adjust to use state_ptr_less_than
and tgba::formate_state.
parent 3f0e95f0
2003-05-27 Alexandre Duret-Lutz <aduret@src.lip6.fr>
* src/tgba/bddprint.hh (bdd_format_set): New function.
* src/tgba/bddprint.cc (bdd_format_set): Likewise.
* src/tgba/state.hh: Add Doxygen comments.
(state::compare): Take a state*, not a state&.
(state_ptr_less_than): New functor.
* src/tgba/statebdd.hh (state_bdd::compare): Take a state*, not a
state&.
* src/tgba/statebdd.cc (state_bdd::compare): Likewise.
* src/tgba/succiter.hh: Add Doxygen comments.
* src/tgba/tgba.hh: Mention promises.
(tgba::formate_state): New pure virtual method.
* src/tgba/tgbabddconcrete.hh (tgba_bdd_concrete::formate_state):
New method.
* src/tgba/tgbabddconcrete.cc (tgba_bdd_concrete::formate_state):
Likewise.
* src/tgbaalgos/dotty.cc: Adjust to use state_ptr_less_than
and tgba::formate_state.
* src/tgba/succiter.hh (tgba_succ_iterator::current_state):
Return a state*, not a state_bdd.
* src/tgba/succiterconcrete.hh
(tgba_succ_iterator_concrete::current_state): Return a state_bdd*,
not a state_bdd.
* src/tgba/state.hh (state::as_bdd): New abstract method.
* src/tgba/statebdd.hh (state_bdd::as_bdd): Move definitions ...
* src/tgba/statebdd.cc (state_bdd::as_bdd): ... here.
* src/tgba/tgba.hh: Add Doxygen comments.
(tgba::succ_iter, tgba::get_init_state): Use state*, not state_bdd.
* src/tgba/tgbabddconcrete.hh (tgba_bdd_concrete::get_init_state):
......
#include <sstream>
#include "bddprint.hh"
#include "ltlvisit/tostring.hh"
......@@ -9,7 +10,7 @@ namespace spot
static void
print_handler(std::ostream& o, int var)
{
tgba_bdd_dict::vf_map::const_iterator isi =
tgba_bdd_dict::vf_map::const_iterator isi =
dict->var_formula_map.find(var);
if (isi != dict->var_formula_map.end())
to_string(isi->second, o);
......@@ -42,9 +43,9 @@ namespace spot
}
}
}
std::ostream&
std::ostream&
bdd_print_set(std::ostream& os, const tgba_bdd_dict& d, bdd b)
{
dict = &d;
......@@ -54,7 +55,15 @@ namespace spot
return os;
}
std::ostream&
std::string
bdd_format_set(const tgba_bdd_dict& d, bdd b)
{
std::ostringstream os;
bdd_print_set(os, d, b);
return os.str();
}
std::ostream&
bdd_print_dot(std::ostream& os, const tgba_bdd_dict& d, bdd b)
{
dict = &d;
......@@ -63,8 +72,8 @@ namespace spot
bdd_strm_hook(0);
return os;
}
std::ostream&
std::ostream&
bdd_print_table(std::ostream& os, const tgba_bdd_dict& d, bdd b)
{
dict = &d;
......
#ifndef SPOT_TGBA_BDDPRINT_HH
# define SPOT_TGBA_BDDPRINT_HH
#include <string>
#include <iostream>
#include "tgbabdddict.hh"
#include <bdd.h>
namespace spot
{
std::ostream& bdd_print_set(std::ostream& os,
std::ostream& bdd_print_set(std::ostream& os,
const tgba_bdd_dict& dict, bdd b);
std::string bdd_format_set(const tgba_bdd_dict& dict, bdd b);
std::ostream& bdd_print_dot(std::ostream& os,
std::ostream& bdd_print_dot(std::ostream& os,
const tgba_bdd_dict& dict, bdd b);
std::ostream& bdd_print_table(std::ostream& os,
std::ostream& bdd_print_table(std::ostream& os,
const tgba_bdd_dict& dict, bdd b);
}
......
......@@ -5,25 +5,48 @@
namespace spot
{
/// \brief Abstract class for states.
class state
{
public:
// Compares two states (that come from the same automaton).
//
// This method returns an integer less than, equal to, or greater
// than zero if THIS is found, respectively, to be less than, equal
// to, or greater than OTHER according to some implicit total order.
//
// This method should not be called to compare state from
// different automata.
virtual int compare(const state& other) const = 0;
virtual bdd as_bdd() const = 0;
/// \brief Compares two states (that come from the same automaton).
///
/// This method returns an integer less than, equal to, or greater
/// than zero if \a this is found, respectively, to be less than, equal
/// to, or greater than \a other according to some implicit total order.
///
/// This method should not be called to compare states from
/// different automata.
///
/// \sa spot::state_ptr_less_than
virtual int compare(const state* other) const = 0;
virtual ~state()
{
}
};
/// \brief Strict Weak Ordering for \c state*.
///
/// This is meant to be used as a comparison functor for
/// STL \c map whose key are of type \c state*.
///
/// For instance here is how one could declare
/// a map of \c state*.
/// \code
/// // Remember how many times each state has been visited.
/// std::map<spot::state*, int, spot::state_ptr_less_than> seen;
/// \endcode
struct state_ptr_less_than
{
bool
operator()(const state* left, const state *right)
{
return left->compare(right) < 0;
}
};
}
#endif // SPOT_TGBA_STATE_HH
#include "statebdd.hh"
#include "bddprint.hh"
#include <cassert>
namespace spot
{
int
state_bdd::compare(const state& other) const
state_bdd::compare(const state* other) const
{
// This method should not be called to compare states from different
// automata, and all states from the same automaton will use the same
// state class.
const state_bdd* o = dynamic_cast<const state_bdd*>(&other);
const state_bdd* o = dynamic_cast<const state_bdd*>(other);
assert(o);
return o->as_bdd().id() - state_.id();
}
bdd
state_bdd::as_bdd() const
{
return state_;
}
}
......@@ -14,8 +14,13 @@ namespace spot
{
}
virtual bdd as_bdd() const;
virtual int compare(const state& other) const;
bdd
as_bdd() const
{
return state_;
}
virtual int compare(const state* other) const;
protected:
bdd state_;
......
......@@ -6,6 +6,13 @@
namespace spot
{
/// \brief Iterate over the successors of a state.
///
/// This class provides the basic functionalities required to
/// iterate over the successors of a state, as well as querying
/// transition labels. Because transitions are never explicitely
/// encoded, labels (conditions and promises) can only be queried
/// while iterating over the successors.
class tgba_succ_iterator
{
public:
......@@ -14,15 +21,57 @@ namespace spot
{
}
// iteration
/// \name Iteration
//@{
/// \brief Position the iterator on the first successor (if any).
///
/// This method can be called several times to make multiple
/// passes over successors.
///
/// \warning One should always call \c done() to
/// ensure there is a successor, even after \c first(). A
/// common trap is to assume that there is at least one
/// successor: this is wrong.
virtual void first() = 0;
/// \brief Jump to the next successor (if any).
///
/// \warning Again, one should always call \c done() to ensure
/// there is a successor.
virtual void next() = 0;
/// \brief Check whether the iteration is finished.
///
/// This function should be called after any call to \c first()
/// or \c next() and before any enquiry about the current state.
///
/// The usual way to do this is with a \c for loop.
/// \code
/// for (s->first(); !s->done(); s->next())
/// ...
/// \endcode
virtual bool done() = 0;
// inspection
//@}
/// \name Inspection
//@{
/// \brief Get the state of the current successor.
///
/// Note that the same state may occur at different points
/// in the iteration. These actually correspond to the same
/// destination. It just means there were several transitions,
/// with different conditions or promises, leading to the
/// same state.
virtual state* current_state() = 0;
/// \brief Get the condition on the transition leading to this successor.
virtual bdd current_condition() = 0;
/// \brief Get the promise on the transition leading to this successor.
virtual bdd current_promise() = 0;
//@}
};
}
......
......@@ -20,6 +20,12 @@ namespace spot
/// transitions), and a path can be accepted only if it traverse
/// at least one transition of each set infinitely often.
///
/// Actually we do not really encode accepting sets but their
/// complement: promise sets. Formulae such as 'a U b' and
/// 'F b' make the promise to fulfil 'b' enventually. A path can
/// be accepted if for each promise it traverse infinitely often
/// a transition that does not make this promise.
///
/// Browsing such automaton can be achieved using two functions.
/// \c get_init_state, and \c succ_iter. The former returns
/// the initial state while the latter allows to explore the
......@@ -65,7 +71,13 @@ namespace spot
/// may use the same BDD variable for different formula),
/// or simply when printing.
virtual const tgba_bdd_dict& get_dict() const = 0;
};
/// \brief Format the state as a string for printing.
///
/// This formating is the responsability of the automata
/// who owns the state.
virtual std::string format_state(const state* state) const = 0;
};
}
......
#include "tgbabddconcrete.hh"
#include "bddprint.hh"
namespace spot
{
......@@ -45,6 +46,14 @@ namespace spot
return new tgba_succ_iterator_concrete(data_, succ_set);
}
std::string
tgba_bdd_concrete::format_state(const state* state) const
{
const state_bdd* s = dynamic_cast<const state_bdd*>(state);
assert(s);
return bdd_format_set(dict_, s->as_bdd());
}
const tgba_bdd_dict&
tgba_bdd_concrete::get_dict() const
{
......
......@@ -21,6 +21,8 @@ namespace spot
tgba_succ_iterator_concrete* succ_iter(const state* state) const;
std::string format_state(const state* state) const;
const tgba_bdd_dict& get_dict() const;
const tgba_bdd_core_data& get_core_data() const;
......
......@@ -5,14 +5,13 @@
namespace spot
{
typedef std::map<int, int> seen_map;
typedef std::map<state*, int, state_ptr_less_than> seen_map;
static bool
dotty_state(std::ostream& os,
const tgba& g, state* st, seen_map& m, int& node)
{
bdd s = st->as_bdd();
seen_map::iterator i = m.find(s.id());
seen_map::iterator i = m.find(st);
// Already drawn?
if (i != m.end())
......@@ -22,10 +21,10 @@ namespace spot
}
node = m.size() + 1;
m[s.id()] = node;
m[st] = node;
std::cout << " " << node << " [label=\"";
bdd_print_set(os, g.get_dict(), s) << "\"]" << std::endl;
os << " " << node << " [label=\""
<< g.format_state(st) << "\"]" << std::endl;
return true;
}
......@@ -44,8 +43,14 @@ namespace spot
bdd_print_set(os, g.get_dict(), si->current_promise()) << "\"]"
<< std::endl;
if (recurse)
dotty_rec(os, g, s, m, node);
delete s;
{
dotty_rec(os, g, s, m, node);
// Do not delete S, it is used as key in M.
}
else
{
delete s;
}
}
delete si;
}
......@@ -63,7 +68,11 @@ namespace spot
os << " 0 -> " << init << std::endl;
dotty_rec(os, g, state, m, init);
os << "}" << std::endl;
delete state;
// Finally delete all states used as keys in m:
for (seen_map::iterator i = m.begin(); i != m.end(); ++i)
delete i->first;
return os;
}
......
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