* src/tgbatest/spotlbtt.test,

src/tgbatest/reductgba.cc,
src/tgbatest/ltl2tgba.cc:
Add option for reduction of TGBA.

* src/tgbatest/emptchk.test, src/tgbaalgos/Makefile.am,
src/tgbaalgos/tarjan_on_fly.hh, src/tgbaalgos/tarjan_on_fly.cc,
src/tgbaalgos/nesteddfs.hh, src/tgbaalgos/nesteddfs.cc,
src/tgbaalgos/minimalce.hh, src/tgbaalgos/minimalce.cc,
src/tgbaalgos/colordfs.hh, src/tgbaalgos/colordfs.cc:
Remove some bugs.

src/tgbaalgos/gtec/ce.cc:
Modification of construction of counter example.

* src/tgbaalgos/reductgba_sim.hh src/tgbaalgos/reductgba_sim.cc,
src/tgbaalgos/reductgba_sim_del.cc,
src/tgba/tgbareduc.hh, src/tgba/tgbareduc.cc:
Modification for delayed simulation.


* src/tgbaalgos/gtec/ce.hh,
* src/tgbatest/ltl2tgba.cc,
This commit is contained in:
martinez 2004-09-13 15:25:13 +00:00
parent 2d1151e018
commit 5af687b2c8
21 changed files with 931 additions and 418 deletions

View file

@ -1,3 +1,26 @@
2004-09-13 Thomas Martinez <martinez@src.lip6.fr>
* src/tgbatest/spotlbtt.test,
src/tgbatest/reductgba.cc,
src/tgbatest/ltl2tgba.cc:
Add option for reduction of TGBA.
* src/tgbatest/emptchk.test, src/tgbaalgos/Makefile.am,
src/tgbaalgos/tarjan_on_fly.hh, src/tgbaalgos/tarjan_on_fly.cc,
src/tgbaalgos/nesteddfs.hh, src/tgbaalgos/nesteddfs.cc,
src/tgbaalgos/minimalce.hh, src/tgbaalgos/minimalce.cc,
src/tgbaalgos/colordfs.hh, src/tgbaalgos/colordfs.cc:
Remove some bugs.
src/tgbaalgos/gtec/ce.cc:
Modification of construction of counter example.
* src/tgbaalgos/reductgba_sim.hh src/tgbaalgos/reductgba_sim.cc,
src/tgbaalgos/reductgba_sim_del.cc,
src/tgba/tgbareduc.hh, src/tgba/tgbareduc.cc:
Modification for delayed simulation.
2004-08-23 Thomas Martinez <martinez@src.lip6.fr> 2004-08-23 Thomas Martinez <martinez@src.lip6.fr>
* src/tgbaalgos/tarjan_on_fly.hh, * src/tgbaalgos/tarjan_on_fly.hh,
@ -9,11 +32,11 @@
src/tgbaalgos/colordfs.hh, src/tgbaalgos/colordfs.hh,
src/tgbaalgos/colordfs.cc: four new algorithms for emptyness check. src/tgbaalgos/colordfs.cc: four new algorithms for emptyness check.
src/tgbaalgos/gtec/ce.hh, * src/tgbaalgos/gtec/ce.hh,
src/tgbaalgos/gtec/ce.cc: Adapt the counter exemple for the ce src/tgbaalgos/gtec/ce.cc: Adapt the counter exemple for the ce
object in minimalce.hh. object in minimalce.hh.
src/tgbatest/ltl2tgba.cc, * src/tgbatest/ltl2tgba.cc,
src/tgbatest/emptchk.test, src/tgbatest/emptchk.test,
src/tgbaalgos/Makefile.am: Add files for emptyness-check. src/tgbaalgos/Makefile.am: Add files for emptyness-check.

View file

@ -22,11 +22,12 @@
# Check for the reduc visitor. # Check for the reduc visitor.
. ./defs || exit 1 # . ./defs || exit 1
set -e set -e
FICH=${1-$srcdir/formulae.txt} #FICH=${1-$srcdir/formulae.txt}
FICH=${1-$srcdir/formules3.ltl}
for opt in 0 1 2 3; do for opt in 0 1 2 3; do
rm -f result.data rm -f result.data

View file

@ -35,7 +35,7 @@ namespace spot
tgba_reachable_iterator_breadth_first(a), tgba_reachable_iterator_breadth_first(a),
h_(nshf->build()) h_(nshf->build())
{ {
dict_->register_all_variables_of(a, this); // useful ?? dict_->register_all_variables_of(a, this);
run(); run();
all_acceptance_conditions_ = a->all_acceptance_conditions(); all_acceptance_conditions_ = a->all_acceptance_conditions();
@ -57,12 +57,12 @@ namespace spot
} }
void void
tgba_reduc::prune_automata(simulation_relation* rel) tgba_reduc::quotient_state(direct_simulation_relation* rel)
{ {
// Remember that for each state couple (*i)->second // Remember that for each state couple
// simulate (*i)->first. // (*i)->second simulate (*i)->first.
for (simulation_relation::iterator i = rel->begin(); for (direct_simulation_relation::iterator i = rel->begin();
i != rel->end(); ++i) i != rel->end(); ++i)
{ {
@ -72,28 +72,29 @@ namespace spot
// We check if the two state are co-simulate. // We check if the two state are co-simulate.
bool recip = false; bool recip = false;
for (spot::simulation_relation::iterator j = i; for (direct_simulation_relation::iterator j = i;
j != rel->end(); ++j) j != rel->end(); ++j)
if ((((*i)->first)->compare((*j)->second) == 0) && if ((((*i)->first)->compare((*j)->second) == 0) &&
(((*j)->first)->compare((*i)->second) == 0)) (((*j)->first)->compare((*i)->second) == 0))
recip = true; recip = true;
if (!recip) if (recip)
this->redirect_transition((*i)->first, (*i)->second); //this->redirect_transition((*i)->first, (*i)->second);
else this->merge_state((*i)->first, (*i)->second);
this->merge_state((*i)->first, (*i)->second);
} }
this->merge_transitions(); this->merge_transitions();
} }
void void
tgba_reduc::quotient_state(simulation_relation* rel) tgba_reduc::quotient_state(delayed_simulation_relation* rel)
{ {
// Remember that for each state couple (*i)->second if (nb_set_acc_cond() > 1)
// simulate (*i)->first. return;
for (simulation_relation::iterator i = rel->begin(); //this->quotient_state(rel);
for (delayed_simulation_relation::iterator i = rel->begin();
i != rel->end(); ++i) i != rel->end(); ++i)
{ {
@ -103,7 +104,7 @@ namespace spot
// We check if the two state are co-simulate. // We check if the two state are co-simulate.
bool recip = false; bool recip = false;
for (spot::simulation_relation::iterator j = i; for (delayed_simulation_relation::iterator j = i;
j != rel->end(); ++j) j != rel->end(); ++j)
if ((((*i)->first)->compare((*j)->second) == 0) && if ((((*i)->first)->compare((*j)->second) == 0) &&
(((*j)->first)->compare((*i)->second) == 0)) (((*j)->first)->compare((*i)->second) == 0))
@ -116,6 +117,19 @@ namespace spot
this->merge_transitions(); this->merge_transitions();
} }
void
tgba_reduc::delete_transitions(simulation_relation* rel)
{
for (simulation_relation::iterator i = rel->begin();
i != rel->end(); ++i)
{
if (((*i)->first)->compare((*i)->second) == 0)
continue;
this->redirect_transition((*i)->first, (*i)->second);
}
this->merge_transitions();
}
void void
tgba_reduc::prune_scc() tgba_reduc::prune_scc()
{ {
@ -146,6 +160,7 @@ namespace spot
} }
//////////////////////////////////////////// ////////////////////////////////////////////
// for build tgba_reduc
void void
tgba_reduc::start() tgba_reduc::start()
@ -430,10 +445,12 @@ namespace spot
tgba_reduc::merge_state_delayed(const spot::state*, tgba_reduc::merge_state_delayed(const spot::state*,
const spot::state*) const spot::state*)
{ {
// TO DO
} }
///////////////////////////////////////// /////////////////////////////////////////
///////////////////////////////////////// /////////////////////////////////////////
// Compute SCC
// From gtec.cc // From gtec.cc
void void
@ -604,24 +621,24 @@ namespace spot
i != s1->end(); ++i) i != s1->end(); ++i)
(*i)->acceptance_conditions = bddfalse; (*i)->acceptance_conditions = bddfalse;
} }
else /*
else
{ {
// FIXME // FIXME
/* tgba_succ_iterator* si = this->succ_iter(sm->first);
tgba_succ_iterator* si = this->succ_iter(sm->first); spot::state* s2 = si->current_state();
spot::state* s2 = si->current_state(); seen_map::iterator sm2 = si_.find(s2);
seen_map::iterator sm2 = si_.find(s2); if (sm2->second == n)
if (sm2->second == n) {
{ s1 = name_state_map_[tgba_explicit::format_state(sm2->first)];
s1 = name_state_map_[tgba_explicit::format_state(sm2->first)]; for (state::iterator i = s1->begin();
for (state::iterator i = s1->begin(); i != s1->end(); ++i)
i != s1->end(); ++i) (*i)->acceptance_conditions = bddfalse;
(*i)->acceptance_conditions = bddfalse;
}
delete s2;
delete si;
*/
} }
delete s2;
delete si;
}
*/
} }
} }
@ -825,6 +842,7 @@ namespace spot
} }
/*
void void
tgba_reduc::remove_scc_depth_first(spot::state* s, int n) tgba_reduc::remove_scc_depth_first(spot::state* s, int n)
{ {
@ -853,7 +871,9 @@ namespace spot
seen_ = 0; seen_ = 0;
} }
} }
*/
/*
bool bool
tgba_reduc::is_alpha_ball(const spot::state* s, bdd label, int n) tgba_reduc::is_alpha_ball(const spot::state* s, bdd label, int n)
{ {
@ -909,6 +929,21 @@ namespace spot
return ret; return ret;
} }
*/
int
tgba_reduc::nb_set_acc_cond() const
{
bdd acc, all;
acc = all = this->all_acceptance_conditions();
int count = 0;
while (all != bddfalse)
{
all -= bdd_satone(all);
count++;
}
return count;
}
//////// JUST FOR DEBUG ////////// //////// JUST FOR DEBUG //////////

View file

@ -34,6 +34,15 @@ namespace spot
typedef Sgi::pair<const spot::state*, const spot::state*> state_couple; typedef Sgi::pair<const spot::state*, const spot::state*> state_couple;
typedef Sgi::vector<state_couple*> simulation_relation; typedef Sgi::vector<state_couple*> simulation_relation;
/*
typedef Sgi::vector<state_couple*> direct_simulation_relation;
typedef Sgi::vector<state_couple*> delayed_simulation_relation;
*/
class direct_simulation_relation : public simulation_relation{};
class delayed_simulation_relation : public simulation_relation{};
class tgba_reduc: public tgba_explicit, class tgba_reduc: public tgba_explicit,
public tgba_reachable_iterator_breadth_first public tgba_reachable_iterator_breadth_first
{ {
@ -46,11 +55,15 @@ namespace spot
/// Reduce the automata using a relation simulation /// Reduce the automata using a relation simulation
/// Do not call this method with a delayed simulation relation. /// Do not call this method with a delayed simulation relation.
void prune_automata(simulation_relation* rel); void quotient_state(direct_simulation_relation* rel);
/// Build the quotient automata. Call this method /// Build the quotient automata. Call this method
/// when use to a delayed simulation relation. /// when use to a delayed simulation relation.
void quotient_state(simulation_relation* rel); void quotient_state(delayed_simulation_relation* rel);
/// \brief Delete some transitions with help of a simulation
/// relation.
void delete_transitions(simulation_relation* rel);
/// Remove all state which not lead to an accepting cycle. /// Remove all state which not lead to an accepting cycle.
void prune_scc(); void prune_scc();
@ -144,9 +157,9 @@ namespace spot
/// publisher = {Springer-Verlag} /// publisher = {Springer-Verlag}
/// } /// }
/// \endverbatim /// \endverbatim
bool is_alpha_ball(const spot::state* s, // bool is_alpha_ball(const spot::state* s,
bdd label = bddfalse, // bdd label = bddfalse,
int n = -1); // int n = -1);
// Return true if we can't reach a state with // Return true if we can't reach a state with
// an other value of scc. // an other value of scc.
@ -165,11 +178,13 @@ namespace spot
void remove_scc(spot::state* s); void remove_scc(spot::state* s);
/// Same as remove_scc but more efficient. /// Same as remove_scc but more efficient.
void remove_scc_depth_first(spot::state* s, int n = -1); // void remove_scc_depth_first(spot::state* s, int n = -1);
/// For compute_scc. /// For compute_scc.
void remove_component(const spot::state* from); void remove_component(const spot::state* from);
int tgba_reduc::nb_set_acc_cond() const;
}; };
} }

View file

@ -36,6 +36,7 @@ tgbaalgos_HEADERS = \
magic.hh \ magic.hh \
minimalce.hh \ minimalce.hh \
nesteddfs.hh \ nesteddfs.hh \
nesteddfsgen.hh \
neverclaim.hh \ neverclaim.hh \
powerset.hh \ powerset.hh \
reachiter.hh \ reachiter.hh \
@ -55,6 +56,7 @@ libtgbaalgos_la_SOURCES = \
magic.cc \ magic.cc \
minimalce.cc \ minimalce.cc \
nesteddfs.cc \ nesteddfs.cc \
nesteddfsgen.cc \
neverclaim.cc \ neverclaim.cc \
powerset.cc \ powerset.cc \
reachiter.cc \ reachiter.cc \

View file

@ -30,6 +30,7 @@ namespace spot
colordfs_search::colordfs_search(const tgba_tba_proxy* a) colordfs_search::colordfs_search(const tgba_tba_proxy* a)
: a(a), x(0), counter_(0) : a(a), x(0), counter_(0)
{ {
Maxdepth = -1;
} }
colordfs_search::~colordfs_search() colordfs_search::~colordfs_search()
@ -111,9 +112,7 @@ namespace spot
int n = 0; int n = 0;
for (i->first(); !i->done(); i->next(), n++) for (i->first(); !i->done(); i->next(), n++)
{ {
//std::cout << "iter : " << n << std::endl;
s2 = i->current_state(); s2 = i->current_state();
//std::cout << a->format_state(s2) << std::endl;
hi = h.find(s2); hi = h.find(s2);
if (hi != h.end()) if (hi != h.end())
return_value &= (hi->second.c == black); return_value &= (hi->second.c == black);
@ -123,8 +122,6 @@ namespace spot
} }
delete i; delete i;
//std::cout << "End Loop" << std::endl;
hi = h.find(s); hi = h.find(s);
assert(hi != h.end()); assert(hi != h.end());
if (return_value) if (return_value)
@ -138,8 +135,8 @@ namespace spot
{ {
clock(); clock();
counter_ = new ce::counter_example(a); counter_ = new ce::counter_example(a);
const state* s = a->get_init_state(); const state *s = a->get_init_state();
if (dfs_blue(s)) if (dfs_blue_min(s))
counter_->build_cycle(x); counter_->build_cycle(x);
else else
{ {
@ -154,49 +151,60 @@ namespace spot
bool bool
colordfs_search::dfs_blue(const state* s, bdd) colordfs_search::dfs_blue(const state* s, bdd)
{ {
//std::cout << "dfs_blue : " << a->format_state(s) << std::endl; std::cout << "dfs_blue : " << std::endl;
if (!push(s, blue))
return false;
hash_type::iterator hi; if (stack.empty())
tgba_succ_iterator* i = a->succ_iter(s); // It's a new search.
int n = 0; push(a->get_init_state(), blue);
for (i->first(); !i->done(); i->next(), n++) else
tstack.pop_front();
while (!stack.empty())
{ {
const state* s2 = i->current_state(); recurse:
//std::cout << "s2 : " << a->format_state(s2) << std::endl; tgba_succ_iterator *i = stack.front().second;
hi = h.find(s2); hash_type::iterator hi;
if (a->state_is_accepting(s2) &&
(hi != h.end() && hi->second.is_in_cp)) //std::cout << a->format_state(p.first) << std::endl;
while (!i->done())
{ {
ce::state_ce ce; const state* s2 = i->current_state();
ce = ce::state_ce(s2, i->current_condition()); hi = h.find(s2);
x = const_cast<state*>(s2); if (a->state_is_accepting(s2) &&
delete i; (hi != h.end() && hi->second.is_in_cp))
return true;// a counter example is found !!
}
else if (hi == h.end() || hi->second.c == white)
{
int res = dfs_blue(s2, i->current_acceptance_conditions());
if (res == 1)
{ {
delete i; //ce::state_ce ce;
return true; //ce = ce::state_ce(s2, i->current_condition());
x = const_cast<state*>(s2);
//push(s2, blue); //
//delete i;
return true;// a counter example is found !!
} }
else if (hi == h.end() || hi->second.c == white)
{
push(s2, blue);
goto recurse;
}
else
delete s2;
i->next();
} }
else
delete s2; // FIXME
}
delete i;
pop(); s = stack.front().first;
pop();
if (!all_succ_black(s) && if (!all_succ_black(s) &&
a->state_is_accepting(s)) a->state_is_accepting(s))
{ {
if (dfs_red(s)) if (dfs_red(s))
return 1; return true;
dfs_black(s);
hash_type::iterator hi = h.find(s);
assert(hi == h.end());
hi->second.c = black;
}
delete s; //
} }
return false; return false;
@ -205,7 +213,7 @@ namespace spot
bool bool
colordfs_search::dfs_red(const state* s) colordfs_search::dfs_red(const state* s)
{ {
//std::cout << "dfs_red : " << a->format_state(s) << std::endl; std::cout << "dfs_red : " << a->format_state(s) << std::endl;
if (!push(s, red)) if (!push(s, red))
return false; return false;
@ -240,12 +248,143 @@ namespace spot
} }
delete i; delete i;
hi = h.find(s);
assert(hi == h.end());
hi->second.c = black;
//std::cout << "dfs_red : pop" << std::endl; //std::cout << "dfs_red : pop" << std::endl;
pop(); pop();
return false; return false;
} }
///////////////////////////////////////////////////////////////////////
// for minimisation
bool
colordfs_search::dfs_blue_min(const state* s, bdd)
{
//std::cout << "dfs_blue : " << a->format_state(s) << std::endl;
if (!push(s, blue))
return false;
hash_type::iterator hi = h.find(s);
if (hi != h.end())
{
if (((int)stack.size() + 1) < hi->second.depth)
hi->second.depth = stack.size(); // for minimize
}
else
{
assert(0);
}
if (Maxdepth == -1 || ((int)stack.size() + 1 < Maxdepth))
{
tgba_succ_iterator* i = a->succ_iter(s);
int n = 0;
for (i->first(); !i->done(); i->next(), n++)
{
const state* s2 = i->current_state();
//std::cout << "s2 : " << a->format_state(s2) << std::endl;
hi = h.find(s2);
if (a->state_is_accepting(s2) &&
(hi != h.end() && hi->second.is_in_cp))
{
Maxdepth = stack.size();
ce::state_ce ce;
ce = ce::state_ce(s2, i->current_condition());
x = const_cast<state*>(s2);
delete i;
return true;// a counter example is found !!
}
else if (hi == h.end() || hi->second.c == white)
{
int res = dfs_blue_min(s2, i->current_acceptance_conditions());
if (res == 1)
{
delete i;
return true;
}
}
else
delete s2; // FIXME
}
delete i;
pop();
if (!all_succ_black(s) &&
a->state_is_accepting(s))
{
if (dfs_red_min(s))
return 1;
dfs_black(s);
}
}
return false;
}
bool
colordfs_search::dfs_red_min(const state* s)
{
//std::cout << "dfs_red : " << a->format_state(s) << std::endl;
if (!push(s, red))
return false;
hash_type::iterator hi = h.find(s);
if (hi != h.end())
{
if (((int)stack.size() + 1) < hi->second.depth)
hi->second.depth = stack.size(); // for minimize
}
else
assert(0);
if (Maxdepth == -1 || ((int)stack.size() + 1 < Maxdepth))
{
tgba_succ_iterator* i = a->succ_iter(s);
int n = 0;
for (i->first(); !i->done(); i->next(), n++)
{
const state* s2 = i->current_state();
hi = h.find(s2);
if (hi != h.end() && hi->second.is_in_cp &&
(a->state_is_accepting(s2) ||
(hi->second.c == blue)))
{
Maxdepth = stack.size();
ce::state_ce ce;
ce = ce::state_ce(s2->clone(), i->current_condition());
x = const_cast<state*>(s2);
delete i;
return true;// a counter example is found !!
}
if (hi != h.end() &&
(hi->second.c == blue))
// || ((int)stack.size() + 1) < hi->second.depth))
{
delete s2; // FIXME
if (dfs_red_min(hi->first))
{
delete i;
return true;
}
}
else
delete s2;
}
delete i;
//std::cout << "dfs_red : pop" << std::endl;
pop();
}
return false;
}
void void
colordfs_search::dfs_black(const state* s) colordfs_search::dfs_black(const state* s)
{ {

View file

@ -97,6 +97,8 @@ namespace spot
/// Pages = "92-108") /// Pages = "92-108")
bool dfs_blue(const state* s, bdd acc = bddfalse); bool dfs_blue(const state* s, bdd acc = bddfalse);
bool dfs_red(const state* s); bool dfs_red(const state* s);
bool dfs_blue_min(const state* s, bdd acc = bddfalse);
bool dfs_red_min(const state* s);
void dfs_black(const state* s); void dfs_black(const state* s);
/// Append a new state to the current path. /// Append a new state to the current path.
@ -110,6 +112,7 @@ namespace spot
const tgba_tba_proxy* a; ///< The automata to check. const tgba_tba_proxy* a; ///< The automata to check.
/// The state for which we are currently seeking an SCC. /// The state for which we are currently seeking an SCC.
const state* x; const state* x;
int Maxdepth; ///< The size of the current counter example.
ce::counter_example* counter_; ce::counter_example* counter_;
clock_t tps_; clock_t tps_;

View file

@ -35,7 +35,10 @@ namespace spot
eccf) eccf)
: ecs_(ecs) : ecs_(ecs)
{ {
counter_ = new ce::counter_example(ecs->aut);
std::cout << "counter_example" << std::endl;
//counter_ = new ce::counter_example(ecs->aut);
assert(!ecs_->root.empty()); assert(!ecs_->root.empty());
assert(suffix.empty()); assert(suffix.empty());
@ -79,7 +82,7 @@ namespace spot
suffix.push_front(spi.first); suffix.push_front(spi.first);
///// /////
counter_->prefix.push_front(ce::state_ce(spi.first->clone(), bddfalse)); // counter_->prefix.push_front(ce::state_ce(spi.first->clone(), bddfalse));
//// ////
// We build a path trough each SCC in the stack. For the // We build a path trough each SCC in the stack. For the
@ -127,14 +130,15 @@ namespace spot
state_sequence seq; state_sequence seq;
/// ///
ce::l_state_ce seq_count; // ce::l_state_ce seq_count;
/// ///
seq.push_front(h_dest); seq.push_front(h_dest);
while (src->compare(start)) while (src->compare(start))
{ {
/// ///
seq_count.push_front(ce::state_ce(src->clone(), bddfalse)); // seq_count.push_front(ce::state_ce(src->clone(),
// bddfalse));
/// ///
seq.push_front(src); seq.push_front(src);
@ -144,8 +148,8 @@ namespace spot
suffix.splice(suffix.end(), seq); suffix.splice(suffix.end(), seq);
/// ///
counter_->prefix.splice(counter_->prefix.end(), // counter_->prefix.splice(counter_->prefix.end(),
seq_count); // seq_count);
/// ///
// Exit this BFS for this SCC. // Exit this BFS for this SCC.
@ -186,6 +190,8 @@ namespace spot
const state* from, const state* from,
const state* to) const state* to)
{ {
//std::cout << "complete_cycle" << std::endl;
// If by change or period already ends on the state we have // If by change or period already ends on the state we have
// to reach back, we are done. // to reach back, we are done.
if (from == to if (from == to
@ -233,8 +239,8 @@ namespace spot
cycle_path p; cycle_path p;
/// ///
ce::l_state_ce p_counter; // ce::l_state_ce p_counter;
p_counter.push_front(ce::state_ce(h_dest->clone(), cond)); // p_counter.push_front(ce::state_ce(h_dest->clone(), cond));
/// ///
p.push_front(state_proposition(h_dest, cond)); p.push_front(state_proposition(h_dest, cond));
@ -242,15 +248,16 @@ namespace spot
{ {
const state_proposition& psi = father[src]; const state_proposition& psi = father[src];
/// ///
p_counter.push_front(ce::state_ce(src->clone(), psi.second)); // p_counter.push_front(ce::state_ce(src->clone(),
// psi.second));
/// ///
p.push_front(state_proposition(src, psi.second)); p.push_front(state_proposition(src, psi.second));
src = psi.first; src = psi.first;
} }
period.splice(period.end(), p); period.splice(period.end(), p);
/// ///
counter_->cycle.splice(counter_->cycle.end(), // counter_->cycle.splice(counter_->cycle.end(),
p_counter); // p_counter);
/// ///
// Exit the BFS, but release all iterators first. // Exit the BFS, but release all iterators first.
@ -441,6 +448,8 @@ namespace spot
counter_example::accepting_path(const explicit_connected_component* scc, counter_example::accepting_path(const explicit_connected_component* scc,
const state* start, bdd acc_to_traverse) const state* start, bdd acc_to_traverse)
{ {
//std::cout << "accepting_path" << std::endl;
// State seen during the DFS. // State seen during the DFS.
typedef Sgi::hash_set<const state*, typedef Sgi::hash_set<const state*,
state_ptr_hash, state_ptr_equal> set_type; state_ptr_hash, state_ptr_equal> set_type;
@ -450,6 +459,9 @@ namespace spot
while (acc_to_traverse != bddfalse) while (acc_to_traverse != bddfalse)
{ {
//std::cout << "accepting_path : while (acc_to_traverse != bddfalse)"
// << std::endl;
// Initial state. // Initial state.
{ {
tgba_succ_iterator* i = ecs_->aut->succ_iter(start); tgba_succ_iterator* i = ecs_->aut->succ_iter(start);
@ -467,6 +479,9 @@ namespace spot
while (!todo.empty()) while (!todo.empty())
{ {
// std::cout << "accepting_path : while (!todo.empty())"
// << std::endl;
tgba_succ_iterator* iter = todo.top().iter; tgba_succ_iterator* iter = todo.top().iter;
const state* s = todo.top().s; const state* s = todo.top().s;
@ -563,8 +578,8 @@ namespace spot
it != best_path.end(); ++it) it != best_path.end(); ++it)
{ {
period.push_back(*it); period.push_back(*it);
ce::state_ce ce(it->first->clone(), it->second); //ce::state_ce ce(it->first->clone(), it->second);
counter_->cycle.push_back(ce); //counter_->cycle.push_back(ce);
//counter_->cycle.push_back(*it); //counter_->cycle.push_back(*it);
} }

View file

@ -223,14 +223,15 @@ namespace spot
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// minimal_search // minimal_search
minimalce_search::minimalce_search(const tgba_tba_proxy *a) minimalce_search::minimalce_search(const tgba_tba_proxy *a,
bool mode)
: a(a), min_ce(0) : a(a), min_ce(0)
{ {
mode_ = mode;
} }
minimalce_search::~minimalce_search() minimalce_search::~minimalce_search()
{ {
hash_type::const_iterator s = h_lenght.begin(); hash_type::const_iterator s = h_lenght.begin();
while (s != h_lenght.end()) while (s != h_lenght.end())
{ {
@ -244,11 +245,13 @@ namespace spot
i != l_ce.end();) i != l_ce.end();)
{ {
//std::cout << "delete a counter" << std::endl; //std::cout << "delete a counter" << std::endl;
if (*i == min_ce) /*
if (*i == min_ce)
{ {
++i; ++i;
continue; continue;
} }
*/
ce::counter_example* ce = *i; ce::counter_example* ce = *i;
++i; ++i;
delete ce; delete ce;
@ -262,11 +265,22 @@ namespace spot
{ {
clock(); clock();
nb_found = 0; nb_found = 0;
min_ce = new ce::counter_example(a);
if ((!min_ce && mode_) ||
!mode_)
min_ce = new ce::counter_example(a);
if (mode_)
{
min_ce = find();
tps_ = clock();
return min_ce;
}
std::ostringstream os; std::ostringstream os;
const state* s = a->get_init_state(); const state* s = a->get_init_state();
recurse_find(s, os); recurse_find(s, os);
std::cout << "nb_found : " << nb_found << std::endl; //std::cout << "nb_found : " << nb_found << std::endl;
if (min_ce->size() == 0) if (min_ce->size() == 0)
{ {
@ -279,45 +293,212 @@ namespace spot
} }
ce::counter_example* ce::counter_example*
minimalce_search::check(ce::counter_example*) minimalce_search::check(ce::counter_example* ce)
{ {
min_ce = new ce::counter_example(a); min_ce = ce;
/*
ce::l_state_ce::iterator i;
int depth = 0;
for (i = min_ce->prefix.begin();
i != min_ce->prefix.end(); ++i, ++depth)
{
stack.push_front(i->first);
//if (h_lenght.find(i->first) == h_lenght.end())
h_lenght[i->first] = depth;
}
for (i = min_ce->cycle.begin();
i != min_ce->cycle.end(); ++i, ++depth)
{
stack.push_front(i->first);
if (h_lenght.find(i->first) == h_lenght.end())
h_lenght[i->first] = depth;
}
*/
const state* s = a->get_init_state();
std::ostringstream os; std::ostringstream os;
const state* s = a->get_init_state();
recurse_find(s, os); recurse_find(s, os);
//if (recurse_find(s)) //std::cout << "nb_found : " << nb_found << std::endl;
//return min_ce; tps_ = clock();
//else
return min_ce; return min_ce;
} }
ce::counter_example*
minimalce_search::find()
{
/// FIXME
std::ostringstream os;
int mode = normal;
int depth_mode = 0;
int depth_mode_memory = -1;
const state* s = 0;
hash_type::iterator i;
tgba_succ_iterator* iter = 0;
if (!h_lenght.size())
{
// it's a new search
//std::cout << "it's a new search" << std::endl;
s = a->get_init_state();
i = h_lenght.find(s);
if (i != h_lenght.end())
{
delete s;
s = i->first;
if (((int)stack.size() + 1) < i->second)
i->second = stack.size() + 1;
}
else
h_lenght[s] = stack.size();
iter = a->succ_iter(s);
iter->first();
stack.push_front(state_pair(s, iter));
depth_mode++;
}
else
s = stack.front().first;
while (!stack.empty())
{
recurse:
//std::cout << "recurse: " << a->format_state(s) << std::endl;
/*
if (iter)
delete iter;
*/
iter = stack.front().second;
while (!iter->done())
{
//std::cout << "iter" << std::endl;
//stack_type::iterator j = stack.begin();
//j->second = iter->current_condition();
const state* succ = iter->current_state();
if ((min_ce->size() == 0) ||
((int)stack.size() + 1 <= min_ce->size()))
{
int depth = in_stack(succ, os);
if (depth != -1)
{
if (closes_accepting(succ, depth, os))
{
// New counter example is found !!
//std::cout << "CE found !!" << std::endl;
save_counter(succ, os);
i = h_lenght.find(succ);
if (i == h_lenght.end())
h_lenght[succ] = stack.size() + 1;
else
{
delete succ;
if (((int)stack.size() + 1) < i->second)
i->second = stack.size() + 1;
}
iter->next();
return min_ce;
}
else
delete succ;
}
else if ((mode == careful) ||
a->state_is_accepting(succ))
{
s = succ;
iter->next();
if (mode != careful)
depth_mode_memory = depth_mode;
mode = careful;
hash_type::iterator i = h_lenght.find(s);
if (i != h_lenght.end())
{
delete s;
s = i->first;
if (((int)stack.size() + 1) < i->second)
i->second = stack.size() + 1;
}
else
h_lenght[s] = stack.size();
iter = a->succ_iter(s);
iter->first();
stack.push_front(state_pair(s, iter));
depth_mode++;
goto recurse;
}
else if (h_lenght.find(succ) == h_lenght.end())
{
s = succ;
iter->next();
hash_type::iterator i = h_lenght.find(s);
if (i != h_lenght.end())
{
delete s;
s = i->first;
if (((int)stack.size() + 1) < i->second)
i->second = stack.size() + 1;
}
else
h_lenght[s] = stack.size();
iter = a->succ_iter(s);
iter->first();
stack.push_front(state_pair(s, iter));
depth_mode++;
goto recurse;
}
else if ((h_lenght[succ] > (int)stack.size() + 1) &&
(min_ce->size() != 0))
{
s = succ;
iter->next();
if (mode != careful)
depth_mode_memory = depth_mode;
mode = careful;
hash_type::iterator i = h_lenght.find(s);
if (i != h_lenght.end())
{
delete s;
s = i->first;
if (((int)stack.size() + 1) < i->second)
i->second = stack.size() + 1;
}
else
h_lenght[s] = stack.size();
iter = a->succ_iter(s);
iter->first();
stack.push_front(state_pair(s, iter));
depth_mode++;
goto recurse;
}
else
delete succ;
}
else
delete succ;
iter->next();
}
delete iter;
depth_mode--;
if (depth_mode_memory == depth_mode)
{
depth_mode_memory = -1;
mode = normal;
}
stack.pop_front();
s = stack.front().first;
}
return 0;
}
void void
minimalce_search::recurse_find(const state* s, minimalce_search::recurse_find(const state* s,
std::ostringstream& os, std::ostringstream& os,
int mode) int mode)
{ {
/*
std::cout << os.str() << "recurse find : " std::cout << os.str() << "recurse find : "
<< a->format_state(s) << std::endl; << a->format_state(s) << std::endl;
*/
hash_type::iterator i = h_lenght.find(s); hash_type::iterator i = h_lenght.find(s);
if (i != h_lenght.end()) if (i != h_lenght.end())
@ -328,22 +509,20 @@ namespace spot
i->second = stack.size() + 1; i->second = stack.size() + 1;
} }
else else
h_lenght[s] = stack.size(); h_lenght[s] = stack.size() + 1;
stack.push_front(state_pair(s, bddfalse)); //stack.push_front(state_pair(s, bddfalse));
//stack.push_front(s);
tgba_succ_iterator* iter = a->succ_iter(s); tgba_succ_iterator* iter = a->succ_iter(s);
stack.push_front(state_pair(s, iter));
iter->first(); iter->first();
while (!iter->done()) while (!iter->done())
{ {
stack_type::iterator j = stack.begin(); //stack_type::iterator j = stack.begin();
j->second = iter->current_condition(); //j->second = iter->current_condition();
const state* succ = iter->current_state(); const state* succ = iter->current_state();
std::cout << "stack.size() +1: " << (int)stack.size() + 1
<< "min_ce->size() : " << min_ce->size()<< std::endl;
if ((min_ce->size() == 0) || if ((min_ce->size() == 0) ||
((int)stack.size() + 1 <= min_ce->size())) ((int)stack.size() + 1 <= min_ce->size()))
{ {
@ -479,9 +658,7 @@ namespace spot
//std::cout << os.str() << "save counter" << std::endl; //std::cout << os.str() << "save counter" << std::endl;
nb_found++; nb_found++;
if (min_ce->size()) if (!min_ce->size())
l_ce.push_front(min_ce);
else
delete min_ce; delete min_ce;
min_ce = new ce::counter_example(a); min_ce = new ce::counter_example(a);
@ -489,8 +666,8 @@ namespace spot
for (stack_type::iterator i = stack.begin(); for (stack_type::iterator i = stack.begin();
i != stack.end(); ++i) i != stack.end(); ++i)
{ {
ce = ce::state_ce(i->first->clone(), i->second); //ce = ce::state_ce(i->first->clone(), i->second->current_condition());
//ce = ce::state_ce((*i)->clone(), bddfalse); ce = ce::state_ce(i->first->clone(), bddfalse);
min_ce->prefix.push_front(ce); min_ce->prefix.push_front(ce);
} }
@ -500,6 +677,7 @@ namespace spot
//const state* s = *i; //const state* s = *i;
min_ce->build_cycle(s); min_ce->build_cycle(s);
l_ce.push_front(min_ce);
} }
std::ostream& std::ostream&

View file

@ -58,7 +58,7 @@ namespace spot
/// \brief Project a counter example on a tgba. /// \brief Project a counter example on a tgba.
void project_ce(const tgba* aut, std::ostream& os = std::cout); void project_ce(const tgba* aut, std::ostream& os = std::cout);
// \brief Build a tgba from a counter example. /// \brief Build a tgba from a counter example.
tgba* ce2tgba(); tgba* ce2tgba();
l_state_ce prefix; l_state_ce prefix;
@ -89,7 +89,7 @@ namespace spot
class minimalce_search: public emptyness_search class minimalce_search: public emptyness_search
{ {
public: public:
minimalce_search(const tgba_tba_proxy *a); minimalce_search(const tgba_tba_proxy *a, bool mode = false);
virtual ~minimalce_search(); virtual ~minimalce_search();
@ -99,6 +99,8 @@ namespace spot
/// \brief Find a counter example shorter than \a min_ce. /// \brief Find a counter example shorter than \a min_ce.
ce::counter_example* check(ce::counter_example* min_ce); ce::counter_example* check(ce::counter_example* min_ce);
ce::counter_example* find();
/// \brief Print Stat. /// \brief Print Stat.
std::ostream& print_stat(std::ostream& os) const; std::ostream& print_stat(std::ostream& os) const;
@ -119,7 +121,8 @@ namespace spot
state_ptr_hash, state_ptr_equal> hash_type; state_ptr_hash, state_ptr_equal> hash_type;
hash_type h_lenght; ///< Map of visited states. hash_type h_lenght; ///< Map of visited states.
typedef std::pair<const state*, bdd> state_pair; typedef std::pair<const state*, tgba_succ_iterator*> state_pair;
//typedef std::pair<const state*, bdd> state_pair;
typedef std::list<state_pair> stack_type; typedef std::list<state_pair> stack_type;
//typedef std::list<const state*> stack_type; //typedef std::list<const state*> stack_type;
stack_type stack; ///< Stack of visited states on the path. stack_type stack; ///< Stack of visited states on the path.
@ -130,8 +133,20 @@ namespace spot
ce::counter_example* min_ce; ce::counter_example* min_ce;
std::list<ce::counter_example*> l_ce; std::list<ce::counter_example*> l_ce;
int nb_found; int nb_found;
bool mode_;
clock_t tps_; clock_t tps_;
/// \brief Perform the minimal search as explain in
/// @InProceedings(GaMoZe04spin,
/// Author = "Gastin, P. and Moro, P. and Zeitoun, M.",
/// Title = "Minimization of counterexamples in {SPIN}",
/// BookTitle = "Proceedings of the 11th SPIN Workshop (SPIN'04)",
/// Editor = "Graf, S. and Mounier, L.",
/// Publisher = SPRINGER,
/// Series = LNCS,
/// Number = 2989,
/// Year = 2004,
/// Pages = "92-108")
void recurse_find(const state* it, void recurse_find(const state* it,
std::ostringstream& os, std::ostringstream& os,
int mode = normal); int mode = normal);

View file

@ -37,6 +37,7 @@ namespace spot
nested_ = true; nested_ = true;
if (opt == my_nested) if (opt == my_nested)
my_nested_ = true; my_nested_ = true;
Maxsize = 0;
} }
nesteddfs_search::~nesteddfs_search() nesteddfs_search::~nesteddfs_search()
@ -62,13 +63,20 @@ namespace spot
bool bool
nesteddfs_search::push(const state* s, bool m) nesteddfs_search::push(const state* s, bool m)
{ {
/*
if ((Maxsize != 0) && // for minimize
(stack.size() + 1 > Maxsize))
return false;
*/
tgba_succ_iterator* i = a->succ_iter(s); tgba_succ_iterator* i = a->succ_iter(s);
i->first(); i->first();
hash_type::iterator hi = h.find(s); hash_type::iterator hi = h.find(s);
if (hi == h.end()) if (hi == h.end())
{ {
magic d = { !m, m, true }; //magic d = { !m, m, true, stack.size() + 1};
magic d = { !m, m, true, };
h[s] = d; h[s] = d;
} }
else else
@ -76,31 +84,18 @@ namespace spot
hi->second.seen_without |= !m; hi->second.seen_without |= !m;
hi->second.seen_with |= m; hi->second.seen_with |= m;
hi->second.seen_path = true; // for nested search hi->second.seen_path = true; // for nested search
/*
if ((stack.size() + 1) < hi->second.depth) // for minimize
hi->second.depth = stack.size() + 1;
*/
if (hi->first != s) if (hi->first != s)
delete s; delete s;
s = hi->first; s = hi->first;
/*
if (hi->second.depth != -1 &&
hi->second.depth > (int)stack.size())
return false;
*/
} }
magic_state ms = { s, m }; magic_state ms = { s, m };
stack.push_front(state_iter_pair(ms, i)); stack.push_front(state_iter_pair(ms, i));
// We build the counter example.
/*
bdd b = bddfalse;
if (!i->done()) // if the state is dead.
b = i->current_condition();
ce::state_ce ce;
ce = ce::state_ce(s->clone(), b);
counter_->prefix.push_back(ce);
*/
return true; return true;
} }
@ -146,29 +141,6 @@ namespace spot
ce::counter_example* ce::counter_example*
nesteddfs_search::check() nesteddfs_search::check()
{ {
///
hash_type::const_iterator s = h.begin();
while (s != h.end())
{
// Advance the iterator before deleting the "key" pointer.
const state* ptr = s->first;
++s;
delete ptr;
}
if (x)
delete x;
while (!stack.empty())
{
delete stack.front().second;
stack.pop_front();
}
///
//counter_ = new ce::counter_example(a);
clock();
if (my_nested_) if (my_nested_)
{ {
accepted_path_ = false; accepted_path_ = false;
@ -215,8 +187,8 @@ namespace spot
assert(stack.size() == tstack.size()); assert(stack.size() == tstack.size());
build_counter(); build_counter();
//Maxsize = stack.size();
//counter_->build_cycle(x); //counter_->build_cycle(x);
tps_ = clock();
return counter_; return counter_;
} }
if (!has(s_prime, magic)) if (!has(s_prime, magic))
@ -226,9 +198,12 @@ namespace spot
accepted_path_ = true; accepted_path_ = true;
accepted_depth_ = stack.size(); accepted_depth_ = stack.size();
} }
push(s_prime, magic); if (push(s_prime, magic))
tstack.push_front(c); {
goto recurse; tstack.push_front(c);
goto recurse;
}
// for minimize
} }
delete s_prime; delete s_prime;
} }
@ -242,10 +217,6 @@ namespace spot
hi->second.seen_path = false; hi->second.seen_path = false;
} }
stack.pop_front(); stack.pop_front();
/*
delete (counter_->prefix.back()).first;
counter_->prefix.pop_back();
*/
if (!magic && a->state_is_accepting(s)) if (!magic && a->state_is_accepting(s))
{ {
@ -265,9 +236,6 @@ namespace spot
std::cout << "END CHECK" << std::endl; std::cout << "END CHECK" << std::endl;
assert(tstack.empty()); assert(tstack.empty());
//delete counter_;
tps_ = clock();
return 0; return 0;
} }
@ -322,8 +290,7 @@ namespace spot
if (counter_) if (counter_)
ce_size = counter_->size(); ce_size = counter_->size();
os << "Size of Counter Example : " << ce_size << std::endl os << "Size of Counter Example : " << ce_size << std::endl
<< "States explored : " << h.size() << std::endl << "States explored : " << h.size() << std::endl;
<< "Computed time : " << tps_ << " microseconds" << std::endl;
return os; return os;
} }

View file

@ -45,11 +45,11 @@ namespace spot
public: public:
/// Initialize the Nesteddfs Search algorithm on the automaton \a a. /// Initialize the Nesteddfs Search algorithm on the automaton \a a.
nesteddfs_search(const tgba_tba_proxy *a, int opt = my_nested); nesteddfs_search(const tgba_tba_proxy *a, int opt = nested);
virtual ~nesteddfs_search(); virtual ~nesteddfs_search();
/// \brief Perform a Nested DFS Search. /// \brief Perform a Magic or a Nested DFS Search.
/// ///
/// \return true iff the algorithm has found a new accepting /// \return true iff the algorithm has found a new accepting
/// path. /// path.
@ -79,6 +79,7 @@ namespace spot
bool seen_without : 1; bool seen_without : 1;
bool seen_with : 1; bool seen_with : 1;
bool seen_path : 1; bool seen_path : 1;
//unsigned int depth;
}; };
/// \brief A state for the spot::magic_search algorithm. /// \brief A state for the spot::magic_search algorithm.
@ -127,8 +128,9 @@ namespace spot
bool accepted_path_; bool accepted_path_;
int accepted_depth_; int accepted_depth_;
unsigned int Maxsize;
ce::counter_example* counter_; ce::counter_example* counter_;
clock_t tps_;
}; };

View file

@ -562,10 +562,10 @@ namespace spot
} }
} }
simulation_relation* direct_simulation_relation*
parity_game_graph_direct::get_relation() parity_game_graph_direct::get_relation()
{ {
simulation_relation* rel = new simulation_relation(); direct_simulation_relation* rel = new direct_simulation_relation;
state_couple* p = 0; state_couple* p = 0;
seen_map::iterator j; seen_map::iterator j;
@ -611,13 +611,13 @@ namespace spot
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
simulation_relation* direct_simulation_relation*
get_direct_relation_simulation(const tgba* f, get_direct_relation_simulation(const tgba* f,
std::ostream& os, std::ostream& os,
int opt) int opt)
{ {
parity_game_graph_direct* G = new parity_game_graph_direct(f); parity_game_graph_direct* G = new parity_game_graph_direct(f);
simulation_relation* rel = G->get_relation(); direct_simulation_relation* rel = G->get_relation();
if (opt == 1) if (opt == 1)
G->print(os); G->print(os);
delete G; delete G;
@ -625,7 +625,7 @@ namespace spot
} }
void void
free_relation_simulation(simulation_relation* rel) free_relation_simulation(direct_simulation_relation* rel)
{ {
if (rel == 0) if (rel == 0)
return; return;
@ -668,24 +668,26 @@ namespace spot
{ {
spot::tgba_reduc* automatareduc = new spot::tgba_reduc(f); spot::tgba_reduc* automatareduc = new spot::tgba_reduc(f);
if (opt & Reduce_Dir_Sim) if (opt & (Reduce_quotient_Dir_Sim | Reduce_transition_Dir_Sim))
{ {
simulation_relation* rel direct_simulation_relation* rel
= get_direct_relation_simulation(automatareduc, std::cout); = get_direct_relation_simulation(automatareduc, std::cout);
automatareduc->display_rel_sim(rel, std::cout); automatareduc->display_rel_sim(rel, std::cout);
automatareduc->prune_automata(rel); automatareduc->quotient_state(rel);
automatareduc->delete_transitions(rel);
free_relation_simulation(rel); free_relation_simulation(rel);
} }
else else
if (opt & Reduce_Del_Sim) if (opt & (Reduce_quotient_Del_Sim | Reduce_transition_Del_Sim))
{ {
simulation_relation* rel delayed_simulation_relation* rel
= get_delayed_relation_simulation(automatareduc, std::cout); = get_delayed_relation_simulation(automatareduc, std::cout);
automatareduc->display_rel_sim(rel, std::cout); automatareduc->display_rel_sim(rel, std::cout);
automatareduc->prune_automata(rel); automatareduc->quotient_state(rel);
automatareduc->delete_transitions(rel);
free_relation_simulation(rel); free_relation_simulation(rel);
} }

View file

@ -37,12 +37,16 @@ namespace spot
{ {
/// No reduction. /// No reduction.
Reduce_None = 0, Reduce_None = 0,
/// Reduction using direct simulation relation. /// Reduction of state using direct simulation relation.
Reduce_Dir_Sim = 1, Reduce_quotient_Dir_Sim = 1,
/// Reduction using delayed simulation relation. /// Reduction of transitions using direct simulation relation.
Reduce_Del_Sim = 2, Reduce_transition_Dir_Sim = 2,
/// Reduction of state using delayed simulation relation.
Reduce_quotient_Del_Sim = 4,
/// Reduction of transition using delayed simulation relation.
Reduce_transition_Del_Sim = 8,
/// Reduction using SCC. /// Reduction using SCC.
Reduce_Scc = 4, Reduce_Scc = 16,
/// All reductions. /// All reductions.
Reduce_All = -1U Reduce_All = -1U
}; };
@ -57,19 +61,21 @@ namespace spot
tgba* reduc_tgba_sim(const tgba* a, int opt = Reduce_All); tgba* reduc_tgba_sim(const tgba* a, int opt = Reduce_All);
/// \brief Compute a direct simulation relation on state of tgba \a f. /// \brief Compute a direct simulation relation on state of tgba \a f.
simulation_relation* get_direct_relation_simulation(const tgba* a, direct_simulation_relation* get_direct_relation_simulation(const tgba* a,
std::ostream& os, std::ostream& os,
int opt = -1); int opt = -1);
/// Compute a delayed simulation relation on state of tgba \a f. /// Compute a delayed simulation relation on state of tgba \a f.
// FIXME: This method is correct but it builds sometime (when there are more // FIXME: This method is correct but it builds sometime (when there are more
// than one acceptance condition) only a part of the simulation relation. // than one acceptance condition) only a part of the simulation relation.
simulation_relation* get_delayed_relation_simulation(const tgba* a, delayed_simulation_relation* get_delayed_relation_simulation(const tgba* a,
std::ostream& os, std::ostream& os,
int opt = -1); int opt = -1);
/// To free a simulation relation. /// To free a simulation relation.
void free_relation_simulation(simulation_relation* rel); void free_relation_simulation(direct_simulation_relation* rel);
/// To free a simulation relation.
void free_relation_simulation(delayed_simulation_relation* rel);
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
// simulation. // simulation.
@ -185,7 +191,7 @@ namespace spot
parity_game_graph_direct(const tgba* a); parity_game_graph_direct(const tgba* a);
~parity_game_graph_direct(); ~parity_game_graph_direct();
virtual simulation_relation* get_relation(); virtual direct_simulation_relation* get_relation();
protected: protected:
virtual void build_graph(); virtual void build_graph();
@ -282,7 +288,7 @@ namespace spot
parity_game_graph_delayed(const tgba* a); parity_game_graph_delayed(const tgba* a);
~parity_game_graph_delayed(); ~parity_game_graph_delayed();
virtual simulation_relation* get_relation(); virtual delayed_simulation_relation* get_relation();
private: private:

View file

@ -622,15 +622,17 @@ namespace spot
//std::cout << "lift::change = false" << std::endl; //std::cout << "lift::change = false" << std::endl;
} }
simulation_relation* delayed_simulation_relation*
parity_game_graph_delayed::get_relation() parity_game_graph_delayed::get_relation()
{ {
simulation_relation* rel = new simulation_relation(); delayed_simulation_relation* rel = new delayed_simulation_relation;
state_couple* p = 0; state_couple* p = 0;
seen_map::iterator j; seen_map::iterator j;
if (this->nb_set_acc_cond() > 1) /*
if (this->nb_set_acc_cond() > 1)
return rel; return rel;
*/
for (Sgi::vector<spoiler_node*>::iterator i for (Sgi::vector<spoiler_node*>::iterator i
= spoiler_vertice_.begin(); = spoiler_vertice_.begin();
@ -674,15 +676,48 @@ namespace spot
} }
/////////////////////////////////////////// ///////////////////////////////////////////
simulation_relation* delayed_simulation_relation*
get_delayed_relation_simulation(const tgba* f, std::ostream& os, int opt) get_delayed_relation_simulation(const tgba* f, std::ostream& os, int opt)
{ {
parity_game_graph_delayed* G = new parity_game_graph_delayed(f); parity_game_graph_delayed* G = new parity_game_graph_delayed(f);
simulation_relation* rel = G->get_relation(); delayed_simulation_relation* rel = G->get_relation();
if (opt == 1) if (opt == 1)
G->print(os); G->print(os);
delete G; delete G;
return rel; return rel;
} }
void
free_relation_simulation(delayed_simulation_relation* rel)
{
if (rel == 0)
return;
Sgi::hash_map<const spot::state*, int,
state_ptr_hash, state_ptr_equal> seen;
Sgi::hash_map<const spot::state*, int,
state_ptr_hash, state_ptr_equal>::iterator j;
delayed_simulation_relation::iterator i;
for (i = rel->begin(); i != rel->end(); ++i)
{
if ((j = seen.find((*i)->first)) == seen.end())
seen[(*i)->first] = 0;
if ((j = seen.find((*i)->second)) == seen.end())
seen[(*i)->second] = 0;
delete *i;
}
delete rel;
rel = 0;
for (j = seen.begin(); j != seen.end();)
{
const state* ptr = j->first;
++j;
delete ptr;
}
}
} }

View file

@ -35,20 +35,19 @@ namespace spot
for (stack_type::iterator i = stack.begin(); for (stack_type::iterator i = stack.begin();
i != stack.end(); ++i) i != stack.end(); ++i)
{ {
if ((*i).s) //if ((*i).s)
delete (*i).s; delete (*i).s;
if ((*i).lasttr) //if ((*i).lasttr)
delete (*i).lasttr; delete (*i).lasttr;
} }
} }
ce::counter_example* ce::counter_example*
tarjan_on_fly::check() tarjan_on_fly::check()
{ {
std::cout << "tarjan_on_fly::check()" << std::endl; tgba_succ_iterator* iter = 0;
const state* succ = 0;
clock(); int pos = 0;
top = dftop = -1; top = dftop = -1;
violation = false; violation = false;
@ -57,24 +56,20 @@ namespace spot
while (!violation && dftop >= 0) while (!violation && dftop >= 0)
{ {
//std::cout << "iter while" << std::endl;
s = stack[dftop].s; s = stack[dftop].s;
std::cout << "s : " << a->format_state(s) << std::endl; iter = stack[dftop].lasttr;
tgba_succ_iterator* iter = stack[dftop].lasttr;
if (iter == 0) if (iter == 0)
{ {
iter = a->succ_iter(s); iter = a->succ_iter(s);
//std::cout << "iter->first" << std::endl;
iter->first(); iter->first();
stack[dftop].lasttr = iter; stack[dftop].lasttr = iter;
} }
else else
{ {
//std::cout << "iter->next" << std::endl;
iter->next(); iter->next();
} }
const state* succ = 0; succ = 0;
if (!iter->done()) if (!iter->done())
{ {
succ = iter->current_state(); succ = iter->current_state();
@ -82,7 +77,7 @@ namespace spot
push(succ); push(succ);
else else
{ {
int pos = in_stack(succ); pos = in_stack(succ);
delete succ; delete succ;
if (pos != -1) // succ is in stack if (pos != -1) // succ is in stack
lowlinkupdate(dftop, pos); lowlinkupdate(dftop, pos);
@ -92,7 +87,6 @@ namespace spot
pop(); pop();
} }
tps_ = clock();
if (violation) if (violation)
return build_counter(); return build_counter();
@ -104,9 +98,6 @@ namespace spot
void void
tarjan_on_fly::push(const state* s) tarjan_on_fly::push(const state* s)
{ {
std::cout << "tarjan_on_fly::push() : "
<< a->format_state(s) << " : " << std::endl;
h[s] = 1; h[s] = 1;
top++; top++;
@ -122,33 +113,19 @@ namespace spot
else else
ss.acc = -1; ss.acc = -1;
/*
std::cout << " lowlink : " << ss.lowlink << std::endl;
std::cout << " pre : " << ss.pre << std::endl;
std::cout << " acc : " << ss.acc << std::endl;
*/
if (top < (int)stack.size()) if (top < (int)stack.size())
{ {
std::cout << "MAJ" << std::endl;
/*
const state* sdel = stack[top].s; const state* sdel = stack[top].s;
tgba_succ_iterator* iter = stack[top].lasttr; tgba_succ_iterator* iter = stack[top].lasttr;
*/
stack[top] = ss;
/*
delete sdel; delete sdel;
if (iter) if (iter)
delete iter; delete iter;
*/
stack[top] = ss;
} }
else else
{ {
std::cout << "INS" << std::endl;
stack.push_back(ss); stack.push_back(ss);
} }
@ -158,8 +135,6 @@ namespace spot
void void
tarjan_on_fly::pop() tarjan_on_fly::pop()
{ {
std::cout << "tarjan_on_fly::pop()" << std::endl;
int p = stack[dftop].pre; int p = stack[dftop].pre;
if (p >= 0) if (p >= 0)
@ -174,20 +149,11 @@ namespace spot
void void
tarjan_on_fly::lowlinkupdate(int f, int t) tarjan_on_fly::lowlinkupdate(int f, int t)
{ {
/*
std::cout << "tarjan_on_fly::lowlinkupdate() : " << std::endl
<< " stack[t].lowlink : " << stack[t].lowlink
<< " stack[f].lowlink : " << stack[f].lowlink
<< " stack[f].acc : " << stack[f].acc
<< std::endl;
*/
if (stack[t].lowlink <= stack[f].lowlink) if (stack[t].lowlink <= stack[f].lowlink)
{ {
if (stack[t].lowlink <= stack[f].acc) if (stack[t].lowlink <= stack[f].acc)
{ {
violation = true; violation = true;
std::cout << "VIOLATION DETECTED" << std::endl;
} }
stack[f].lowlink = stack[t].lowlink; stack[f].lowlink = stack[t].lowlink;
} }
@ -196,9 +162,6 @@ namespace spot
int int
tarjan_on_fly::in_stack(const state* s) const tarjan_on_fly::in_stack(const state* s) const
{ {
std::cout << "tarjan_on_fly::in_stack() : "
<< a->format_state(s) << std::endl;
int n = 0; int n = 0;
stack_type::const_iterator i; stack_type::const_iterator i;
for (i = stack.begin(); i != stack.end(); ++i, ++n) for (i = stack.begin(); i != stack.end(); ++i, ++n)
@ -214,8 +177,6 @@ namespace spot
ce::counter_example* ce::counter_example*
tarjan_on_fly::build_counter() tarjan_on_fly::build_counter()
{ {
std::cout << "tarjan_on_fly::build_counter()" << std::endl;
ce = new ce::counter_example(a); ce = new ce::counter_example(a);
stack_type::iterator i; stack_type::iterator i;
@ -224,20 +185,14 @@ namespace spot
if (x && x->compare((*i).s) == 0) if (x && x->compare((*i).s) == 0)
break; break;
//os << " " << a->format_state(i->first) << std::endl;
ce->prefix.push_back(ce::state_ce((*i).s->clone(), ce->prefix.push_back(ce::state_ce((*i).s->clone(),
//bddtrue)); (*i).lasttr->current_condition()));
(*i).lasttr->current_condition()));
} }
for (; i != stack.end(); ++i) for (; i != stack.end(); ++i)
{ {
//os << " " << a->format_state(i->first) << std::endl;
ce->cycle.push_back(ce::state_ce((*i).s->clone(), ce->cycle.push_back(ce::state_ce((*i).s->clone(),
//bddtrue)); (*i).lasttr->current_condition()));
(*i).lasttr->current_condition()));
} }
return ce; return ce;
@ -250,8 +205,7 @@ namespace spot
if (ce) if (ce)
ce_size = ce->size(); ce_size = ce->size();
os << "Size of Counter Example : " << ce_size << std::endl os << "Size of Counter Example : " << ce_size << std::endl
<< "States explored : " << h.size() << std::endl << "States explored : " << h.size() << std::endl;
<< "Computed time : " << tps_ << " microseconds" << std::endl;
return os; return os;
} }

View file

@ -85,7 +85,7 @@ namespace spot
int in_stack(const state* s) const; int in_stack(const state* s) const;
ce::counter_example* build_counter(); ce::counter_example* build_counter();
clock_t tps_; //clock_t tps_;
}; };

View file

@ -27,12 +27,15 @@ set -e
expect_ce() expect_ce()
{ {
run 0 ./ltl2tgba -ms -f "$1"
run 0 ./ltl2tgba -m -f "$1" run 0 ./ltl2tgba -m -f "$1"
run 0 ./ltl2tgba -ndfs -f "$1" run 0 ./ltl2tgba -ndfs -f "$1"
#run 0 ./ltl2tgba -ndfs2 -f "$1"
run 0 ./ltl2tgba -tj -f "$1" run 0 ./ltl2tgba -tj -f "$1"
run 0 ./ltl2tgba -c -f "$1" run 0 ./ltl2tgba -c -f "$1"
run 0 ./ltl2tgba -ndfs2 -f "$1"
run 0 ./ltl2tgba -ng -f "$1"
#run 0 ./ltl2tgba -ms -f "$1"
#run 0 ./ltl2tgba -msit -f "$1"
run 0 ./ltl2tgba -e "$1" run 0 ./ltl2tgba -e "$1"
run 0 ./ltl2tgba -e -D "$1" run 0 ./ltl2tgba -e -D "$1"
@ -48,12 +51,14 @@ expect_ce()
expect_no() expect_no()
{ {
run 0 ./ltl2tgba -Ms -f "$1"
run 0 ./ltl2tgba -M -f "$1" run 0 ./ltl2tgba -M -f "$1"
run 0 ./ltl2tgba -Ndfs -f "$1" run 0 ./ltl2tgba -Ndfs -f "$1"
run 0 ./ltl2tgba -Ndfs2 -f "$1"
run 0 ./ltl2tgba -TJ -f "$1" run 0 ./ltl2tgba -TJ -f "$1"
run 0 ./ltl2tgba -C -f "$1" run 0 ./ltl2tgba -C -f "$1"
run 0 ./ltl2tgba -Ndfs2 -f "$1"
run 0 ./ltl2tgba -NG -f "$1"
#run 0 ./ltl2tgba -Ms -f "$1"
run 0 ./ltl2tgba -E "$1" run 0 ./ltl2tgba -E "$1"
run 0 ./ltl2tgba -E -D "$1" run 0 ./ltl2tgba -E -D "$1"
@ -67,8 +72,7 @@ expect_no()
run 0 ./ltl2tgba -M -f "$1" run 0 ./ltl2tgba -M -f "$1"
} }
#expect_no '!((FF a) <=> (F a))' expect_ce 'Fa & Xb & GFc & Gd'
#expect_ce 'Fc & X(a | Xb) & GF(a | Xb) & Gc'
expect_ce 'a' expect_ce 'a'
expect_ce 'a U b' expect_ce 'a U b'

View file

@ -36,6 +36,7 @@
#include "tgba/tgbatba.hh" #include "tgba/tgbatba.hh"
#include "tgbaalgos/magic.hh" #include "tgbaalgos/magic.hh"
#include "tgbaalgos/nesteddfs.hh" #include "tgbaalgos/nesteddfs.hh"
#include "tgbaalgos/nesteddfsgen.hh"
#include "tgbaalgos/colordfs.hh" #include "tgbaalgos/colordfs.hh"
#include "tgbaalgos/tarjan_on_fly.hh" #include "tgbaalgos/tarjan_on_fly.hh"
//#include "tgbaalgos/minimalce.hh" //#include "tgbaalgos/minimalce.hh"
@ -81,12 +82,18 @@ syntax(char* prog)
<< std::endl << std::endl
<< " -ms minmimal-search (implies -D), expect a counter-example" << " -ms minmimal-search (implies -D), expect a counter-example"
<< std::endl << std::endl
<< " -msit minmimal-search (implies -D), expect a counter-example"
<< std::endl
<< " -mold magic-search (implies -D), expect a counter-example" << " -mold magic-search (implies -D), expect a counter-example"
<< std::endl << std::endl
<< " -M magic-search (implies -D), expect no counter-example" << " -M magic-search (implies -D), expect no counter-example"
<< std::endl << std::endl
<< " -Mold magic-search (implies -D), expect no counter-example" << " -Mold magic-search (implies -D), expect no counter-example"
<< std::endl << std::endl
<< " -n same as -m, but display more counter-examples"
<< std::endl
<< " -N display the never clain for Spin "
<< "(implies -D)" << std::endl
<< " -ndfs nesteddfs-search (implies -D), expect a " << " -ndfs nesteddfs-search (implies -D), expect a "
<< "counter-example" << "counter-example"
<< std::endl << std::endl
@ -99,10 +106,12 @@ syntax(char* prog)
<< " -Ndfs2 modify-nesteddfs-search (implies -D), " << " -Ndfs2 modify-nesteddfs-search (implies -D), "
<< "expect no counter-example" << "expect no counter-example"
<< std::endl << std::endl
<< " -n same as -m, but display more counter-examples" << " -ng nesteddfs-search generalized (implies -D), expect a "
<< "counter-example"
<< std::endl
<< " -NG nesteddfs-search generalized (implies -D), expect no "
<< "counter-example"
<< std::endl << std::endl
<< " -N display the never clain for Spin "
<< "(implies -D)" << std::endl
<< " -p branching postponement (implies -f)" << std::endl << " -p branching postponement (implies -f)" << std::endl
<< " -r display the relation BDD, not the reachability graph" << " -r display the relation BDD, not the reachability graph"
<< std::endl << std::endl
@ -114,12 +123,18 @@ syntax(char* prog)
<< " -r4 reduce formula using all rules" << std::endl << " -r4 reduce formula using all rules" << std::endl
<< " -rd display the reduce formula" << std::endl << " -rd display the reduce formula" << std::endl
<< " -R same as -r, but as a set" << std::endl << " -R same as -r, but as a set" << std::endl
<< " -R1 use direct simulation to reduce the automata " << " -R1q use direct simulation to merge some state "
<< "(use -L for more reduction)" << "(use -L for more reduction)"
<< std::endl << std::endl
<< " -R2 use delayed simulation to reduce the automata " << " -R1t use direct simulation to remove some transition "
<< "(use -L for more reduction)" << "(use -L for more reduction)"
<< std::endl << std::endl
<< " -R2q use delayed simulation to merge some state "
<< "(the automaton must be degeneralised)"
<< std::endl
<< " -R2t use delayed simulation to remove some transition "
<< "(the automaton must be degeneralised)"
<< std::endl
<< " -R3 use SCC to reduce the automata" << " -R3 use SCC to reduce the automata"
<< std::endl << std::endl
<< " -Rd display the simulation relation" << " -Rd display the simulation relation"
@ -163,9 +178,9 @@ main(int argc, char** argv)
int formula_index = 0; int formula_index = 0;
enum { None, Couvreur, Couvreur2, MagicSearch, MagicSearchOld, enum { None, Couvreur, Couvreur2, MagicSearch, MagicSearchOld,
NestedDFSSearch, NestedDFSSearchModify, ColorDFSSearch, NestedDFSSearch, NestedDFSSearchModify, ColorDFSSearch,
TarjanOnFly, MinimalSearch} echeck = None; TarjanOnFly, MinimalSearch, MinimalSearchIterative,
NestedGeneSearch} echeck = None;
spot::emptyness_search* es = 0; spot::emptyness_search* es = 0;
//int opt_search = 0; //FIXME
spot::search_opt opt_nested_search = spot::magic; spot::search_opt opt_nested_search = spot::magic;
enum { NoneDup, BFS, DFS } dupexp = NoneDup; enum { NoneDup, BFS, DFS } dupexp = NoneDup;
bool magic_many = false; bool magic_many = false;
@ -197,7 +212,6 @@ main(int argc, char** argv)
else if (!strcmp(argv[formula_index], "-c")) else if (!strcmp(argv[formula_index], "-c"))
{ {
echeck = ColorDFSSearch; echeck = ColorDFSSearch;
//opt_search = 0;
degeneralize_opt = true; degeneralize_opt = true;
expect_counter_example = true; expect_counter_example = true;
output = -1; output = -1;
@ -255,37 +269,14 @@ main(int argc, char** argv)
fair_loop_approx = true; fair_loop_approx = true;
fm_opt = true; fm_opt = true;
} }
else if (!strcmp(argv[formula_index], "-mold"))
{
echeck = MagicSearchOld;
//opt_search = 0;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
}
else if (!strcmp(argv[formula_index], "-m")) else if (!strcmp(argv[formula_index], "-m"))
{ {
opt_nested_search = spot::magic; opt_nested_search = spot::magic;
echeck = MagicSearch; echeck = MagicSearch;
//opt_search = 0;
degeneralize_opt = true; degeneralize_opt = true;
expect_counter_example = true; expect_counter_example = true;
output = -1; output = -1;
//magic_many = true; magic_many = true;
}
else if (!strcmp(argv[formula_index], "-ms"))
{
echeck = MinimalSearch;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
}
else if (!strcmp(argv[formula_index], "-Mold"))
{
echeck = MagicSearchOld; // FIXME
degeneralize_opt = true;
expect_counter_example = false;
output = -1;
} }
else if (!strcmp(argv[formula_index], "-M")) else if (!strcmp(argv[formula_index], "-M"))
{ {
@ -295,6 +286,28 @@ main(int argc, char** argv)
expect_counter_example = false; expect_counter_example = false;
output = -1; output = -1;
} }
else if (!strcmp(argv[formula_index], "-mold"))
{
echeck = MagicSearchOld;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
magic_many = true;
}
else if (!strcmp(argv[formula_index], "-Mold"))
{
echeck = MagicSearchOld;
degeneralize_opt = true;
expect_counter_example = false;
output = -1;
}
else if (!strcmp(argv[formula_index], "-ms"))
{
echeck = MinimalSearch;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
}
else if (!strcmp(argv[formula_index], "-Ms")) else if (!strcmp(argv[formula_index], "-Ms"))
{ {
echeck = MinimalSearch; echeck = MinimalSearch;
@ -302,40 +315,12 @@ main(int argc, char** argv)
expect_counter_example = false; expect_counter_example = false;
output = -1; output = -1;
} }
else if (!strcmp(argv[formula_index], "-ndfs")) else if (!strcmp(argv[formula_index], "-msit"))
{ {
opt_nested_search = spot::nested; echeck = MinimalSearchIterative;
echeck = NestedDFSSearch;
//opt_search = 1;
degeneralize_opt = true; degeneralize_opt = true;
expect_counter_example = true; expect_counter_example = true;
output = -1; magic_many = true;
}
else if (!strcmp(argv[formula_index], "-Ndfs"))
{
opt_nested_search = spot::nested;
echeck = NestedDFSSearch;
//opt_search = 1;
degeneralize_opt = true;
expect_counter_example = false;
output = -1;
}
else if (!strcmp(argv[formula_index], "-ndfs2"))
{
opt_nested_search = spot::my_nested;
echeck = NestedDFSSearchModify;
//opt_search = 2;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
}
else if (!strcmp(argv[formula_index], "-Ndfs2"))
{
opt_nested_search = spot::my_nested;
echeck = NestedDFSSearchModify;
//opt_search = 2;
degeneralize_opt = true;
expect_counter_example = false;
output = -1; output = -1;
} }
else if (!strcmp(argv[formula_index], "-n")) else if (!strcmp(argv[formula_index], "-n"))
@ -351,6 +336,53 @@ main(int argc, char** argv)
degeneralize_opt = true; degeneralize_opt = true;
output = 8; output = 8;
} }
else if (!strcmp(argv[formula_index], "-ndfs"))
{
opt_nested_search = spot::nested;
echeck = NestedDFSSearch;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
magic_many = true;
}
else if (!strcmp(argv[formula_index], "-Ndfs"))
{
opt_nested_search = spot::nested;
echeck = NestedDFSSearch;
degeneralize_opt = true;
expect_counter_example = false;
output = -1;
}
else if (!strcmp(argv[formula_index], "-ndfs2"))
{
opt_nested_search = spot::my_nested;
echeck = NestedDFSSearchModify;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
}
else if (!strcmp(argv[formula_index], "-Ndfs2"))
{
opt_nested_search = spot::my_nested;
echeck = NestedDFSSearchModify;
degeneralize_opt = true;
expect_counter_example = false;
output = -1;
}
else if (!strcmp(argv[formula_index], "-ng"))
{
echeck = NestedGeneSearch;
degeneralize_opt = true;
expect_counter_example = true;
output = -1;
}
else if (!strcmp(argv[formula_index], "-NG"))
{
echeck = NestedGeneSearch;
degeneralize_opt = true;
expect_counter_example = false;
output = -1;
}
else if (!strcmp(argv[formula_index], "-p")) else if (!strcmp(argv[formula_index], "-p"))
{ {
post_branching = true; post_branching = true;
@ -380,15 +412,21 @@ main(int argc, char** argv)
{ {
output = 3; output = 3;
} }
else if (!strcmp(argv[formula_index], "-R1")) else if (!strcmp(argv[formula_index], "-R1q"))
{ {
//degeneralize_opt = true; // FIXME reduc_aut |= spot::Reduce_quotient_Dir_Sim;
reduc_aut |= spot::Reduce_Dir_Sim;
} }
else if (!strcmp(argv[formula_index], "-R2")) else if (!strcmp(argv[formula_index], "-R1t"))
{ {
//degeneralize_opt = true; // FIXME reduc_aut |= spot::Reduce_transition_Dir_Sim;
reduc_aut |= spot::Reduce_Del_Sim; }
else if (!strcmp(argv[formula_index], "-R2q"))
{
reduc_aut |= spot::Reduce_quotient_Del_Sim;
}
else if (!strcmp(argv[formula_index], "-R2t"))
{
reduc_aut |= spot::Reduce_transition_Del_Sim;
} }
else if (!strcmp(argv[formula_index], "-R3")) else if (!strcmp(argv[formula_index], "-R3"))
{ {
@ -542,36 +580,46 @@ main(int argc, char** argv)
if (reduc_aut & spot::Reduce_Scc) if (reduc_aut & spot::Reduce_Scc)
aut_red->prune_scc(); aut_red->prune_scc();
if ((reduc_aut & spot::Reduce_Dir_Sim) || if (reduc_aut & (spot::Reduce_quotient_Dir_Sim |
(reduc_aut & spot::Reduce_Del_Sim)) spot::Reduce_transition_Dir_Sim |
spot::Reduce_quotient_Del_Sim |
spot::Reduce_transition_Del_Sim))
{ {
spot::simulation_relation* rel; spot::direct_simulation_relation* rel_dir = 0;
if (reduc_aut & spot::Reduce_Dir_Sim) spot::delayed_simulation_relation* rel_del = 0;
rel = spot::get_direct_relation_simulation(a,
std::cout, if (reduc_aut & (spot::Reduce_quotient_Dir_Sim |
display_parity_game); spot::Reduce_transition_Dir_Sim))
else if (reduc_aut & spot::Reduce_Del_Sim) rel_dir = spot::get_direct_relation_simulation(a,
rel = spot::get_delayed_relation_simulation(a, std::cout,
std::cout, display_parity_game);
display_parity_game); else if (reduc_aut & (spot::Reduce_quotient_Del_Sim |
else spot::Reduce_transition_Del_Sim))
{ rel_del = spot::get_delayed_relation_simulation(a,
assert(0); std::cout,
// Please GCC so it does not think REL is unused. display_parity_game);
rel = 0;
}
if (display_rel_sim) if (display_rel_sim)
aut_red->display_rel_sim(rel, std::cout); {
if (rel_dir)
aut_red->display_rel_sim(rel_dir, std::cout);
if (rel_del)
aut_red->display_rel_sim(rel_del, std::cout);
}
if (reduc_aut & spot::Reduce_Dir_Sim) if (reduc_aut & spot::Reduce_quotient_Dir_Sim)
aut_red->prune_automata(rel); aut_red->quotient_state(rel_dir);
else if (reduc_aut & spot::Reduce_Del_Sim) if (reduc_aut & spot::Reduce_transition_Dir_Sim)
aut_red->quotient_state(rel); aut_red->delete_transitions(rel_dir);
else if (reduc_aut & spot::Reduce_quotient_Del_Sim)
assert(0); aut_red->quotient_state(rel_del);
if (reduc_aut & spot::Reduce_transition_Del_Sim)
aut_red->delete_transitions(rel_del);
spot::free_relation_simulation(rel); if (rel_dir)
spot::free_relation_simulation(rel_dir);
if (rel_del)
spot::free_relation_simulation(rel_del);
} }
} }
@ -639,6 +687,7 @@ main(int argc, char** argv)
case Couvreur: case Couvreur:
case Couvreur2: case Couvreur2:
{ {
std::cout << "Tarjan Couvreur" << std::endl;
spot::emptiness_check* ec; spot::emptiness_check* ec;
if (echeck == Couvreur) if (echeck == Couvreur)
ec = new spot::emptiness_check(a); ec = new spot::emptiness_check(a);
@ -654,12 +703,16 @@ main(int argc, char** argv)
break; break;
} }
spot::counter_example ce(ec->result()); spot::counter_example ce(ec->result());
//ce.print_result(std::cout); ce.print_result(std::cout);
spot::ce::counter_example* res2 = ce.get_counter_example(); ce.print_stats(std::cout);
spot::tgba* aut = res2->ce2tgba();
spot::dotty_reachable(std::cout, aut); //spot::ce::counter_example* res2 = ce.get_counter_example();
delete res2; //spot::tgba* aut = res2->ce2tgba();
delete aut; //spot::dotty_reachable(std::cout, aut);
//res2->print(std::cout);
//delete res2;
//delete aut;
} }
else else
{ {
@ -669,8 +722,28 @@ main(int argc, char** argv)
} }
break; break;
case NestedGeneSearch:
{
std::cout << "Nested DFS generalized" << std::endl;
spot::nesteddfsgen_search* ec = new spot::nesteddfsgen_search(a);
bool res = ec->check();
ec->print_stats(std::cout);
if (expect_counter_example)
{
if (!res)
exit_code = 1;
}
else
{
exit_code = res;
}
delete ec;
}
break;
case MagicSearchOld: case MagicSearchOld:
{ {
std::cout << "Magic Search" << std::endl;
spot::magic_search ms(degeneralized); spot::magic_search ms(degeneralized);
bool res = ms.check(); bool res = ms.check();
if (expect_counter_example) if (expect_counter_example)
@ -692,23 +765,46 @@ main(int argc, char** argv)
break; break;
case ColorDFSSearch: case ColorDFSSearch:
std::cout << "Colored Search" << std::endl;
es = new spot::colordfs_search(degeneralized); es = new spot::colordfs_search(degeneralized);
break; break;
case TarjanOnFly: case TarjanOnFly:
std::cout << "Tarjan On Fly" << std::endl;
es = new spot::tarjan_on_fly(degeneralized); es = new spot::tarjan_on_fly(degeneralized);
break; break;
case MinimalSearch: case MinimalSearch:
es = new spot::minimalce_search(degeneralized); {
std::cout << "Recursive Minimal Search" << std::endl;
es = new spot::colordfs_search(degeneralized);
spot::ce::counter_example* res = es->check();
res->print(std::cout);
std::cout << "Minimisation:" << std::endl;
es = new spot::minimalce_search(degeneralized, false);
res = es->check();
res->print(std::cout);
}
break;
case MinimalSearchIterative:
std::cout << "Iterative Minimal Search" << std::endl;
es = new spot::minimalce_search(degeneralized, true);
break; break;
case MagicSearch: case MagicSearch:
case NestedDFSSearch: std::cout << "Magic Search" << std::endl;
case NestedDFSSearchModify:
es = new spot::nesteddfs_search(degeneralized, opt_nested_search); es = new spot::nesteddfs_search(degeneralized, opt_nested_search);
break; break;
case NestedDFSSearch:
case NestedDFSSearchModify:
std::cout << "Nested DFS" << std::endl;
es = new spot::nesteddfs_search(degeneralized, opt_nested_search);
break;
default:
assert(0);
} }
if (es) if (es)
@ -750,6 +846,7 @@ main(int argc, char** argv)
delete res; delete res;
} }
if (es) if (es)
delete es; delete es;
if (f) if (f)

View file

@ -66,18 +66,28 @@ main(int argc, char** argv)
o = spot::Reduce_Scc; o = spot::Reduce_Scc;
break; break;
case 1: case 1:
o = spot::Reduce_Dir_Sim; o = spot::Reduce_quotient_Dir_Sim;
break; break;
case 2: case 2:
o = spot::Reduce_Del_Sim; o = spot::Reduce_transition_Dir_Sim;
break; break;
case 3: case 3:
o = spot::Reduce_Dir_Sim | spot::Reduce_Scc; o = spot::Reduce_quotient_Del_Sim;
break; break;
case 4: case 4:
o = spot::Reduce_Del_Sim | spot::Reduce_Scc; o = spot::Reduce_transition_Del_Sim;
break; break;
case 5: case 5:
o = spot::Reduce_quotient_Dir_Sim |
spot::Reduce_transition_Dir_Sim |
spot::Reduce_Scc;
break;
case 6:
o = spot::Reduce_quotient_Del_Sim |
spot::Reduce_transition_Del_Sim |
spot::Reduce_Scc;
break;
case 7:
// No Reduction // No Reduction
break; break;
default: default:
@ -85,7 +95,8 @@ main(int argc, char** argv)
} }
int exit_code = 0; int exit_code = 0;
spot::simulation_relation* rel = 0; spot::direct_simulation_relation* rel_dir = 0;
spot::delayed_simulation_relation* rel_del = 0;
spot::tgba* automata = 0; spot::tgba* automata = 0;
spot::tgba_reduc* automatareduc = 0; spot::tgba_reduc* automatareduc = 0;
@ -110,21 +121,30 @@ main(int argc, char** argv)
spot::dotty_reachable(std::cout, automata); spot::dotty_reachable(std::cout, automata);
automatareduc = new spot::tgba_reduc(automata); automatareduc = new spot::tgba_reduc(automata);
if (o & spot::Reduce_Dir_Sim) if (o & spot::Reduce_quotient_Dir_Sim)
{ {
rel = spot::get_direct_relation_simulation(automatareduc, std::cout); rel_dir = spot::get_direct_relation_simulation(automatareduc, std::cout);
automatareduc->prune_automata(rel); automatareduc->quotient_state(rel_dir);
} }
else if (o & spot::Reduce_Del_Sim) else if (o & spot::Reduce_quotient_Del_Sim)
{ {
rel = spot::get_delayed_relation_simulation(automatareduc, std::cout); std::cout << "get delayed" << std::endl;
automatareduc->quotient_state(rel); rel_del = spot::get_delayed_relation_simulation(automatareduc, std::cout);
std::cout << "quotient state" << std::endl;
automatareduc->quotient_state(rel_del);
std::cout << "end" << std::endl;
} }
if (rel != 0) if (rel_dir != 0)
{ {
automatareduc->display_rel_sim(rel, std::cout); automatareduc->display_rel_sim(rel_dir, std::cout);
spot::free_relation_simulation(rel); spot::free_relation_simulation(rel_dir);
}
if (rel_del != 0)
{
automatareduc->display_rel_sim(rel_del, std::cout);
spot::free_relation_simulation(rel_del);
} }
if (o & spot::Reduce_Scc) if (o & spot::Reduce_Scc)

View file

@ -104,7 +104,7 @@ Algorithm
{ {
Name = "Spot (Couvreur -- FM), post reduction with direct simulation" Name = "Spot (Couvreur -- FM), post reduction with direct simulation"
Path = "${LBTT_TRANSLATE}" Path = "${LBTT_TRANSLATE}"
Parameters = "--spot './ltl2tgba -R1 -F -f -t'" Parameters = "--spot './ltl2tgba -R1q -R1t -F -f -t'"
Enabled = yes Enabled = yes
} }
@ -112,7 +112,7 @@ Algorithm
{ {
Name = "Spot (Couvreur -- FM), post reduction with delayed simulation" Name = "Spot (Couvreur -- FM), post reduction with delayed simulation"
Path = "${LBTT_TRANSLATE}" Path = "${LBTT_TRANSLATE}"
Parameters = "--spot './ltl2tgba -R2 -F -f -t'" Parameters = "--spot './ltl2tgba -R2q -R2t -F -f -t'"
Enabled = yes Enabled = yes
} }
@ -128,7 +128,7 @@ Algorithm
{ {
Name = "Spot (Couvreur -- FM), pre + post reduction" Name = "Spot (Couvreur -- FM), pre + post reduction"
Path = "${LBTT_TRANSLATE}" Path = "${LBTT_TRANSLATE}"
Parameters = "--spot './ltl2tgba -r4 -R1 -R3 -F -f -t'" Parameters = "--spot './ltl2tgba -r4 -R1q -R1t -R3 -F -f -t'"
Enabled = yes Enabled = yes
} }