Now succ_iter() can fetch extra information from
the root of a product to reduce its number of successors. * src/tgba/Makefile.am (libtgba_la_SOURCES): Add tgba.cc. * src/tgba/tgba.hh (tgba::succ_iter): Add the global_state and global_automaton arguments. (tgba::support_conditions, tgba::support_variables, tgba::compute_support_conditions, tgba::compute_support_variables): New functions. (tgba::last_support_conditions_input_, tgba::last_support_conditions_output_, tgba::last_support_variables_input_, tgba::last_support_variables_output_): New attributes. * src/tgba/tgbabddconcrete.cc (tgba_bdd_concrete::succ_iter): Handle the two new arguments. (tgba_bdd_concrete::compute_support_conditions, tgba_bdd_concrete::compute_support_variables): Implement them. * src/tgba/tgbabddconcrete.hh: Adjust. * src/tgba/tgbaexplicit.cc (tgba_explicit::succ_iter): Ignore the two new arguments. (tgba_explicit::compute_support_conditions, tgba_explicit::compute_support_variables): Implement them. * src/tgba/tgbaexplicit.hh: Adjust. * src/tgba/tgbaproduct.cc (tgba_product::succ_iter): Handle the two new arguments. (tgba_product::compute_support_conditions, tgba_product::compute_support_variables): Implement them. * src/tgba/tgbaproduct.hh: Adjust. * iface/gspn/gspn.cc (tgba_gspn_private_::last_state_cond_input, tgba_gspn_private_::last_state_cond_output, (tgba_gspn_private_::tgba_gspn_private_): Set last_state_cond_input. (tgba_gspn_private_::~tgba_gspn_private_): Delete last_state_cond_input. (tgba_gspn_private_::state_conds): New function, eved out from tgba_gspn::succ_iter. (tgba_gspn::succ_iter): Use it. Use the two new arguments. (tgba_gspn::compute_support_conditions, tgba_gspn::compute_support_variables): New functions. * iface/gspn/gspn.hh: Adjust.
This commit is contained in:
parent
4bf6c52bea
commit
1d9c3d6409
13 changed files with 435 additions and 119 deletions
|
|
@ -26,6 +26,7 @@ libtgba_la_SOURCES = \
|
|||
bddprint.cc \
|
||||
statebdd.cc \
|
||||
succiterconcrete.cc \
|
||||
tgba.cc \
|
||||
tgbabddconcrete.cc \
|
||||
tgbabddconcretefactory.cc \
|
||||
tgbabddconcreteproduct.cc \
|
||||
|
|
|
|||
49
src/tgba/tgba.cc
Normal file
49
src/tgba/tgba.cc
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#include "tgba.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
tgba::tgba()
|
||||
: last_support_conditions_input_(0),
|
||||
last_support_variables_input_(0)
|
||||
{
|
||||
}
|
||||
|
||||
tgba::~tgba()
|
||||
{
|
||||
if (last_support_conditions_input_)
|
||||
delete last_support_conditions_input_;
|
||||
if (last_support_variables_input_)
|
||||
delete last_support_variables_input_;
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba::support_conditions(const state* state) const
|
||||
{
|
||||
if (! last_support_conditions_input_
|
||||
|| last_support_conditions_input_->compare(state) != 0)
|
||||
{
|
||||
last_support_conditions_output_ =
|
||||
compute_support_conditions(state);
|
||||
if (last_support_conditions_input_)
|
||||
delete last_support_conditions_input_;
|
||||
last_support_conditions_input_ = state->clone();
|
||||
}
|
||||
return last_support_conditions_output_;
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba::support_variables(const state* state) const
|
||||
{
|
||||
if (! last_support_variables_input_
|
||||
|| last_support_variables_input_->compare(state) != 0)
|
||||
{
|
||||
last_support_variables_output_ =
|
||||
compute_support_variables(state);
|
||||
if (last_support_variables_input_)
|
||||
delete last_support_variables_input_;
|
||||
last_support_variables_input_ = state->clone();
|
||||
}
|
||||
return last_support_variables_output_;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,12 +31,11 @@ namespace spot
|
|||
/// a state.
|
||||
class tgba
|
||||
{
|
||||
public:
|
||||
virtual
|
||||
~tgba()
|
||||
{
|
||||
}
|
||||
protected:
|
||||
tgba();
|
||||
virtual ~tgba();
|
||||
|
||||
public:
|
||||
/// \brief Get the initial state of the automaton.
|
||||
///
|
||||
/// The state has been allocated with \c new. It is the
|
||||
|
|
@ -44,18 +43,63 @@ namespace spot
|
|||
/// longer needed.
|
||||
virtual state* get_init_state() const = 0;
|
||||
|
||||
/// \brief Get an iterator over the successors of \a state.
|
||||
/// \brief Get an iterator over the successors of \a local_state.
|
||||
///
|
||||
/// The iterator has been allocated with \c new. It is the
|
||||
/// responsability of the caller to \c delete it when no
|
||||
/// longer needed.
|
||||
///
|
||||
/// \param state is the state whose successors are to be explored.
|
||||
/// During synchornized products, additional informations are
|
||||
/// passed about the entire product and its state. Recall that
|
||||
/// products can be nested, forming a tree of spot::tgba where
|
||||
/// most values are computed on demand. \a global_automaton
|
||||
/// designate the root spot::tgba, and \a global_state its
|
||||
/// state. This two objects can be used by succ_iter() to
|
||||
/// restrict the set of successors to compute.
|
||||
///
|
||||
/// \param local_state The state whose successors are to be explored.
|
||||
/// This pointer is not adopted in any way by \c succ_iter, and
|
||||
/// it is still the caller's responsability to delete it when
|
||||
/// appropriate (this can be done during the lifetime of
|
||||
/// the iterator).
|
||||
virtual tgba_succ_iterator* succ_iter(const state* state) const = 0;
|
||||
/// \param global_state In a product, the state of the global
|
||||
/// product automaton. Otherwise, 0. Like \a locale_state,
|
||||
/// \a global_state is not adopted by \c succ_iter.
|
||||
/// \param global_automaton In a product, the state of the global
|
||||
/// product automaton. Otherwise, 0.
|
||||
virtual tgba_succ_iterator*
|
||||
succ_iter(const state* local_state,
|
||||
const state* global_state = 0,
|
||||
const tgba* global_automaton = 0) const = 0;
|
||||
|
||||
/// \brief Get a formula that must hold whatever successor is taken.
|
||||
///
|
||||
/// \return A formula which must be verified for all successors
|
||||
/// of \a state.
|
||||
///
|
||||
/// This can be as simple as \c bddtrue, or more completely
|
||||
/// the disjunction of the condition of all successors. This
|
||||
/// is used as an hint by \c succ_iter() to reduce the number
|
||||
/// of successor to compute in a product.
|
||||
///
|
||||
/// Sub classes should implement compute_support_conditions(),
|
||||
/// this function is just a wrapper that will cache the
|
||||
/// last return value for efficiency.
|
||||
bdd support_conditions(const state* state) const;
|
||||
|
||||
/// \brief Get the conjunctions of variables tested by
|
||||
/// the outgoing transitions of \a state.
|
||||
///
|
||||
/// All variables tested by outgoing transitions must be
|
||||
/// returned. This is mandatory.
|
||||
///
|
||||
/// This is used as an hint by some \c succ_iter() to reduce the
|
||||
/// number of successor to compute in a product.
|
||||
///
|
||||
/// Sub classes should implement compute_support_variables(),
|
||||
/// this function is just a wrapper that will cache the
|
||||
/// last return value for efficiency.
|
||||
bdd support_variables(const state* state) const;
|
||||
|
||||
/// \brief Get the dictionary associated to the automaton.
|
||||
///
|
||||
|
|
@ -89,10 +133,21 @@ namespace spot
|
|||
/// <tt>Acc[b]</tt> and <tt>Acc[c]</tt> to describe accepting sets,
|
||||
/// this function should return <tt>!Acc[a]\&!Acc[b]\&!Acc[c]</tt>.
|
||||
///
|
||||
/// This is useful when making products: each operand conditions
|
||||
/// This is useful when making products: each operand's condition
|
||||
/// set should be augmented with the neg_accepting_conditions() of
|
||||
/// the other operand.
|
||||
virtual bdd neg_accepting_conditions() const = 0;
|
||||
|
||||
protected:
|
||||
/// Do the actual computation of tgba::support_conditions().
|
||||
virtual bdd compute_support_conditions(const state* state) const = 0;
|
||||
/// Do the actual computation of tgba::support_variables().
|
||||
virtual bdd compute_support_variables(const state* state) const = 0;
|
||||
private:
|
||||
mutable const state* last_support_conditions_input_;
|
||||
mutable bdd last_support_conditions_output_;
|
||||
mutable const state* last_support_variables_input_;
|
||||
mutable bdd last_support_variables_output_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,14 +71,46 @@ namespace spot
|
|||
}
|
||||
|
||||
tgba_succ_iterator_concrete*
|
||||
tgba_bdd_concrete::succ_iter(const state* state) const
|
||||
tgba_bdd_concrete::succ_iter(const state* state,
|
||||
const state* global_state,
|
||||
const tgba* global_automaton) const
|
||||
{
|
||||
const state_bdd* s = dynamic_cast<const state_bdd*>(state);
|
||||
assert(s);
|
||||
bdd succ_set = data_.relation & s->as_bdd();
|
||||
// If we are in a product, inject the local conditions of
|
||||
// all other automata to limit the number of successors.
|
||||
if (global_automaton)
|
||||
{
|
||||
bdd varused = bdd_support(succ_set);
|
||||
bdd global_conds = global_automaton->support_conditions(global_state);
|
||||
succ_set = bdd_appexcomp(succ_set, global_conds, bddop_and, varused);
|
||||
}
|
||||
return new tgba_succ_iterator_concrete(data_, succ_set);
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba_bdd_concrete::compute_support_conditions(const state* st) const
|
||||
{
|
||||
const state_bdd* s = dynamic_cast<const state_bdd*>(st);
|
||||
assert(s);
|
||||
return bdd_relprod(s->as_bdd(), data_.relation, data_.notvar_set);
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba_bdd_concrete::compute_support_variables(const state* st) const
|
||||
{
|
||||
const state_bdd* s = dynamic_cast<const state_bdd*>(st);
|
||||
assert(s);
|
||||
bdd succ_set = data_.relation & s->as_bdd();
|
||||
// bdd_support must be called BEFORE bdd_exist
|
||||
// because bdd_exist(bdd_support((a&Next[f])|(!a&Next[g])),Next[*])
|
||||
// is obviously not the same as bdd_support(a|!a).
|
||||
// In other words: we can reuse compute_support_conditions() for
|
||||
// this computation.
|
||||
return bdd_exist(bdd_support(succ_set), data_.notvar_set);
|
||||
}
|
||||
|
||||
std::string
|
||||
tgba_bdd_concrete::format_state(const state* state) const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,12 +21,12 @@ namespace spot
|
|||
/// \brief Construct a tgba_bdd_concrete with known initial state.
|
||||
tgba_bdd_concrete(const tgba_bdd_factory& fact, bdd init);
|
||||
|
||||
~tgba_bdd_concrete();
|
||||
virtual ~tgba_bdd_concrete();
|
||||
|
||||
/// \brief Set the initial state.
|
||||
void set_init_state(bdd s);
|
||||
virtual void set_init_state(bdd s);
|
||||
|
||||
state_bdd* get_init_state() const;
|
||||
virtual state_bdd* get_init_state() const;
|
||||
|
||||
/// \brief Get the initial state directly as a BDD.
|
||||
///
|
||||
|
|
@ -39,9 +39,12 @@ namespace spot
|
|||
/// \endcode
|
||||
bdd get_init_bdd() const;
|
||||
|
||||
tgba_succ_iterator_concrete* succ_iter(const state* state) const;
|
||||
virtual tgba_succ_iterator_concrete*
|
||||
succ_iter(const state* local_state,
|
||||
const state* global_state = 0,
|
||||
const tgba* global_automaton = 0) const;
|
||||
|
||||
std::string format_state(const state* state) const;
|
||||
virtual std::string format_state(const state* state) const;
|
||||
|
||||
bdd_dict* get_dict() const;
|
||||
|
||||
|
|
@ -56,6 +59,9 @@ namespace spot
|
|||
virtual bdd neg_accepting_conditions() const;
|
||||
|
||||
protected:
|
||||
virtual bdd compute_support_conditions(const state* state) const;
|
||||
virtual bdd compute_support_variables(const state* state) const;
|
||||
|
||||
tgba_bdd_core_data data_; ///< Core data associated to the automaton.
|
||||
bdd init_; ///< Initial state.
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -206,14 +206,46 @@ namespace spot
|
|||
}
|
||||
|
||||
tgba_succ_iterator*
|
||||
tgba_explicit::succ_iter(const spot::state* state) const
|
||||
tgba_explicit::succ_iter(const spot::state* state,
|
||||
const spot::state* global_state,
|
||||
const tgba* global_automaton) const
|
||||
{
|
||||
const state_explicit* s = dynamic_cast<const state_explicit*>(state);
|
||||
assert(s);
|
||||
(void) global_state;
|
||||
(void) global_automaton;
|
||||
return new tgba_explicit_succ_iterator(s->get_state(),
|
||||
all_accepting_conditions());
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba_explicit::compute_support_conditions(const spot::state* in) const
|
||||
{
|
||||
const state_explicit* s = dynamic_cast<const state_explicit*>(in);
|
||||
assert(s);
|
||||
const state* st = s->get_state();
|
||||
|
||||
bdd res = bddtrue;
|
||||
tgba_explicit::state::const_iterator i;
|
||||
for (i = st->begin(); i != st->end(); ++i)
|
||||
res |= (*i)->condition;
|
||||
return res;
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba_explicit::compute_support_variables(const spot::state* in) const
|
||||
{
|
||||
const state_explicit* s = dynamic_cast<const state_explicit*>(in);
|
||||
assert(s);
|
||||
const state* st = s->get_state();
|
||||
|
||||
bdd res = bddtrue;
|
||||
tgba_explicit::state::const_iterator i;
|
||||
for (i = st->begin(); i != st->end(); ++i)
|
||||
res &= bdd_support((*i)->condition);
|
||||
return res;
|
||||
}
|
||||
|
||||
bdd_dict*
|
||||
tgba_explicit::get_dict() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ namespace spot
|
|||
virtual ~tgba_explicit();
|
||||
virtual spot::state* get_init_state() const;
|
||||
virtual tgba_succ_iterator*
|
||||
succ_iter(const spot::state* state) const;
|
||||
succ_iter(const spot::state* local_state,
|
||||
const spot::state* global_state = 0,
|
||||
const tgba* global_automaton = 0) const;
|
||||
virtual bdd_dict* get_dict() const;
|
||||
virtual std::string format_state(const spot::state* state) const;
|
||||
|
||||
|
|
@ -50,6 +52,9 @@ namespace spot
|
|||
virtual bdd neg_accepting_conditions() const;
|
||||
|
||||
protected:
|
||||
virtual bdd compute_support_conditions(const spot::state* state) const;
|
||||
virtual bdd compute_support_variables(const spot::state* state) const;
|
||||
|
||||
state* add_state(const std::string& name);
|
||||
bdd get_condition(ltl::formula* f);
|
||||
bdd get_accepting_condition(ltl::formula* f);
|
||||
|
|
|
|||
|
|
@ -171,18 +171,53 @@ namespace spot
|
|||
}
|
||||
|
||||
tgba_product_succ_iterator*
|
||||
tgba_product::succ_iter(const state* state) const
|
||||
tgba_product::succ_iter(const state* local_state,
|
||||
const state* global_state,
|
||||
const tgba* global_automaton) const
|
||||
{
|
||||
const state_bdd_product* s = dynamic_cast<const state_bdd_product*>(state);
|
||||
const state_bdd_product* s =
|
||||
dynamic_cast<const state_bdd_product*>(local_state);
|
||||
assert(s);
|
||||
|
||||
tgba_succ_iterator* li = left_->succ_iter(s->left());
|
||||
tgba_succ_iterator* ri = right_->succ_iter(s->right());
|
||||
// If global_automaton is not specified, THIS is the root of a
|
||||
// product tree.
|
||||
if (! global_automaton)
|
||||
{
|
||||
global_automaton = this;
|
||||
global_state = local_state;
|
||||
}
|
||||
|
||||
tgba_succ_iterator* li = left_->succ_iter(s->left(),
|
||||
global_state, global_automaton);
|
||||
tgba_succ_iterator* ri = right_->succ_iter(s->right(),
|
||||
global_state, global_automaton);
|
||||
return new tgba_product_succ_iterator(li, ri,
|
||||
left_->neg_accepting_conditions(),
|
||||
right_->neg_accepting_conditions());
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba_product::compute_support_conditions(const state* in) const
|
||||
{
|
||||
const state_bdd_product* s =
|
||||
dynamic_cast<const state_bdd_product*>(in);
|
||||
assert(s);
|
||||
bdd lsc = left_->support_conditions(s->left());
|
||||
bdd rsc = right_->support_conditions(s->right());
|
||||
return lsc & rsc;
|
||||
}
|
||||
|
||||
bdd
|
||||
tgba_product::compute_support_variables(const state* in) const
|
||||
{
|
||||
const state_bdd_product* s =
|
||||
dynamic_cast<const state_bdd_product*>(in);
|
||||
assert(s);
|
||||
bdd lsc = left_->support_variables(s->left());
|
||||
bdd rsc = right_->support_variables(s->right());
|
||||
return lsc & rsc;
|
||||
}
|
||||
|
||||
bdd_dict*
|
||||
tgba_product::get_dict() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -101,7 +101,9 @@ namespace spot
|
|||
virtual state* get_init_state() const;
|
||||
|
||||
virtual tgba_product_succ_iterator*
|
||||
succ_iter(const state* state) const;
|
||||
succ_iter(const state* local_state,
|
||||
const state* global_state = 0,
|
||||
const tgba* global_automaton = 0) const;
|
||||
|
||||
virtual bdd_dict* get_dict() const;
|
||||
|
||||
|
|
@ -110,6 +112,10 @@ namespace spot
|
|||
virtual bdd all_accepting_conditions() const;
|
||||
virtual bdd neg_accepting_conditions() const;
|
||||
|
||||
protected:
|
||||
virtual bdd compute_support_conditions(const state* state) const;
|
||||
virtual bdd compute_support_variables(const state* state) const;
|
||||
|
||||
private:
|
||||
bdd_dict* dict_;
|
||||
const tgba* left_;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue