Specialize scc_filter when handling tgba_explicit_formula automata.
If the input is a tgba_explicit_formula we can output a tgba_explicit_formula too, and we want to do that because it is more space efficient. * src/tgba/tgbaexplicit.hh (get_label): New method. * src/tgbaalgos/sccfilter.cc (create_transition): New function, to handle tgba_explicit_formula and tgba_explicit_string output differently. (filter_iter): Template it on the output tgba type, and adjust to call create_transition. (scc_filter): Use filter_iter<tgba_explicit_formula> or filter_iter<tgba_explicit_string> depending on the input tgba type.
This commit is contained in:
parent
dfb9c6622b
commit
81e0872b5d
3 changed files with 94 additions and 14 deletions
18
ChangeLog
18
ChangeLog
|
|
@ -1,3 +1,21 @@
|
||||||
|
2009-11-23 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
|
Specialize scc_filter when handling tgba_explicit_formula automata.
|
||||||
|
|
||||||
|
If the input is a tgba_explicit_formula we can output a
|
||||||
|
tgba_explicit_formula too, and we want to do that because it is
|
||||||
|
more space efficient.
|
||||||
|
|
||||||
|
* src/tgba/tgbaexplicit.hh (get_label): New method.
|
||||||
|
* src/tgbaalgos/sccfilter.cc (create_transition): New function,
|
||||||
|
to handle tgba_explicit_formula and tgba_explicit_string output
|
||||||
|
differently.
|
||||||
|
(filter_iter): Template it on the output tgba type, and adjust
|
||||||
|
to call create_transition.
|
||||||
|
(scc_filter): Use filter_iter<tgba_explicit_formula> or
|
||||||
|
filter_iter<tgba_explicit_string> depending on the input tgba
|
||||||
|
type.
|
||||||
|
|
||||||
2009-11-20 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
2009-11-20 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
Strip useless acceptance conditions in scc_filter().
|
Strip useless acceptance conditions in scc_filter().
|
||||||
|
|
|
||||||
|
|
@ -181,6 +181,20 @@ namespace spot
|
||||||
return name_state_map_.find(name) != name_state_map_.end();
|
return name_state_map_.find(name) != name_state_map_.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const label& get_label(const tgba_explicit::state* s) const
|
||||||
|
{
|
||||||
|
typename sn_map::const_iterator i = state_name_map_.find(s);
|
||||||
|
assert(i != state_name_map_.end());
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const label& get_label(const spot::state* s) const
|
||||||
|
{
|
||||||
|
const state_explicit* se = dynamic_cast<const state_explicit*>(s);
|
||||||
|
assert(se);
|
||||||
|
return get_label(se->get_state());
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the tgba_explicit::state for \a name, creating the state if
|
/// Return the tgba_explicit::state for \a name, creating the state if
|
||||||
/// it does not exist.
|
/// it does not exist.
|
||||||
state* add_state(const label& name)
|
state* add_state(const label& name)
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,36 @@ namespace spot
|
||||||
{
|
{
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
static
|
||||||
|
tgba_explicit::transition*
|
||||||
|
create_transition(const tgba* aut, tgba_explicit_string* out_aut,
|
||||||
|
const state* in_s, int in,
|
||||||
|
const state* out_s, int out)
|
||||||
|
{
|
||||||
|
std::ostringstream in_name;
|
||||||
|
in_name << "(#" << in << ") " << aut->format_state(in_s);
|
||||||
|
std::ostringstream out_name;
|
||||||
|
out_name << "(#" << out << ") " << aut->format_state(out_s);
|
||||||
|
return out_aut->create_transition(in_name.str(), out_name.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
tgba_explicit::transition*
|
||||||
|
create_transition(const tgba* aut, tgba_explicit_formula* out_aut,
|
||||||
|
const state* in_s, int, const state* out_s, int)
|
||||||
|
{
|
||||||
|
const tgba_explicit_formula* a =
|
||||||
|
static_cast<const tgba_explicit_formula*>(aut);
|
||||||
|
const ltl::formula* in_f = a->get_label(in_s);
|
||||||
|
const ltl::formula* out_f = a->get_label(out_s);
|
||||||
|
if (!out_aut->has_state(in_f))
|
||||||
|
in_f->clone();
|
||||||
|
if (!out_aut->has_state(out_f))
|
||||||
|
out_f->clone();
|
||||||
|
return out_aut->create_transition(in_f, out_f);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
class filter_iter: public tgba_reachable_iterator_depth_first
|
class filter_iter: public tgba_reachable_iterator_depth_first
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -36,7 +66,7 @@ namespace spot
|
||||||
const std::vector<bool>& useless,
|
const std::vector<bool>& useless,
|
||||||
bdd useful, bdd strip)
|
bdd useful, bdd strip)
|
||||||
: tgba_reachable_iterator_depth_first(a),
|
: tgba_reachable_iterator_depth_first(a),
|
||||||
out_(new tgba_explicit_string(a->get_dict())),
|
out_(new T(a->get_dict())),
|
||||||
sm_(sm),
|
sm_(sm),
|
||||||
useless_(useless),
|
useless_(useless),
|
||||||
useful_(useful),
|
useful_(useful),
|
||||||
|
|
@ -45,7 +75,7 @@ namespace spot
|
||||||
out_->set_acceptance_conditions(useful);
|
out_->set_acceptance_conditions(useful);
|
||||||
}
|
}
|
||||||
|
|
||||||
tgba_explicit_string*
|
T*
|
||||||
result()
|
result()
|
||||||
{
|
{
|
||||||
return out_;
|
return out_;
|
||||||
|
|
@ -62,13 +92,8 @@ namespace spot
|
||||||
const state* out_s, int out,
|
const state* out_s, int out,
|
||||||
const tgba_succ_iterator* si)
|
const tgba_succ_iterator* si)
|
||||||
{
|
{
|
||||||
std::ostringstream in_name;
|
|
||||||
in_name << "(#" << in << ") " << this->automata_->format_state(in_s);
|
|
||||||
std::ostringstream out_name;
|
|
||||||
out_name << "(#" << out << ") " << this->automata_->format_state(out_s);
|
|
||||||
|
|
||||||
tgba_explicit::transition* t =
|
tgba_explicit::transition* t =
|
||||||
out_->create_transition(in_name.str(), out_name.str());
|
create_transition(this->automata_, out_, in_s, in, out_s, out);
|
||||||
out_->add_conditions(t, si->current_condition());
|
out_->add_conditions(t, si->current_condition());
|
||||||
|
|
||||||
// Do not output any acceptance condition if either the source or
|
// Do not output any acceptance condition if either the source or
|
||||||
|
|
@ -81,12 +106,13 @@ namespace spot
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
tgba_explicit_string* out_;
|
T* out_;
|
||||||
const scc_map& sm_;
|
const scc_map& sm_;
|
||||||
const std::vector<bool>& useless_;
|
const std::vector<bool>& useless_;
|
||||||
bdd useful_;
|
bdd useful_;
|
||||||
bdd strip_;
|
bdd strip_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // anonymous
|
} // anonymous
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -122,12 +148,34 @@ namespace spot
|
||||||
bdd strip = bdd_exist(bdd_support(aut->all_acceptance_conditions()),
|
bdd strip = bdd_exist(bdd_support(aut->all_acceptance_conditions()),
|
||||||
positive);
|
positive);
|
||||||
useful = bdd_exist(useful, strip);
|
useful = bdd_exist(useful, strip);
|
||||||
filter_iter fi(aut, sm, ss.useless_scc_map, useful, strip);
|
|
||||||
|
// In most cases we will create a tgba_explicit_string copy of the
|
||||||
|
// initial tgba, but this is not very space efficient as the
|
||||||
|
// labels are built using the "format_state()" string output of
|
||||||
|
// the original automaton. In the case where the source automaton is
|
||||||
|
// a tgba_explicit_formula (typically after calling ltl2tgba_fm())
|
||||||
|
// we can create another tgba_explicit_formula instead.
|
||||||
|
const tgba_explicit_formula* af =
|
||||||
|
dynamic_cast<const tgba_explicit_formula*>(aut);
|
||||||
|
if (af)
|
||||||
|
{
|
||||||
|
filter_iter<tgba_explicit_formula> fi(af, sm, ss.useless_scc_map,
|
||||||
|
useful, strip);
|
||||||
|
fi.run();
|
||||||
|
tgba_explicit_formula* res = fi.result();
|
||||||
|
res->merge_transitions();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
filter_iter<tgba_explicit_string> fi(aut, sm, ss.useless_scc_map,
|
||||||
|
useful, strip);
|
||||||
fi.run();
|
fi.run();
|
||||||
tgba_explicit_string* res = fi.result();
|
tgba_explicit_string* res = fi.result();
|
||||||
res->merge_transitions();
|
res->merge_transitions();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue