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

replace sba_explicit_* by tgba_digraph, and use tgba_digraph is postproc

This is a huge patch.  tgba_digraph are equiped with some boolean
properties that can be used to indicate whether they represent SBA
(and will carry more informations later).  All algorithms that produce
or use sba_explicit_* automata are changed to use tgba_digraph.
postproc has been rewritten using only tgba_digraph, and this required
changing the return types of many algorithms from tgba* to
tgba_digraph*.

* src/bin/dstar2tgba.cc, src/bin/ltlfilt.cc, src/dstarparse/dra2ba.cc,
src/dstarparse/dstar2tgba.cc, src/dstarparse/nra2nba.cc,
src/dstarparse/nsa2tgba.cc, src/dstarparse/public.hh,
src/tgba/tgbagraph.hh, src/tgba/tgbasafracomplement.cc,
src/tgbaalgos/compsusp.cc, src/tgbaalgos/compsusp.hh,
src/tgbaalgos/degen.cc, src/tgbaalgos/degen.hh,
src/tgbaalgos/dotty.cc, src/tgbaalgos/minimize.cc,
src/tgbaalgos/minimize.hh, src/tgbaalgos/postproc.cc,
src/tgbaalgos/postproc.hh, src/tgbaalgos/sccfilter.cc,
src/tgbaalgos/sccinfo.cc, src/tgbaalgos/stripacc.cc,
src/tgbaalgos/stripacc.hh, src/tgbaalgos/translate.cc,
src/tgbaalgos/translate.hh, src/tgbatest/ltl2tgba.cc,
wrap/python/spot.i: Update.
parent 637aeff2
...@@ -307,8 +307,8 @@ namespace ...@@ -307,8 +307,8 @@ namespace
const xtime_t before = gethrxtime(); const xtime_t before = gethrxtime();
spot::tgba* nba = spot::dstar_to_tgba(daut); auto nba = spot::dstar_to_tgba(daut);
const spot::tgba* aut = post.run(nba, 0); auto aut = post.run(nba, 0);
const xtime_t after = gethrxtime(); const xtime_t after = gethrxtime();
const double prec = XTIME_PRECISION; const double prec = XTIME_PRECISION;
......
...@@ -548,8 +548,8 @@ namespace ...@@ -548,8 +548,8 @@ namespace
// other reasons. // other reasons.
if (matched && obligation) if (matched && obligation)
{ {
spot::tgba* aut = ltl_to_tgba_fm(f, simpl.get_dict()); auto aut = ltl_to_tgba_fm(f, simpl.get_dict());
spot::tgba* min = minimize_obligation(aut, f); auto min = minimize_obligation(aut, f);
assert(min); assert(min);
if (aut == min) if (aut == min)
{ {
......
...@@ -49,7 +49,7 @@ namespace spot ...@@ -49,7 +49,7 @@ namespace spot
// This function is defined in nra2nba.cc, and used only here. // This function is defined in nra2nba.cc, and used only here.
SPOT_LOCAL SPOT_LOCAL
tgba* nra_to_nba(const dstar_aut* nra, const tgba* aut); tgba_digraph* nra_to_nba(const dstar_aut* nra, const tgba* aut);
namespace namespace
{ {
...@@ -320,7 +320,7 @@ namespace spot ...@@ -320,7 +320,7 @@ namespace spot
} }
tgba* dra_to_ba(const dstar_aut* dra, bool* dba) tgba_digraph* dra_to_ba(const dstar_aut* dra, bool* dba)
{ {
assert(dra->type == Rabin); assert(dra->type == Rabin);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
namespace spot namespace spot
{ {
tgba* tgba_digraph*
dstar_to_tgba(const dstar_aut* daut) dstar_to_tgba(const dstar_aut* daut)
{ {
switch (daut->type) switch (daut->type)
......
...@@ -122,7 +122,7 @@ namespace spot ...@@ -122,7 +122,7 @@ namespace spot
// In dra_to_dba() we call this function with a second argument // In dra_to_dba() we call this function with a second argument
// that is a masked version of nra->aut. // that is a masked version of nra->aut.
SPOT_LOCAL SPOT_LOCAL
tgba* nra_to_nba(const dstar_aut* nra, const tgba* aut) tgba_digraph* nra_to_nba(const dstar_aut* nra, const tgba* aut)
{ {
assert(nra->type == Rabin); assert(nra->type == Rabin);
nra_to_nba_worker w(nra, aut); nra_to_nba_worker w(nra, aut);
...@@ -134,7 +134,7 @@ namespace spot ...@@ -134,7 +134,7 @@ namespace spot
} }
SPOT_API SPOT_API
tgba* nra_to_nba(const dstar_aut* nra) tgba_digraph* nra_to_nba(const dstar_aut* nra)
{ {
return nra_to_nba(nra, nra->aut); return nra_to_nba(nra, nra->aut);
} }
......
...@@ -99,7 +99,7 @@ namespace spot ...@@ -99,7 +99,7 @@ namespace spot
} }
SPOT_API SPOT_API
tgba* nsa_to_tgba(const dstar_aut* nsa) tgba_digraph* nsa_to_tgba(const dstar_aut* nsa)
{ {
assert(nsa->type == Streett); assert(nsa->type == Streett);
tgba_digraph* a = nsa->aut; tgba_digraph* a = nsa->aut;
......
...@@ -106,14 +106,14 @@ namespace spot ...@@ -106,14 +106,14 @@ namespace spot
/// \brief Convert a non-deterministic Rabin automaton into a /// \brief Convert a non-deterministic Rabin automaton into a
/// non-deterministic Büchi automaton. /// non-deterministic Büchi automaton.
SPOT_API tgba* SPOT_API tgba_digraph*
nra_to_nba(const dstar_aut* nra); nra_to_nba(const dstar_aut* nra);
/// \brief Convert a non-deterministic Rabin automaton into a /// \brief Convert a non-deterministic Rabin automaton into a
/// non-deterministic Büchi automaton. /// non-deterministic Büchi automaton.
/// ///
/// This version simply ignores all states in \a ignore. /// This version simply ignores all states in \a ignore.
SPOT_API tgba* SPOT_API tgba_digraph*
nra_to_nba(const dstar_aut* nra, const state_set* ignore); nra_to_nba(const dstar_aut* nra, const state_set* ignore);
/// \brief Convert a deterministic Rabin automaton into a /// \brief Convert a deterministic Rabin automaton into a
...@@ -132,18 +132,18 @@ namespace spot ...@@ -132,18 +132,18 @@ namespace spot
/// If the optional \a dba_output argument is non-null, the /// If the optional \a dba_output argument is non-null, the
/// pointed Boolean will be updated to indicate whether the /// pointed Boolean will be updated to indicate whether the
/// returned Büchi automaton is deterministic. /// returned Büchi automaton is deterministic.
SPOT_API tgba* SPOT_API tgba_digraph*
dra_to_ba(const dstar_aut* dra, bool* dba_output = 0); dra_to_ba(const dstar_aut* dra, bool* dba_output = 0);
/// \brief Convert a non-deterministic Streett automaton into a /// \brief Convert a non-deterministic Streett automaton into a
/// non-deterministic tgba. /// non-deterministic tgba.
SPOT_API tgba* SPOT_API tgba_digraph*
nsa_to_tgba(const dstar_aut* nra); nsa_to_tgba(const dstar_aut* nra);
/// \brief Convert a Rabin or Streett automaton into a TGBA. /// \brief Convert a Rabin or Streett automaton into a TGBA.
/// ///
/// This function calls dra_to_ba() or nsa_to_tgba(). /// This function calls dra_to_ba() or nsa_to_tgba().
SPOT_API tgba* SPOT_API tgba_digraph*
dstar_to_tgba(const dstar_aut* dstar); dstar_to_tgba(const dstar_aut* dstar);
......
...@@ -411,6 +411,48 @@ namespace spot ...@@ -411,6 +411,48 @@ namespace spot
} }
g_.defrag(); g_.defrag();
} }
protected:
unsigned bprops_ = 0;
public:
enum bprop {
StateBasedAcc = 1,
SingleAccSet = 2,
SBA = StateBasedAcc | SingleAccSet,
};
bool get_bprop(bprop p) const
{
return (bprops_ & p) == p;
}
void set_bprop(bprop p)
{
bprops_ |= p;
}
void clear_bprop(bprop p)
{
bprops_ &= ~p;
}
bool state_is_accepting(unsigned s) const
{
assert(get_bprop(StateBasedAcc));
for (auto& t: g_.out(s))
// Stop at the first transition, since the remaining should be
// labeled identically.
return t.acc == all_acceptance_conditions_;
return false;
}
bool state_is_accepting(const state* s) const
{
return state_is_accepting(state_number(s));
}
}; };
} }
......
...@@ -34,7 +34,6 @@ ...@@ -34,7 +34,6 @@
#include "ltlast/constant.hh" #include "ltlast/constant.hh"
#include "tgbaalgos/dotty.hh" #include "tgbaalgos/dotty.hh"
#include "tgba/tgbasafracomplement.hh" #include "tgba/tgbasafracomplement.hh"
#include "tgba/sba.hh"
#include "tgbaalgos/degen.hh" #include "tgbaalgos/degen.hh"
namespace spot namespace spot
...@@ -54,7 +53,7 @@ namespace spot ...@@ -54,7 +53,7 @@ namespace spot
/// \brief Automaton with Safra's tree as states. /// \brief Automaton with Safra's tree as states.
struct safra_tree_automaton struct safra_tree_automaton
{ {
safra_tree_automaton(const tgba* sba); safra_tree_automaton(const tgba_digraph* sba);
~safra_tree_automaton(); ~safra_tree_automaton();
typedef std::map<bdd, const safra_tree*, bdd_less_than> transition_list; typedef std::map<bdd, const safra_tree*, bdd_less_than> transition_list;
typedef typedef
...@@ -67,14 +66,14 @@ namespace spot ...@@ -67,14 +66,14 @@ namespace spot
int get_nb_acceptance_pairs() const; int get_nb_acceptance_pairs() const;
safra_tree* get_initial_state() const; safra_tree* get_initial_state() const;
void set_initial_state(safra_tree* s); void set_initial_state(safra_tree* s);
const tgba* get_sba(void) const const tgba_digraph* get_sba(void) const
{ {
return a_; return a_;
} }
private: private:
mutable int max_nb_pairs_; mutable int max_nb_pairs_;
safra_tree* initial_state; safra_tree* initial_state;
const tgba* a_; const tgba_digraph* a_;
}; };
/// \brief A Safra tree, used as state during the determinization /// \brief A Safra tree, used as state during the determinization
...@@ -112,7 +111,7 @@ namespace spot ...@@ -112,7 +111,7 @@ namespace spot
int max_name() const; int max_name() const;
// Operations to get successors of a tree. // Operations to get successors of a tree.
safra_tree* branch_accepting(const sba& a); safra_tree* branch_accepting(const tgba_digraph& a);
safra_tree* succ_create(const bdd& condition, safra_tree* succ_create(const bdd& condition,
cache_t& cache_transition); cache_t& cache_transition);
safra_tree* normalize_siblings(); safra_tree* normalize_siblings();
...@@ -316,7 +315,7 @@ namespace spot ...@@ -316,7 +315,7 @@ namespace spot
/// is inserted with the set of all accepting states of \c nodes /// is inserted with the set of all accepting states of \c nodes
/// as label and an unused name. /// as label and an unused name.
safra_tree* safra_tree*
safra_tree::branch_accepting(const sba& a) safra_tree::branch_accepting(const tgba_digraph& a)
{ {
for (auto c: children) for (auto c: children)
c->branch_accepting(a); c->branch_accepting(a);
...@@ -574,7 +573,8 @@ namespace spot ...@@ -574,7 +573,8 @@ namespace spot
private: private:
typedef std::set<int> atomic_list_t; typedef std::set<int> atomic_list_t;
typedef std::set<bdd, bdd_less_than> conjunction_list_t; typedef std::set<bdd, bdd_less_than> conjunction_list_t;
static void retrieve_atomics(const safra_tree* node, sba* sba_aut, static void retrieve_atomics(const safra_tree* node,
tgba_digraph* sba_aut,
safra_tree::cache_t& cache, safra_tree::cache_t& cache,
atomic_list_t& atomic_list); atomic_list_t& atomic_list);
static void set_atomic_list(atomic_list_t& list, bdd condition); static void set_atomic_list(atomic_list_t& list, bdd condition);
...@@ -587,7 +587,7 @@ namespace spot ...@@ -587,7 +587,7 @@ namespace spot
safra_determinisation::create_safra_automaton(const tgba* a) safra_determinisation::create_safra_automaton(const tgba* a)
{ {
// initialization. // initialization.
sba* sba_aut = degeneralize(a); auto sba_aut = degeneralize(a);
safra_tree_automaton* st = new safra_tree_automaton(sba_aut); safra_tree_automaton* st = new safra_tree_automaton(sba_aut);
...@@ -664,7 +664,7 @@ namespace spot ...@@ -664,7 +664,7 @@ namespace spot
/// of the states in the label of the node. /// of the states in the label of the node.
void void
safra_determinisation::retrieve_atomics(const safra_tree* node, safra_determinisation::retrieve_atomics(const safra_tree* node,
sba* sba_aut, tgba_digraph* sba_aut,
safra_tree::cache_t& cache, safra_tree::cache_t& cache,
atomic_list_t& atomic_list) atomic_list_t& atomic_list)
{ {
...@@ -1031,7 +1031,7 @@ namespace spot ...@@ -1031,7 +1031,7 @@ namespace spot
// safra_tree_automaton // safra_tree_automaton
//////////////////////// ////////////////////////
safra_tree_automaton::safra_tree_automaton(const tgba* a) safra_tree_automaton::safra_tree_automaton(const tgba_digraph* a)
: max_nb_pairs_(-1), initial_state(0), a_(a) : max_nb_pairs_(-1), initial_state(0), a_(a)
{ {
a->get_dict()->register_all_variables_of(a, this); a->get_dict()->register_all_variables_of(a, this);
......
...@@ -349,7 +349,7 @@ namespace spot ...@@ -349,7 +349,7 @@ namespace spot
} }
tgba* tgba_digraph*
compsusp(const ltl::formula* f, bdd_dict* dict, compsusp(const ltl::formula* f, bdd_dict* dict,
bool no_wdba, bool no_simulation, bool no_wdba, bool no_simulation,
bool early_susp, bool no_susp_product, bool wdba_smaller, bool early_susp, bool no_susp_product, bool wdba_smaller,
...@@ -371,18 +371,11 @@ namespace spot ...@@ -371,18 +371,11 @@ namespace spot
if (!no_wdba) if (!no_wdba)
{ {
tgba* min = minimize_obligation(res, g, 0, wdba_smaller); tgba_digraph* min = minimize_obligation(res, g, 0, wdba_smaller);
if (min != res) if (min != res)
{ {
delete res; delete res;
// FIXME: minimize_obligation does not yet return a res = min;
// tgba_digraph, so we convert the result using dupexp.
// Once minimize_obligation is fixed, we should remove the
// call to dupexp.
assert(dynamic_cast<tgba_digraph*>(min) == nullptr);
res = tgba_dupexp_dfs(min);
delete min;
//res = min;
no_simulation = true; no_simulation = true;
} }
} }
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
# define SPOT_TGBAALGOS_COMPSUSP_HH # define SPOT_TGBAALGOS_COMPSUSP_HH
#include "ltlast/formula.hh" #include "ltlast/formula.hh"
#include "tgba/tgbagraph.hh"
namespace spot namespace spot
{ {
...@@ -49,7 +50,7 @@ namespace spot ...@@ -49,7 +50,7 @@ namespace spot
/// This interface is subject to change, and clients aiming for /// This interface is subject to change, and clients aiming for
/// long-term stability should better use the services of the /// long-term stability should better use the services of the
/// spot::translator class instead. /// spot::translator class instead.
SPOT_API tgba* SPOT_API tgba_digraph*
compsusp(const ltl::formula* f, bdd_dict* dict, compsusp(const ltl::formula* f, bdd_dict* dict,
bool no_wdba = false, bool no_simulation = false, bool no_wdba = false, bool no_simulation = false,
bool early_susp = false, bool no_susp_product = false, bool early_susp = false, bool no_susp_product = false,
......
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "degen.hh" #include "degen.hh"
#include "tgba/tgbaexplicit.hh" #include "tgba/tgbagraph.hh"
#include "misc/hash.hh" #include "misc/hash.hh"
#include "misc/hashfunc.hh" #include "misc/hashfunc.hh"
#include "ltlast/constant.hh" #include "ltlast/constant.hh"
...@@ -251,7 +251,7 @@ namespace spot ...@@ -251,7 +251,7 @@ namespace spot
}; };
} }
sba* tgba_digraph*
degeneralize(const tgba* a, bool use_z_lvl, bool use_cust_acc_orders, degeneralize(const tgba* a, bool use_z_lvl, bool use_cust_acc_orders,
int use_lvl_cache, bool skip_levels) int use_lvl_cache, bool skip_levels)
{ {
...@@ -259,8 +259,9 @@ namespace spot ...@@ -259,8 +259,9 @@ namespace spot
bdd_dict* dict = a->get_dict(); bdd_dict* dict = a->get_dict();
// The result (degeneralized) automaton uses numbered states. // The result automaton is an SBA.
sba_explicit_number* res = new sba_explicit_number(dict); auto res = new tgba_digraph(dict);
res->set_bprop(tgba_digraph::SBA);
// We use the same BDD variables as the input, except for the // We use the same BDD variables as the input, except for the
// acceptance. // acceptance.
...@@ -314,7 +315,7 @@ namespace spot ...@@ -314,7 +315,7 @@ namespace spot
// (dest*2+acc) where dest is the destination state number, and // (dest*2+acc) where dest is the destination state number, and
// acc is 1 iff the transition is accepting. The source // acc is 1 iff the transition is accepting. The source
// is always that of the current iteration. // is always that of the current iteration.
typedef std::map<int, state_explicit_number::transition*> tr_cache_t; typedef std::map<int, unsigned> tr_cache_t;
tr_cache_t tr_cache; tr_cache_t tr_cache;
// State level cache // State level cache
...@@ -355,16 +356,7 @@ namespace spot ...@@ -355,16 +356,7 @@ namespace spot
} }
} }
#ifdef DEGEN_DEBUG ds2num[s] = res->new_state();
std::map<const state*, int>names;
names[s.first] = 1;
ds2num[s] =
10000 * names[s.first] + 100 * s.second + m.scc_of_state(s.first);
#else
ds2num[s] = 0;
#endif
todo.push_back(s); todo.push_back(s);
// If use_lvl_cache is on insert initial state to level cache // If use_lvl_cache is on insert initial state to level cache
...@@ -557,11 +549,7 @@ namespace spot ...@@ -557,11 +549,7 @@ namespace spot
} }
else else
{ {
#ifdef DEGEN_DEBUG dest = res->new_state();
dest = 10000 * names[d.first] + 100 * d.second + scc;
#else
dest = ds2num.size();
#endif
ds2num[d] = dest; ds2num[d] = dest;
todo.push_back(d); todo.push_back(d);
// Insert new state to cache // Insert new state to cache
...@@ -582,24 +570,24 @@ namespace spot ...@@ -582,24 +570,24 @@ namespace spot
} }
} }
state_explicit_number::transition*& t = unsigned& t = tr_cache[dest * 2 + is_acc];
tr_cache[dest * 2 + is_acc];
if (t == 0) if (t == 0)
{ {
// Actually create the transition. // Actually create the transition. If the source
t = res->create_transition(src, dest); // state is accepting, we have to put degen_acc on all
t->condition = i->current_condition(); // outgoing transitions. (We are still building a
// If the source state is accepting, we have to put // TGBA; we only assure that it can be used as an
// degen_acc on all outgoing transitions. (We are still // SBA.)
// building a TGBA; we only assure that it can be used as bdd acc = bddfalse;
// an SBA.)
if (is_acc) if (is_acc)
t->acceptance_conditions = degen_acc; acc = degen_acc;
t = res->new_transition(src, dest,
i->current_condition(), acc);
} }
else else
{ {
t->condition |= i->current_condition(); res->trans_data(t).cond |= i->current_condition();
} }
} }
tr_cache.clear(); tr_cache.clear();
......
...@@ -20,13 +20,10 @@ ...@@ -20,13 +20,10 @@
#ifndef SPOT_TGBAALGOS_DEGEN_HH #ifndef SPOT_TGBAALGOS_DEGEN_HH
# define SPOT_TGBAALGOS_DEGEN_HH # define SPOT_TGBAALGOS_DEGEN_HH
# include "misc/common.hh" # include "tgba/tgbagraph.hh"
namespace spot namespace spot
{ {
class sba;
class tgba;
/// \ingroup tgba_misc /// \ingroup tgba_misc
/// \brief Degeneralize a spot::tgba into an equivalent sba with /// \brief Degeneralize a spot::tgba into an equivalent sba with
/// only one acceptance condition. /// only one acceptance condition.
...@@ -52,7 +49,7 @@ namespace spot ...@@ -52,7 +49,7 @@ namespace spot
/// \a a to be computed prior to its actual degeneralization. /// \a a to be computed prior to its actual degeneralization.
/// ///
/// \see tgba_sba_proxy, tgba_tba_proxy /// \see tgba_sba_proxy, tgba_tba_proxy
SPOT_API sba* SPOT_API tgba_digraph*
degeneralize(const tgba* a, bool use_z_lvl = true, degeneralize(const tgba* a, bool use_z_lvl = true,
bool use_cust_acc_orders = false, bool use_cust_acc_orders = false,
int use_lvl_cache = 1, int use_lvl_cache = 1,
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
#include "tgba/bddprint.hh" #include "tgba/bddprint.hh"
#include "reachiter.hh" #include "reachiter.hh"
#include "misc/escape.hh" #include "misc/escape.hh"
#include "tgba/tgbatba.hh" #include "tgba/tgbagraph.hh"
#include "tgba/formula2bdd.hh" #include "tgba/formula2bdd.hh"