Store membership to acceptance sets using bitsets, not BDDs.

This is a huge patch, that took over a month to complete.  The bit sets
are currently restricted to what 'unsigned can store', but it should be
easy to extend it to 'uint64_t' should we need it.

* NEWS: Update.
* src/tgba/acc.hh: New file.
* src/tgbatest/acc.cc, src/tgbatest/acc.test: Test it.
* src/tgba/tgbakvcomplement.cc, src/tgba/tgbakvcomplement.hh,
src/tgba/tgbasgba.cc, src/tgba/tgbasgba.hh: Delete.  The KV
complementation is too slow to be used in practice, and I somehow broke
it during the conversion to bitsets.  The tgba->sgba conversion was only
used for the KV complementation, and should be better redone on
tgba_digraph_ptr should it be needed again.
* src/bin/ltlcross.cc, src/dstarparse/dra2ba.cc,
src/dstarparse/nsa2tgba.cc, src/graphtest/tgbagraph.cc,
src/graphtest/tgbagraph.test, src/kripke/fairkripke.cc,
src/kripke/fairkripke.hh, src/kripke/kripke.cc, src/kripke/kripke.hh,
src/kripke/kripkeexplicit.cc, src/kripke/kripkeexplicit.hh,
src/misc/hash.hh, src/neverparse/neverclaimparse.yy, src/priv/accmap.hh,
src/ta/ta.cc, src/ta/ta.hh, src/ta/taexplicit.cc, src/ta/taexplicit.hh,
src/ta/taproduct.cc, src/ta/taproduct.hh, src/ta/tgta.cc,
src/ta/tgta.hh, src/ta/tgtaexplicit.cc, src/ta/tgtaexplicit.hh,
src/ta/tgtaproduct.cc, src/ta/tgtaproduct.hh, src/taalgos/dotty.cc,
src/taalgos/emptinessta.cc, src/taalgos/minimize.cc,
src/taalgos/tgba2ta.cc, src/tgba/Makefile.am, src/tgba/fwd.hh,
src/tgba/taatgba.cc, src/tgba/taatgba.hh, src/tgba/tgba.cc,
src/tgba/tgba.hh, src/tgba/tgbagraph.cc, src/tgba/tgbagraph.hh,
src/tgba/tgbamask.cc, src/tgba/tgbamask.hh, src/tgba/tgbaproduct.cc,
src/tgba/tgbaproduct.hh, src/tgba/tgbaproxy.cc, src/tgba/tgbaproxy.hh,
src/tgba/tgbasafracomplement.cc, src/tgba/tgbasafracomplement.hh,
src/tgbaalgos/bfssteps.cc, src/tgbaalgos/complete.cc,
src/tgbaalgos/compsusp.cc, src/tgbaalgos/degen.cc,
src/tgbaalgos/dotty.cc, src/tgbaalgos/dtbasat.cc,
src/tgbaalgos/dtgbacomp.cc, src/tgbaalgos/dtgbasat.cc,
src/tgbaalgos/dupexp.cc, src/tgbaalgos/emptiness.cc,
src/tgbaalgos/emptiness.hh, src/tgbaalgos/gtec/ce.cc,
src/tgbaalgos/gtec/gtec.cc, src/tgbaalgos/gtec/gtec.hh,
src/tgbaalgos/gtec/sccstack.cc, src/tgbaalgos/gtec/sccstack.hh,
src/tgbaalgos/gv04.cc, src/tgbaalgos/hoaf.cc,
src/tgbaalgos/isweakscc.cc, src/tgbaalgos/lbtt.cc,
src/tgbaalgos/ltl2tgba_fm.cc, src/tgbaalgos/magic.cc,
src/tgbaalgos/ndfs_result.hxx, src/tgbaalgos/neverclaim.cc,
src/tgbaalgos/postproc.cc, src/tgbaalgos/powerset.cc,
src/tgbaalgos/randomgraph.cc, src/tgbaalgos/randomgraph.hh,
src/tgbaalgos/reducerun.cc, src/tgbaalgos/replayrun.cc,
src/tgbaalgos/safety.cc, src/tgbaalgos/save.cc, src/tgbaalgos/scc.cc,
src/tgbaalgos/scc.hh, src/tgbaalgos/sccfilter.cc,
src/tgbaalgos/sccinfo.cc, src/tgbaalgos/sccinfo.hh,
src/tgbaalgos/se05.cc, src/tgbaalgos/simulation.cc,
src/tgbaalgos/simulation.hh, src/tgbaalgos/stats.cc,
src/tgbaalgos/stripacc.cc, src/tgbaalgos/tau03.cc,
src/tgbaalgos/tau03opt.cc, src/tgbaalgos/weight.cc,
src/tgbaalgos/weight.hh, src/tgbaparse/tgbaparse.yy,
src/tgbatest/Makefile.am, src/tgbatest/complementation.cc,
src/tgbatest/complementation.test, src/tgbatest/degenlskip.test,
src/tgbatest/det.test, src/tgbatest/dstar.test, src/tgbatest/emptchk.cc,
src/tgbatest/explpro2.test, src/tgbatest/explpro3.test,
src/tgbatest/explpro4.test, src/tgbatest/explprod.test,
src/tgbatest/ltl2tgba.cc, src/tgbatest/ltl2tgba.test,
src/tgbatest/maskacc.cc, src/tgbatest/maskacc.test,
src/tgbatest/neverclaimread.test, src/tgbatest/randtgba.cc,
src/tgbatest/readsave.test, src/tgbatest/sim.test,
src/tgbatest/sim2.test, src/tgbatest/spotlbtt.test,
src/tgbatest/tgbaread.test, src/tgbatest/tripprod.test,
iface/dve2/dve2.cc: Adjust or use to the new acceptance interface.
This commit is contained in:
Alexandre Duret-Lutz 2014-09-29 18:17:34 +02:00
parent 37ece2b878
commit 2c764fb3c7
125 changed files with 1950 additions and 3254 deletions

