tgba_digraph: add a set_single_acceptance_set() method.

* src/tgba/tgbagraph.cc: New file.
* src/tgba/Makefile.am: Adjust.
* src/tgba/tgbagraph.hh (set_single_acceptance_set,
new_acc_transition): New methods.
(set_acceptance_conditions, merge_transitions): Move body
to tgbagraph.cc.
* src/tgbaalgos/complete.cc, src/tgbaalgos/degen.cc,
src/tgbaalgos/dtbasat.cc, src/tgbaalgos/dtgbacomp.cc,
src/neverparse/neverclaimparse.yy, src/dstarparse/dra2ba.cc,
src/dstarparse/nra2nba.cc: Simplify using these new methods.
This commit is contained in:
Alexandre Duret-Lutz 2014-08-13 11:37:39 +02:00
parent 5739240c0f
commit 917f70073f
10 changed files with 144 additions and 145 deletions

View file

@ -53,6 +53,7 @@ libtgba_la_SOURCES = \
futurecondcol.cc \
taatgba.cc \
tgba.cc \
tgbagraph.cc \
tgbakvcomplement.cc \
tgbaproduct.cc \
tgbamask.cc \

102
src/tgba/tgbagraph.cc Normal file
View file

@ -0,0 +1,102 @@
// -*- coding: utf-8 -*-
// Copyright (C) 2014 Laboratoire de Recherche et Développement de
// l'Epita.
//
// This file is part of Spot, a model checking library.
//
// Spot is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// Spot is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
// License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "tgbagraph.hh"
#include "ltlast/constant.hh"
namespace spot
{
void tgba_digraph::set_acceptance_conditions(bdd all)
{
if (all_acceptance_conditions_ != bddfalse)
dict_->unregister_all_typed_variables(bdd_dict::acc, this);
bdd sup = bdd_support(all);
dict_->register_acceptance_variables(sup, this);
neg_acceptance_conditions_ = bddtrue;
while (sup != bddtrue)
{
neg_acceptance_conditions_ &= bdd_nithvar(bdd_var(sup));
sup = bdd_high(sup);
}
all_acceptance_conditions_ =
compute_all_acceptance_conditions(neg_acceptance_conditions_);
if (number_of_acceptance_conditions() == 1)
set_bprop(tgba_digraph::SingleAccSet);
else
clear_bprop(tgba_digraph::SingleAccSet);
}
bdd tgba_digraph::set_single_acceptance_set()
{
if (all_acceptance_conditions_ != bddfalse)
dict_->unregister_all_typed_variables(bdd_dict::acc, this);
set_bprop(tgba_digraph::SingleAccSet);
int accvar =
dict_->register_acceptance_variable(ltl::constant::true_instance(),
this);
bdd degen_acc = bdd_ithvar(accvar);
all_acceptance_conditions_ = degen_acc;
neg_acceptance_conditions_ = bdd_nithvar(accvar);
return degen_acc;
}
void tgba_digraph::merge_transitions()
{
for (auto& s: g_.states())
{
// Map a pair (dest state, acc) to the first transition seen
// with such characteristic.
typedef std::pair<graph_t::state, int> key_t;
std::unordered_map<key_t, graph_t::transition, pair_hash> trmap;
auto t = g_.out_iteraser(s);
while (t)
{
// Simply skip false transitions.
if (t->cond == bddfalse)
{
t.erase();
continue;
}
key_t k(t->dst, t->acc.id());
auto p = trmap.emplace(k, t.trans());
if (!p.second)
{
// A previous transitions exist for k, merge the
// condition, and schedule the transition for
// removal.
g_.trans_data(p.first->second).cond |= t->cond;
t.erase();
}
else
{
++t;
}
}
}
g_.defrag();
}
}

View file

@ -90,7 +90,7 @@ namespace spot
template<class Graph>
class tgba_digraph_succ_iterator: public tgba_succ_iterator
class SPOT_API tgba_digraph_succ_iterator: public tgba_succ_iterator
{
private:
typedef typename Graph::transition transition;
@ -153,7 +153,7 @@ namespace spot
};
class tgba_digraph: public tgba
class SPOT_API tgba_digraph: public tgba
{
public:
typedef digraph<tgba_graph_state, tgba_graph_trans_data> graph_t;
@ -302,24 +302,8 @@ namespace spot
return g_.trans_data(t);
}
void set_acceptance_conditions(bdd all)
{
bdd sup = bdd_support(all);
this->dict_->register_acceptance_variables(sup, this);
neg_acceptance_conditions_ = bddtrue;
while (sup != bddtrue)
{
neg_acceptance_conditions_ &= bdd_nithvar(bdd_var(sup));
sup = bdd_high(sup);
}
all_acceptance_conditions_ =
compute_all_acceptance_conditions(neg_acceptance_conditions_);
if (number_of_acceptance_conditions() == 1)
set_bprop(tgba_digraph::SingleAccSet);
else
clear_bprop(tgba_digraph::SingleAccSet);
}
void set_acceptance_conditions(bdd all);
bdd set_single_acceptance_set();
unsigned new_state()
{
@ -337,6 +321,15 @@ namespace spot
return g_.new_transition(src, dst, cond, acc);
}
unsigned new_acc_transition(unsigned src, unsigned dst,
bdd cond, bool acc = true)
{
if (acc)
return g_.new_transition(src, dst, cond, all_acceptance_conditions_);
else
return g_.new_transition(src, dst, cond);
}
auto out(unsigned src) const
SPOT_RETURN(g_.out(src));
auto out(unsigned src)
@ -378,45 +371,7 @@ namespace spot
/// Iterate over all transitions, and merge those with compatible
/// extremities and acceptance.
void merge_transitions()
{
for (auto& s: g_.states())
{
// Map a pair (dest state, acc) to the first transition seen
// with such characteristic.
typedef std::pair<graph_t::state, int> key_t;
std::unordered_map<key_t, graph_t::transition, pair_hash> trmap;
auto t = g_.out_iteraser(s);
while (t)
{
// Simply skip false transitions.
if (t->cond == bddfalse)
{
t.erase();
continue;
}
key_t k(t->dst, t->acc.id());
auto p = trmap.emplace(k, t.trans());
if (!p.second)
{
// A previous transitions exist for k, merge the
// condition, and schedule the transition for
// removal.
g_.trans_data(p.first->second).cond |= t->cond;
t.erase();
}
else
{
++t;
}
}
}
g_.defrag();
}
void merge_transitions();
protected:
unsigned bprops_ = 0;