View file

@ -67,24 +67,13 @@ namespace spot
/// \brief Initialize the search algorithm on the automaton \a a
tau03_opt_search(const const_tgba_ptr& a, size_t size, option_map o)
: emptiness_check(a, o),
current_weight(a->neg_acceptance_conditions()),
current_weight(a->acc()),
h(size),
all_acc(a->all_acceptance_conditions()),
use_condition_stack(o.get("condstack")),
use_ordering(use_condition_stack && o.get("ordering")),
use_weights(o.get("weights", 1)),
use_red_weights(use_weights && o.get("redweights", 1))
{
if (use_ordering)
{
bdd all_conds = all_acc;
while (all_conds != bddfalse)
{
bdd acc = bdd_satone(all_conds);
cond.push_back(acc);
all_conds -= acc;
}
}
}
virtual ~tau03_opt_search()
@ -116,7 +105,7 @@ namespace spot
const state* s0 = a_->get_init_state();
inc_states();
h.add_new_state(s0, CYAN, current_weight);
push(st_blue, s0, bddfalse, bddfalse);
push(st_blue, s0, bddfalse, 0U);
auto t = std::static_pointer_cast<tau03_opt_search>
(this->emptiness_check::shared_from_this());
if (dfs_blue())
@ -149,7 +138,7 @@ namespace spot
private:
void push(stack_type& st, const state* s,
const bdd& label, const bdd& acc)
const bdd& label, acc_cond::mark_t acc)
{
inc_depth();
tgba_succ_iterator* i = a_->succ_iter(s);
@ -164,14 +153,16 @@ namespace spot
st.pop_front();
}
bdd project_acc(bdd acc) const
acc_cond::mark_t project_acc(acc_cond::mark_t acc) const
{
bdd result = bddfalse;
for (std::vector<bdd>::const_iterator i = cond.begin();
i != cond.end() && (acc & *i) != bddfalse;
++i)
result |= *i;
return result;
if (!use_ordering)
return acc;
// FIXME: This should be improved.
std::vector<unsigned> res;
unsigned max = a_->acc().num_sets();
for (unsigned n = 0; n < max && a_->acc().has(acc, n); ++n)
res.push_back(n);
return a_->acc().marks(res.begin(), res.end());
}
/// \brief weight of the state on top of the blue stack.
@ -187,9 +178,6 @@ namespace spot
/// by the last dfs visiting it.
heap h;
/// The unique acceptance condition of the automaton \a a.
bdd all_acc;
/// Whether to use the "condition stack".
bool use_condition_stack;
/// Whether to use an ordering between the acceptance conditions.
@ -200,9 +188,6 @@ namespace spot
/// Whether to use weights in the red dfs.
bool use_red_weights;
/// Ordering of the acceptance conditions.
std::vector<bdd> cond;
bool dfs_blue()
{
while (!st_blue.empty())
@ -215,7 +200,7 @@ namespace spot
trace << " Visit the successor: "
<< a_->format_state(s_prime) << std::endl;
bdd label = f.it->current_condition();
bdd acc = f.it->current_acceptance_conditions();
auto acc = f.it->current_acceptance_conditions();
// Go down the edge (f.s, <label, acc>, s_prime)
f.it->next();
inc_transitions();
@ -224,7 +209,7 @@ namespace spot
{
trace << " It is white, go down" << std::endl;
if (use_weights)
current_weight += acc;
current_weight.add(a_->acc(), acc);
inc_states();
h.add_new_state(s_prime, CYAN, current_weight);
push(st_blue, s_prime, label, acc);
@ -234,22 +219,21 @@ namespace spot
typename heap::color_ref c = h.get_color_ref(f.s);
assert(!c.is_white());
if (c_prime.get_color() == CYAN
&& all_acc == ((current_weight - c_prime.get_weight())
| c.get_acc()
| acc
| c_prime.get_acc()))
&& a_->acc().accepting
(current_weight.diff(a_->acc(), c_prime. get_weight())
| c.get_acc() | acc | c_prime.get_acc()))
{
trace << " It is cyan and acceptance condition "
<< "is reached, report cycle" << std::endl;
c_prime.cumulate_acc(all_acc);
c_prime.cumulate_acc(a_->acc().all_sets());
push(st_red, s_prime, label, acc);
return true;
}
else
{
trace << " It is cyan or blue and";
bdd acu = acc | c.get_acc();
bdd acp = (use_ordering ? project_acc(acu) : acu);
auto acu = acc | c.get_acc();
auto acp = project_acc(acu);
if ((c_prime.get_acc() & acp) != acp)
{
trace << " a propagation is needed, "
@ -276,7 +260,7 @@ namespace spot
stack_item f_dest(f);
pop(st_blue);
if (use_weights)
current_weight -= f_dest.acc;
current_weight.sub(a_->acc(), f_dest.acc);
typename heap::color_ref c_prime = h.get_color_ref(f_dest.s);
assert(!c_prime.is_white());
c_prime.set_color(BLUE);
@ -285,8 +269,8 @@ namespace spot
typename heap::color_ref c =
h.get_color_ref(st_blue.front().s);
assert(!c.is_white());
bdd acu = f_dest.acc | c.get_acc();
bdd acp = (use_ordering ? project_acc(acu) : acu);
auto acu = f_dest.acc | c.get_acc();
auto acp = project_acc(acu);
if ((c_prime.get_acc() & acp) != acp)
{
trace << " The arc from "
@ -315,15 +299,15 @@ namespace spot
}
bool
dfs_red(bdd acu)
dfs_red(acc_cond::mark_t acu)
{
assert(!st_red.empty());
// These are useful only when USE_CONDITION_STACK is set.
typedef std::pair<bdd, unsigned> cond_level;
typedef std::pair<acc_cond::mark_t, unsigned> cond_level;
std::stack<cond_level> condition_stack;
unsigned depth = 1;
condition_stack.emplace(bddfalse, 0);
condition_stack.emplace(0U, 0);
while (!st_red.empty())
{
@ -335,7 +319,7 @@ namespace spot
trace << " Visit the successor: "
<< a_->format_state(s_prime) << std::endl;
bdd label = f.it->current_condition();
bdd acc = f.it->current_acceptance_conditions();
auto acc = f.it->current_acceptance_conditions();
// Go down the edge (f.s, <label, acc>, s_prime)
f.it->next();
inc_transitions();
@ -347,22 +331,23 @@ namespace spot
continue;
}
else if (c_prime.get_color() == CYAN &&
(all_acc == ((use_red_weights ?
(current_weight - c_prime.get_weight())
: bdd_false())
| c_prime.get_acc()
| acc
| acu)))
a_->acc().accepting
(acc | acu | c_prime.get_acc() |
(use_red_weights ?
current_weight.diff(a_->acc(),
c_prime.
get_weight())
: acc_cond::mark_t(0U))))
{
trace << " It is cyan and acceptance condition "
<< "is reached, report cycle" << std::endl;
c_prime.cumulate_acc(all_acc);
c_prime.cumulate_acc(a_->acc().all_sets());
push(st_red, s_prime, label, acc);
return true;
}
bdd acp;
acc_cond::mark_t acp;
if (use_ordering)
acp = project_acc(c_prime.get_acc() | acu | acc);
acp = project_acc(acu | acc | c_prime.get_acc());
else if (use_condition_stack)
acp = acu | acc;
else
@ -376,7 +361,7 @@ namespace spot
push(st_red, s_prime, label, acc);
if (use_condition_stack)
{
bdd old = acu;
auto old = acu;
acu |= acc;
condition_stack.emplace(acu - old, depth);
}
@ -412,20 +397,22 @@ namespace spot
class explicit_tau03_opt_search_heap
{
typedef std::unordered_map<const state*, std::pair<weight, bdd>,
typedef std::unordered_map<const state*, std::pair<weight,
acc_cond::mark_t>,
state_ptr_hash, state_ptr_equal> hcyan_type;
typedef std::unordered_map<const state*, std::pair<color, bdd>,
typedef std::unordered_map<const state*, std::pair<color,
acc_cond::mark_t>,
state_ptr_hash, state_ptr_equal> hash_type;
public:
class color_ref
{
public:
color_ref(hash_type* h, hcyan_type* hc, const state* s,
const weight* w, bdd* a)
const weight* w, acc_cond::mark_t* a)
: is_cyan(true), w(w), ph(h), phc(hc), ps(s), acc(a)
{
}
color_ref(color* c, bdd* a)
color_ref(color* c, acc_cond::mark_t* a)
: is_cyan(false), pc(c), acc(a)
{
}
@ -459,12 +446,12 @@ namespace spot
*pc=c;
}
}
const bdd& get_acc() const
acc_cond::mark_t get_acc() const
{
assert(!is_white());
return *acc;
}
void cumulate_acc(const bdd& a)
void cumulate_acc(acc_cond::mark_t a)
{
assert(!is_white());
*acc |= a;
@ -480,8 +467,8 @@ namespace spot
hcyan_type* phc; // point to the hash table hcyan
const state* ps; // point to the state in hcyan
color *pc; // point to the color of a state stored in main hash table
bdd* acc; // point to the acc set of a state stored in main hash table
// or hcyan
acc_cond::mark_t* acc; // point to the acc set of a state stored
// in main hash table or hcyan
};
explicit_tau03_opt_search_heap(size_t)
@ -540,7 +527,7 @@ namespace spot
(void)c;
hc.emplace(std::piecewise_construct,
std::forward_as_tuple(s),
std::forward_as_tuple(w, bddfalse));
std::forward_as_tuple(w, 0U));
}
void pop_notify(const state*) const