Remove the old broken game-theory-based simulation reductions.
This implementation of direct simulation was only working on degeneralized automata, and produce automata that are inferiors to those output by the new direct simulation implementation (in tgba/simulation.hh) which can also work on TGBA. The delayed simulation has never been reliable. It's time for some spring cleaning. * src/tgba/tgbareduc.hh, src/tgba/tgbareduc.cc: Delete. * src/tgba/Makefile.am: Adjust. * src/tgbaalgos/reductgba_sim.cc, src/tgbaalgos/reductgba_sim.hh: Remove all code, and keep only a deprecated replacement from reduc_tgba_sim(). * src/tgbaalgos/reductgba_sim_del.cc: Delete. * src/tgbaalgos/Makefile.am: Adjust. * src/tgbatest/reduccmp.test, src/tgbatest/reductgba.cc, src/tgbatest/reductgba.test: Delete. * src/tgbatest/Makefile.am: Adjust. * src/tgbatest/ltl2tgba.cc: Undocument options -R1s, -R1t, -R2s, -R2t, and implement them using the new direct simulation. Remove options -Rd and -RD. * src/tgbatest/spotlbtt.test: Remove entry using these old options. * wrap/python/spot.i: Do not process tgbaalgos/reductgba_sim.cc.
This commit is contained in:
parent
7ba4ab7931
commit
7e5875845a
14 changed files with 69 additions and 2713 deletions
|
|
@ -1,8 +1,9 @@
|
|||
## Copyright (C) 2008, 2009, 2010, 2011 Laboratoire de Recherche et
|
||||
## Développement de l'Epita (LRDE).
|
||||
## -*- coding: utf-8 -*-
|
||||
## Copyright (C) 2008, 2009, 2010, 2011, 2012 Laboratoire de Recherche
|
||||
## et Développement de l'Epita (LRDE).
|
||||
## Copyright (C) 2003, 2004, 2005 Laboratoire d'Informatique de Paris
|
||||
## 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
## Université Pierre et Marie Curie.
|
||||
## 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
## Université Pierre et Marie Curie.
|
||||
##
|
||||
## This file is part of Spot, a model checking library.
|
||||
##
|
||||
|
|
@ -99,7 +100,6 @@ libtgbaalgos_la_SOURCES = \
|
|||
tau03.cc \
|
||||
tau03opt.cc \
|
||||
reductgba_sim.cc \
|
||||
reductgba_sim_del.cc \
|
||||
weight.cc
|
||||
|
||||
libtgbaalgos_la_LIBADD = gtec/libgtec.la
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2009, 2011 Laboratoire de Recherche et Développement
|
||||
// Copyright (C) 2009, 2011, 2012 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2004, 2005, 2007 Laboratoire d'Informatique de
|
||||
// Paris 6 (LIP6), département Systèmes Répartis Coopératifs (SRC),
|
||||
|
|
@ -22,633 +22,12 @@
|
|||
// 02111-1307, USA.
|
||||
|
||||
#include "reductgba_sim.hh"
|
||||
#include "tgba/bddprint.hh"
|
||||
#include "sccfilter.hh"
|
||||
#include "simulation.hh"
|
||||
#include "dupexp.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spoiler_node
|
||||
|
||||
spoiler_node::spoiler_node(const state* d_node,
|
||||
const state* s_node,
|
||||
int num)
|
||||
{
|
||||
num_ = num;
|
||||
sc_ = new state_couple(d_node, s_node);
|
||||
lnode_succ = new sn_v;
|
||||
lnode_pred = new sn_v;
|
||||
not_win = false;
|
||||
}
|
||||
|
||||
spoiler_node::~spoiler_node()
|
||||
{
|
||||
lnode_succ->clear();
|
||||
lnode_pred->clear();
|
||||
delete lnode_succ;
|
||||
delete lnode_pred;
|
||||
delete sc_;
|
||||
}
|
||||
|
||||
bool
|
||||
spoiler_node::add_succ(spoiler_node* n)
|
||||
{
|
||||
bool exist = false;
|
||||
for (sn_v::iterator i = lnode_succ->begin();
|
||||
i != lnode_succ->end(); ++i)
|
||||
if ((*i == n) ||
|
||||
((*i)->compare(n) == true))
|
||||
exist = true;
|
||||
if (exist)
|
||||
return false;
|
||||
|
||||
lnode_succ->push_back(n);
|
||||
n->add_pred(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
spoiler_node::del_succ(spoiler_node* n)
|
||||
{
|
||||
for (sn_v::iterator i = lnode_succ->begin();
|
||||
i != lnode_succ->end();)
|
||||
{
|
||||
if (*i == n)
|
||||
{
|
||||
i = lnode_succ->erase(i);
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
spoiler_node::add_pred(spoiler_node* n)
|
||||
{
|
||||
lnode_pred->push_back(n);
|
||||
}
|
||||
|
||||
void
|
||||
spoiler_node::del_pred()
|
||||
{
|
||||
for (sn_v::iterator i = lnode_pred->begin();
|
||||
i != lnode_pred->end(); ++i)
|
||||
(*i)->del_succ(this);
|
||||
}
|
||||
|
||||
bool
|
||||
spoiler_node::set_win()
|
||||
{
|
||||
bool change = not_win;
|
||||
for (std::vector<spoiler_node*>::iterator i = lnode_succ->begin();
|
||||
i != lnode_succ->end(); ++i)
|
||||
{
|
||||
not_win |= (*i)->not_win;
|
||||
}
|
||||
if (change != not_win)
|
||||
for (std::vector<spoiler_node*>::iterator i = lnode_pred->begin();
|
||||
i != lnode_pred->end(); ++i)
|
||||
(*i)->set_win();
|
||||
|
||||
return change != not_win;
|
||||
}
|
||||
|
||||
std::string
|
||||
spoiler_node::to_string(const tgba* a)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << num_
|
||||
<< " [shape=box, label=\"("
|
||||
<< a->format_state(sc_->first)
|
||||
<< ", "
|
||||
<< a->format_state(sc_->second)
|
||||
<< ")\"]"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
std::string
|
||||
spoiler_node::succ_to_string()
|
||||
{
|
||||
std::ostringstream os;
|
||||
sn_v::iterator i;
|
||||
for (i = lnode_succ->begin(); i != lnode_succ->end(); ++i)
|
||||
{
|
||||
os << num_ << " -> " << (*i)->num_ << std::endl;
|
||||
}
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
spoiler_node::compare(spoiler_node* n)
|
||||
{
|
||||
return (((sc_->first)->compare((n->get_pair())->first) == 0) &&
|
||||
((sc_->second)->compare((n->get_pair())->second) == 0));
|
||||
}
|
||||
|
||||
int
|
||||
spoiler_node::get_nb_succ()
|
||||
{
|
||||
return lnode_succ->size();
|
||||
}
|
||||
|
||||
const state*
|
||||
spoiler_node::get_spoiler_node()
|
||||
{
|
||||
return sc_->first;
|
||||
}
|
||||
|
||||
const state*
|
||||
spoiler_node::get_duplicator_node()
|
||||
{
|
||||
return sc_->second;
|
||||
}
|
||||
|
||||
state_couple*
|
||||
spoiler_node::get_pair()
|
||||
{
|
||||
return sc_;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// duplicator_node
|
||||
|
||||
duplicator_node::duplicator_node(const state* d_node,
|
||||
const state* s_node,
|
||||
bdd l,
|
||||
bdd a,
|
||||
int num)
|
||||
: spoiler_node(d_node, s_node, num),
|
||||
label_(l),
|
||||
acc_(a)
|
||||
{
|
||||
}
|
||||
|
||||
duplicator_node::~duplicator_node()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node::set_win()
|
||||
{
|
||||
bool change = not_win;
|
||||
|
||||
if (!this->get_nb_succ())
|
||||
not_win = true;
|
||||
else
|
||||
{
|
||||
not_win = true;
|
||||
for (std::vector<spoiler_node*>::iterator i = lnode_succ->begin();
|
||||
i != lnode_succ->end(); ++i)
|
||||
{
|
||||
not_win &= (*i)->not_win;
|
||||
}
|
||||
}
|
||||
if (change != not_win)
|
||||
for (std::vector<spoiler_node*>::iterator i = lnode_pred->begin();
|
||||
i != lnode_pred->end(); ++i)
|
||||
(*i)->set_win();
|
||||
|
||||
return change != not_win;
|
||||
}
|
||||
|
||||
std::string
|
||||
duplicator_node::to_string(const tgba* a)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << num_
|
||||
<< " [shape=box, label=\"("
|
||||
<< a->format_state(sc_->first)
|
||||
<< ", "
|
||||
<< a->format_state(sc_->second)
|
||||
<< ", ";
|
||||
bdd_print_acc(os, a->get_dict(), label_);
|
||||
os << ", ";
|
||||
bdd_print_acc(os, a->get_dict(), acc_);
|
||||
os << ")\"]"
|
||||
<< std::endl;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node::compare(spoiler_node* n)
|
||||
{
|
||||
return (this->spoiler_node::compare(n) &&
|
||||
(label_ == static_cast<duplicator_node*>(n)->get_label()) &&
|
||||
(acc_ == static_cast<duplicator_node*>(n)->get_acc()));
|
||||
}
|
||||
|
||||
bdd
|
||||
duplicator_node::get_label() const
|
||||
{
|
||||
return label_;
|
||||
}
|
||||
|
||||
bdd
|
||||
duplicator_node::get_acc() const
|
||||
{
|
||||
return acc_;
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node::match(bdd l, bdd a)
|
||||
{
|
||||
return ((l == label_) && (a == acc_));
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node::implies(bdd l, bdd a)
|
||||
{
|
||||
// if (a | !b) == true then (a => b).
|
||||
return (((l | !label_) == bddtrue) &&
|
||||
((a | !acc_) == bddtrue));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// parity_game_graph
|
||||
|
||||
void
|
||||
parity_game_graph::process_state(const state* s,
|
||||
int,
|
||||
tgba_succ_iterator*)
|
||||
{
|
||||
tgba_state_.push_back(s);
|
||||
}
|
||||
|
||||
void
|
||||
parity_game_graph::print(std::ostream& os)
|
||||
{
|
||||
std::vector<spoiler_node*>::iterator i1;
|
||||
std::vector<duplicator_node*>::iterator i2;
|
||||
|
||||
int n = 0;
|
||||
|
||||
os << "digraph G {" << std::endl;
|
||||
|
||||
os << "{" << std::endl
|
||||
<< "rank = same;" << std::endl
|
||||
<< "node [color=red];" << std::endl;
|
||||
for (i1 = spoiler_vertice_.begin();
|
||||
i1 != spoiler_vertice_.end(); ++i1)
|
||||
{
|
||||
os << (*i1)->to_string(aut_);
|
||||
++n;
|
||||
if (n > 20)
|
||||
{
|
||||
n = 0;
|
||||
os << "}" << std::endl << std::endl
|
||||
<< "{" << std::endl
|
||||
<< "rank = same" << std::endl
|
||||
<< "node [color=red];" << std::endl;
|
||||
}
|
||||
}
|
||||
os << "}" << std::endl;
|
||||
|
||||
n = 0;
|
||||
os << "{" << std::endl
|
||||
<< "rank = same;" << std::endl
|
||||
<< "node [color=green];" << std::endl;
|
||||
for (i2 = duplicator_vertice_.begin();
|
||||
i2 != duplicator_vertice_.end(); ++i2)
|
||||
{
|
||||
os << (*i2)->to_string(aut_);
|
||||
++n;
|
||||
if (n > 20)
|
||||
{
|
||||
n = 0;
|
||||
os << "}" << std::endl << std::endl
|
||||
<< "{" << std::endl
|
||||
<< "rank = same" << std::endl
|
||||
<< "node [color=green];" << std::endl;
|
||||
}
|
||||
}
|
||||
os << "}" << std::endl << std::endl;
|
||||
|
||||
os << "edge [color=red];" << std::endl;
|
||||
for (i1 = spoiler_vertice_.begin();
|
||||
i1 != spoiler_vertice_.end(); ++i1)
|
||||
{
|
||||
os << (*i1)->succ_to_string();
|
||||
}
|
||||
|
||||
os << std::endl
|
||||
<< "edge [color=green];" << std::endl;
|
||||
for (i2 = duplicator_vertice_.begin();
|
||||
i2 != duplicator_vertice_.end(); ++i2)
|
||||
{
|
||||
os << (*i2)->succ_to_string();
|
||||
}
|
||||
|
||||
os << "}" << std::endl;
|
||||
|
||||
}
|
||||
|
||||
parity_game_graph::~parity_game_graph()
|
||||
{
|
||||
std::vector<spoiler_node*>::iterator i1;
|
||||
std::vector<duplicator_node*>::iterator i2;
|
||||
|
||||
for (i1 = spoiler_vertice_.begin();
|
||||
i1 != spoiler_vertice_.end(); ++i1)
|
||||
{
|
||||
delete *i1;
|
||||
}
|
||||
|
||||
for (i2 = duplicator_vertice_.begin();
|
||||
i2 != duplicator_vertice_.end(); ++i2)
|
||||
{
|
||||
delete *i2;
|
||||
}
|
||||
|
||||
spoiler_vertice_.clear();
|
||||
duplicator_vertice_.clear();
|
||||
}
|
||||
|
||||
parity_game_graph::parity_game_graph(const tgba* a)
|
||||
: tgba_reachable_iterator_breadth_first(a)
|
||||
{
|
||||
this->run();
|
||||
nb_node_parity_game = 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// parity_game_graph_direct
|
||||
|
||||
void
|
||||
parity_game_graph_direct::build_graph()
|
||||
{
|
||||
tgba_succ_iterator* si = 0;
|
||||
typedef std::pair<bdd, bdd> couple_bdd;
|
||||
couple_bdd *p = 0;
|
||||
std::vector<couple_bdd*>* trans = 0;
|
||||
bool exist = false;
|
||||
spot::state* s = 0;
|
||||
|
||||
for (std::vector<const state*>::iterator i = tgba_state_.begin();
|
||||
i != tgba_state_.end(); ++i)
|
||||
{
|
||||
|
||||
// spoiler node are all state couple (i,j)
|
||||
for (std::vector<const state*>::iterator j = tgba_state_.begin();
|
||||
j != tgba_state_.end(); ++j)
|
||||
{
|
||||
spoiler_node* n1 = new spoiler_node(*i,
|
||||
*j,
|
||||
nb_node_parity_game++);
|
||||
spoiler_vertice_.push_back(n1);
|
||||
}
|
||||
|
||||
// duplicator node are all state couple where
|
||||
// the first state i are reachable.
|
||||
trans = new std::vector<couple_bdd*>;
|
||||
for (std::vector<const state*>::iterator j = tgba_state_.begin();
|
||||
j != tgba_state_.end(); ++j)
|
||||
{
|
||||
si = aut_->succ_iter(*j);
|
||||
for (si->first(); !si->done(); si->next())
|
||||
{
|
||||
|
||||
// if there exist a predecessor of i named j
|
||||
s = si->current_state();
|
||||
if (s->compare(*i) == 0)
|
||||
{
|
||||
|
||||
// p is the label of the transition j->i
|
||||
p = new couple_bdd(si->current_condition(),
|
||||
si->current_acceptance_conditions());
|
||||
|
||||
// If an other predecessor of i has the same label p
|
||||
// to reach i, then we don't compute the duplicator node.
|
||||
exist = false;
|
||||
for (std::vector<couple_bdd*>::iterator v
|
||||
= trans->begin();
|
||||
v != trans->end(); ++v)
|
||||
{
|
||||
if ((si->current_condition() == (*v)->first) &&
|
||||
(si->current_acceptance_conditions()
|
||||
== (*v)->second))
|
||||
exist = true;
|
||||
}
|
||||
|
||||
if (!exist)
|
||||
{
|
||||
// We build all the state couple with the label p.
|
||||
trans->push_back(p);
|
||||
for (std::vector<const state*>::iterator s
|
||||
= tgba_state_.begin();
|
||||
s != tgba_state_.end(); ++s)
|
||||
{
|
||||
duplicator_node* n2
|
||||
= new
|
||||
duplicator_node(*i,
|
||||
*s,
|
||||
si->current_condition(),
|
||||
si
|
||||
->current_acceptance_conditions(),
|
||||
nb_node_parity_game++);
|
||||
duplicator_vertice_.push_back(n2);
|
||||
}
|
||||
}
|
||||
else
|
||||
delete p;
|
||||
}
|
||||
s->destroy();
|
||||
}
|
||||
delete si;
|
||||
}
|
||||
std::vector<couple_bdd*>::iterator i2;
|
||||
for (i2 = trans->begin(); i2 != trans->end(); ++i2)
|
||||
{
|
||||
delete *i2;
|
||||
}
|
||||
delete trans;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parity_game_graph_direct::build_link()
|
||||
{
|
||||
int nb_ds = 0;
|
||||
int nb_sd = 0;
|
||||
spot::state* s = 0;
|
||||
|
||||
// for each couple of (spoiler, duplicator)
|
||||
for (std::vector<spoiler_node*>::iterator i
|
||||
= spoiler_vertice_.begin(); i != spoiler_vertice_.end(); ++i)
|
||||
{
|
||||
for (std::vector<duplicator_node*>::iterator j
|
||||
= duplicator_vertice_.begin();
|
||||
j != duplicator_vertice_.end(); ++j)
|
||||
{
|
||||
// We add a link between a duplicator and a spoiler.
|
||||
if ((*j)->get_spoiler_node()
|
||||
->compare((*i)->get_spoiler_node()) == 0)
|
||||
{
|
||||
tgba_succ_iterator* si
|
||||
= aut_->succ_iter((*j)->get_duplicator_node());
|
||||
for (si->first(); !si->done(); si->next())
|
||||
{
|
||||
s = si->current_state();
|
||||
if ((s->compare((*i)->get_duplicator_node()) == 0) &&
|
||||
(*j)->implies(si->current_condition(),
|
||||
si->current_acceptance_conditions()))
|
||||
{
|
||||
(*j)->add_succ(*i);
|
||||
++nb_ds;
|
||||
}
|
||||
s->destroy();
|
||||
}
|
||||
delete si;
|
||||
}
|
||||
|
||||
// We add a link between a spoiler and a duplicator.
|
||||
if ((*j)->get_duplicator_node()
|
||||
->compare((*i)->get_duplicator_node()) == 0)
|
||||
{
|
||||
tgba_succ_iterator* si
|
||||
= aut_->succ_iter((*i)->get_spoiler_node());
|
||||
for (si->first(); !si->done(); si->next())
|
||||
{
|
||||
s = si->current_state();
|
||||
if ((s->compare((*j)->get_spoiler_node()) == 0) &&
|
||||
(*j)->match(si->current_condition(),
|
||||
si->current_acceptance_conditions()))
|
||||
{
|
||||
(*i)->add_succ(*j);
|
||||
++nb_sd;
|
||||
}
|
||||
s->destroy();
|
||||
}
|
||||
delete si;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parity_game_graph_direct::lift()
|
||||
{
|
||||
bool change = true;
|
||||
|
||||
while (change)
|
||||
{
|
||||
change = false;
|
||||
for (std::vector<duplicator_node*>::iterator i
|
||||
= duplicator_vertice_.begin();
|
||||
i != duplicator_vertice_.end(); ++i)
|
||||
{
|
||||
change |= (*i)->set_win();
|
||||
}
|
||||
for (std::vector<spoiler_node*>::iterator i
|
||||
= spoiler_vertice_.begin();
|
||||
i != spoiler_vertice_.end(); ++i)
|
||||
{
|
||||
change |= (*i)->set_win();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
direct_simulation_relation*
|
||||
parity_game_graph_direct::get_relation()
|
||||
{
|
||||
direct_simulation_relation* rel = new direct_simulation_relation;
|
||||
state_couple* p = 0;
|
||||
seen_map::iterator j;
|
||||
|
||||
for (std::vector<spoiler_node*>::iterator i
|
||||
= spoiler_vertice_.begin();
|
||||
i != spoiler_vertice_.end(); ++i)
|
||||
{
|
||||
if (!(*i)->not_win)
|
||||
{
|
||||
p = new state_couple((*i)->get_spoiler_node(),
|
||||
(*i)->get_duplicator_node());
|
||||
rel->push_back(p);
|
||||
|
||||
|
||||
// We remove the state in rel from seen
|
||||
// because the destructor of
|
||||
// tgba_reachable_iterator_breadth_first
|
||||
// delete all instance of state.
|
||||
|
||||
|
||||
if ((j = seen.find(p->first)) != seen.end())
|
||||
seen.erase(j);
|
||||
if ((j = seen.find(p->second)) != seen.end())
|
||||
seen.erase(j);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
parity_game_graph_direct::~parity_game_graph_direct()
|
||||
{
|
||||
}
|
||||
|
||||
parity_game_graph_direct::parity_game_graph_direct(const tgba* a)
|
||||
: parity_game_graph(a)
|
||||
{
|
||||
this->build_graph();
|
||||
this->build_link();
|
||||
this->lift();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
direct_simulation_relation*
|
||||
get_direct_relation_simulation(const tgba* f,
|
||||
std::ostream& os,
|
||||
int opt)
|
||||
{
|
||||
parity_game_graph_direct* G = new parity_game_graph_direct(f);
|
||||
direct_simulation_relation* rel = G->get_relation();
|
||||
if (opt == 1)
|
||||
G->print(os);
|
||||
delete G;
|
||||
return rel;
|
||||
}
|
||||
|
||||
void
|
||||
free_relation_simulation(direct_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;
|
||||
|
||||
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;
|
||||
ptr->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
is_include(const tgba*, const tgba*)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const tgba*
|
||||
reduc_tgba_sim(const tgba* f, int opt)
|
||||
{
|
||||
|
|
@ -661,41 +40,18 @@ namespace spot
|
|||
return f;
|
||||
}
|
||||
|
||||
spot::tgba_reduc* automatareduc = new spot::tgba_reduc(f);
|
||||
|
||||
// Destroy the automaton created by scc_filter.
|
||||
if (opt & Reduce_Scc)
|
||||
delete f;
|
||||
|
||||
if (opt & (Reduce_quotient_Dir_Sim | Reduce_transition_Dir_Sim))
|
||||
if (opt & (Reduce_quotient_Dir_Sim | Reduce_transition_Dir_Sim
|
||||
| Reduce_quotient_Del_Sim | Reduce_transition_Del_Sim))
|
||||
{
|
||||
direct_simulation_relation* rel
|
||||
= get_direct_relation_simulation(automatareduc, std::cout);
|
||||
tgba* res = simulation(f);
|
||||
|
||||
assert(rel);
|
||||
if (opt & Reduce_Scc)
|
||||
delete f;
|
||||
|
||||
automatareduc->display_rel_sim(rel, std::cout);
|
||||
automatareduc->quotient_state(rel);
|
||||
automatareduc->delete_transitions(rel);
|
||||
|
||||
free_relation_simulation(rel);
|
||||
return res;
|
||||
}
|
||||
else
|
||||
if (opt & (Reduce_quotient_Del_Sim | Reduce_transition_Del_Sim))
|
||||
{
|
||||
delayed_simulation_relation* rel
|
||||
= get_delayed_relation_simulation(automatareduc, std::cout);
|
||||
|
||||
assert(rel);
|
||||
|
||||
automatareduc->display_rel_sim(rel, std::cout);
|
||||
automatareduc->quotient_state(rel);
|
||||
automatareduc->delete_transitions(rel);
|
||||
|
||||
free_relation_simulation(rel);
|
||||
}
|
||||
|
||||
return automatareduc;
|
||||
return tgba_dupexp_dfs(f);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Copyright (C) 2009, 2010, 2011 Laboratoire de Recherche et
|
||||
// Copyright (C) 2009, 2010, 2011, 2012 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
|
|
@ -25,14 +25,9 @@
|
|||
#ifndef SPOT_TGBAALGOS_REDUCTGBA_SIM_HH
|
||||
#define SPOT_TGBAALGOS_REDUCTGBA_SIM_HH
|
||||
|
||||
#include "tgba/tgbareduc.hh"
|
||||
#include "tgbaalgos/reachiter.hh"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <sstream>
|
||||
|
||||
namespace spot
|
||||
{
|
||||
class tgba;
|
||||
|
||||
/// \addtogroup tgba_reduction
|
||||
/// @{
|
||||
|
|
@ -62,280 +57,34 @@ namespace spot
|
|||
#endif
|
||||
};
|
||||
|
||||
/// \brief Remove some node of the automata using a simulation
|
||||
/// relation.
|
||||
#if __GNUC__
|
||||
/// \brief Simplify the automaton using a simulation relation.
|
||||
///
|
||||
/// \param a the automata to reduce.
|
||||
/// Do not use this obsolete function.
|
||||
///
|
||||
/// \param a the automata to reduce
|
||||
/// \param opt a conjonction of spot::reduce_tgba_options specifying
|
||||
/// which optimizations to apply.
|
||||
/// \return the reduced automata.
|
||||
/// which optimizations to apply. Actually any
|
||||
/// simulation-related flag will cause direct simulation
|
||||
/// to be applied.
|
||||
/// \return the reduced automaton
|
||||
/// \deprecated Use scc_filter(), minimize_wdba(), or simulation().
|
||||
const tgba* reduc_tgba_sim(const tgba* a, int opt = Reduce_All)
|
||||
__attribute__ ((deprecated));
|
||||
#else
|
||||
/// \brief Simplify the automaton using a simulation relation.
|
||||
///
|
||||
/// Do not use this obsolete function.
|
||||
///
|
||||
/// \param a the automata to reduce
|
||||
/// \param opt a conjonction of spot::reduce_tgba_options specifying
|
||||
/// which optimizations to apply. Actually any
|
||||
/// simulation-related flag will cause direct simulation
|
||||
/// to be applied.
|
||||
/// \return the reduced automaton
|
||||
/// \deprecated Use scc_filter(), minimize_wdba(), or simulation().
|
||||
const tgba* reduc_tgba_sim(const tgba* a, int opt = Reduce_All);
|
||||
|
||||
#ifndef SWIG
|
||||
|
||||
/// \brief Compute a direct simulation relation on state of tgba \a f.
|
||||
direct_simulation_relation* get_direct_relation_simulation(const tgba* a,
|
||||
std::ostream& os,
|
||||
int opt = -1);
|
||||
|
||||
/// Compute a delayed simulation relation on state of tgba \a f.
|
||||
/// \bug Does not work for generalized automata.
|
||||
delayed_simulation_relation* get_delayed_relation_simulation(const tgba* a,
|
||||
std::ostream& os,
|
||||
int opt = -1);
|
||||
|
||||
/// To free a simulation relation.
|
||||
void free_relation_simulation(direct_simulation_relation* rel);
|
||||
/// To free a simulation relation.
|
||||
void free_relation_simulation(delayed_simulation_relation* rel);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// simulation.
|
||||
|
||||
class spoiler_node;
|
||||
class duplicator_node;
|
||||
|
||||
typedef std::vector<spoiler_node*> sn_v;
|
||||
typedef std::vector<duplicator_node*> dn_v;
|
||||
typedef std::vector<const state*> s_v;
|
||||
|
||||
/// \brief Parity game graph which compute a simulation relation.
|
||||
class parity_game_graph : public tgba_reachable_iterator_breadth_first
|
||||
{
|
||||
public:
|
||||
parity_game_graph(const tgba* a);
|
||||
virtual ~parity_game_graph();
|
||||
|
||||
virtual simulation_relation* get_relation() = 0;
|
||||
|
||||
void print(std::ostream& os);
|
||||
|
||||
protected:
|
||||
sn_v spoiler_vertice_;
|
||||
dn_v duplicator_vertice_;
|
||||
s_v tgba_state_;
|
||||
int nb_node_parity_game;
|
||||
|
||||
void process_state(const state* s, int n, tgba_succ_iterator* si);
|
||||
|
||||
/// \brief Compute each node of the graph.
|
||||
virtual void build_graph() = 0;
|
||||
|
||||
/// \brief Remove edge from spoiler to duplicator that make
|
||||
/// duplicator loose.
|
||||
/// Spoiler node whose still have some link, reveal
|
||||
/// a direct simulation relation.
|
||||
virtual void lift() = 0;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Direct simulation.
|
||||
|
||||
/// Spoiler node of parity game graph.
|
||||
class spoiler_node
|
||||
{
|
||||
public:
|
||||
spoiler_node(const state* d_node,
|
||||
const state* s_node,
|
||||
int num);
|
||||
virtual ~spoiler_node();
|
||||
|
||||
/// \brief Add a successor.
|
||||
/// Return true if \a n wasn't yet in the list of successor,
|
||||
/// false eitherwise.
|
||||
bool add_succ(spoiler_node* n);
|
||||
void del_succ(spoiler_node* n);
|
||||
virtual void add_pred(spoiler_node* n);
|
||||
virtual void del_pred();
|
||||
int get_nb_succ();
|
||||
bool prune();
|
||||
virtual bool set_win();
|
||||
virtual std::string to_string(const tgba* a);
|
||||
virtual std::string succ_to_string();
|
||||
virtual bool compare(spoiler_node* n);
|
||||
|
||||
const state* get_spoiler_node();
|
||||
const state* get_duplicator_node();
|
||||
state_couple* get_pair();
|
||||
|
||||
bool not_win;
|
||||
int num_; // for the dot display.
|
||||
|
||||
protected:
|
||||
sn_v* lnode_succ;
|
||||
sn_v* lnode_pred;
|
||||
state_couple* sc_;
|
||||
};
|
||||
|
||||
/// Duplicator node of parity game graph.
|
||||
class duplicator_node : public spoiler_node
|
||||
{
|
||||
public:
|
||||
duplicator_node(const state* d_node,
|
||||
const state* s_node,
|
||||
bdd l,
|
||||
bdd a,
|
||||
int num);
|
||||
virtual ~duplicator_node();
|
||||
|
||||
virtual bool set_win();
|
||||
virtual std::string to_string(const tgba* a);
|
||||
virtual bool compare(spoiler_node* n);
|
||||
|
||||
bool match(bdd l, bdd a);
|
||||
bool implies(bdd l, bdd a);
|
||||
|
||||
bdd get_label() const;
|
||||
bdd get_acc() const;
|
||||
|
||||
protected:
|
||||
bdd label_;
|
||||
bdd acc_;
|
||||
};
|
||||
|
||||
/// Parity game graph which compute the direct simulation relation.
|
||||
class parity_game_graph_direct : public parity_game_graph
|
||||
{
|
||||
public:
|
||||
parity_game_graph_direct(const tgba* a);
|
||||
~parity_game_graph_direct();
|
||||
|
||||
virtual direct_simulation_relation* get_relation();
|
||||
|
||||
protected:
|
||||
virtual void build_graph();
|
||||
virtual void lift();
|
||||
void build_link();
|
||||
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Delayed simulation.
|
||||
|
||||
/// Spoiler node of parity game graph for delayed simulation.
|
||||
class spoiler_node_delayed : public spoiler_node
|
||||
{
|
||||
public:
|
||||
spoiler_node_delayed(const state* d_node,
|
||||
const state* s_node,
|
||||
bdd a,
|
||||
int num);
|
||||
~spoiler_node_delayed();
|
||||
|
||||
/// Return true if the progress_measure has changed.
|
||||
bool set_win();
|
||||
bdd get_acceptance_condition_visited() const;
|
||||
virtual bool compare(spoiler_node* n);
|
||||
virtual std::string to_string(const tgba* a);
|
||||
int get_progress_measure() const;
|
||||
|
||||
bool get_lead_2_acc_all();
|
||||
bool set_lead_2_acc_all(bdd acc = bddfalse);
|
||||
|
||||
//
|
||||
bool seen_;
|
||||
protected:
|
||||
/// a Bdd for retain all the acceptance condition
|
||||
/// that a node has visited.
|
||||
bdd acceptance_condition_visited_;
|
||||
int progress_measure_;
|
||||
bool lead_2_acc_all_;
|
||||
};
|
||||
|
||||
/// Duplicator node of parity game graph for delayed simulation.
|
||||
class duplicator_node_delayed : public duplicator_node
|
||||
{
|
||||
public:
|
||||
duplicator_node_delayed(const state* d_node,
|
||||
const state* s_node,
|
||||
bdd l,
|
||||
bdd a,
|
||||
int num);
|
||||
~duplicator_node_delayed();
|
||||
|
||||
/// Return true if the progress_measure has changed.
|
||||
bool set_win();
|
||||
virtual std::string to_string(const tgba* a);
|
||||
bool implies_label(bdd l);
|
||||
bool implies_acc(bdd a);
|
||||
int get_progress_measure();
|
||||
|
||||
bool get_lead_2_acc_all();
|
||||
bool set_lead_2_acc_all(bdd acc = bddfalse);
|
||||
|
||||
//
|
||||
bool seen_;
|
||||
protected:
|
||||
int progress_measure_;
|
||||
bool lead_2_acc_all_;
|
||||
};
|
||||
|
||||
|
||||
/// Parity game graph which computes the delayed simulation relation
|
||||
/// as explained in
|
||||
/// \verbatim
|
||||
/// @InProceedings{etessami.01.alp,
|
||||
/// author = {Kousha Etessami and Thomas Wilke and Rebecca A. Schuller},
|
||||
/// title = {Fair Simulation Relations, Parity Games, and State Space
|
||||
/// Reduction for Buchi Automata},
|
||||
/// booktitle = {Proceedings of the 28th international colloquium on
|
||||
/// Automata, Languages and Programming},
|
||||
/// pages = {694--707},
|
||||
/// year = {2001},
|
||||
/// editor = {Fernando Orejas and Paul G. Spirakis and Jan van Leeuwen},
|
||||
/// volume = {2076},
|
||||
/// series = {Lecture Notes in Computer Science},
|
||||
/// address = {Crete, Greece},
|
||||
/// month = {July},
|
||||
/// publisher = {Springer-Verlag}
|
||||
/// }
|
||||
/// \endverbatim
|
||||
class parity_game_graph_delayed: public parity_game_graph
|
||||
{
|
||||
public:
|
||||
parity_game_graph_delayed(const tgba* a);
|
||||
~parity_game_graph_delayed();
|
||||
|
||||
virtual delayed_simulation_relation* get_relation();
|
||||
|
||||
private:
|
||||
|
||||
/// Vector which contain all the sub-set of the set
|
||||
/// of acceptance condition.
|
||||
typedef std::vector<bdd> bdd_v;
|
||||
bdd_v sub_set_acc_cond_;
|
||||
|
||||
/// Return the number of acceptance condition.
|
||||
int nb_set_acc_cond();
|
||||
|
||||
///
|
||||
duplicator_node_delayed* add_duplicator_node_delayed(const spot::state* sn,
|
||||
const spot::state* dn,
|
||||
bdd acc,
|
||||
bdd label,
|
||||
int nb);
|
||||
|
||||
///
|
||||
spoiler_node_delayed* add_spoiler_node_delayed(const spot::state* sn,
|
||||
const spot::state* dn,
|
||||
bdd acc,
|
||||
int nb);
|
||||
|
||||
void build_recurse_successor_spoiler(spoiler_node* sn,
|
||||
std::ostringstream& os);
|
||||
void build_recurse_successor_duplicator(duplicator_node* dn,
|
||||
spoiler_node* sn,
|
||||
std::ostringstream& os);
|
||||
|
||||
/// \brief Compute the couple as for direct simulation,
|
||||
virtual void build_graph();
|
||||
|
||||
/// \brief The Jurdzinski's lifting algorithm.
|
||||
virtual void lift();
|
||||
};
|
||||
|
||||
#endif // SWIG
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,675 +0,0 @@
|
|||
// Copyright (C) 2008, 2011 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2004, 2005 Laboratoire d'Informatique de Paris 6 (LIP6),
|
||||
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
|
||||
// et Marie Curie.
|
||||
//
|
||||
// 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 2 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 Spot; see the file COPYING. If not, write to the Free
|
||||
// Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||
// 02111-1307, USA.
|
||||
|
||||
#include "reductgba_sim.hh"
|
||||
#include "tgba/bddprint.hh"
|
||||
|
||||
namespace spot
|
||||
{
|
||||
/// Number of spoiler node with a one priority (see icalp2001).
|
||||
/// The one priority is represent by a \a acceptance_condition_visited_
|
||||
/// which differ of bddfalse.
|
||||
/// This spoiler node are looser for the duplicator.
|
||||
/// FIXME: get rid of these ugly globals
|
||||
static int nb_spoiler_loose_;
|
||||
|
||||
static int nb_spoiler;
|
||||
static int nb_duplicator;
|
||||
|
||||
static bdd all_acc_cond = bddfalse;
|
||||
|
||||
static std::vector<bool*> bool_v;
|
||||
|
||||
//static int nb_node = 0;
|
||||
|
||||
//seen_map_node seen_node_;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// spoiler_node_delayed
|
||||
|
||||
spoiler_node_delayed::spoiler_node_delayed(const state* d_node,
|
||||
const state* s_node,
|
||||
bdd a,
|
||||
int num)
|
||||
: spoiler_node(d_node, s_node, num),
|
||||
acceptance_condition_visited_(a)
|
||||
{
|
||||
++nb_spoiler;
|
||||
progress_measure_ = 0;
|
||||
if (acceptance_condition_visited_ != bddfalse)
|
||||
++nb_spoiler_loose_;
|
||||
lead_2_acc_all_ = false;
|
||||
|
||||
seen_ = false;
|
||||
}
|
||||
|
||||
spoiler_node_delayed::~spoiler_node_delayed()
|
||||
{
|
||||
if (acceptance_condition_visited_ != bddfalse)
|
||||
--nb_spoiler_loose_;
|
||||
}
|
||||
|
||||
bool
|
||||
spoiler_node_delayed::set_win()
|
||||
{
|
||||
// We take the max of the progress measure of the successor node
|
||||
// because we are on a spoiler.
|
||||
|
||||
if (lnode_succ->empty())
|
||||
progress_measure_ = nb_spoiler_loose_ + 1;
|
||||
|
||||
if (progress_measure_ >= nb_spoiler_loose_ + 1)
|
||||
return false;
|
||||
|
||||
bool change;
|
||||
int tmpmax = 0;
|
||||
int tmp = 0;
|
||||
int tmpmaxwin = -1;
|
||||
sn_v::iterator i = lnode_succ->begin();
|
||||
if (i != lnode_succ->end())
|
||||
{
|
||||
tmpmax =
|
||||
static_cast<duplicator_node_delayed*>(*i)->get_progress_measure();
|
||||
if (static_cast<duplicator_node_delayed*>(*i)->get_lead_2_acc_all())
|
||||
tmpmaxwin = tmpmax;
|
||||
++i;
|
||||
}
|
||||
for (; i != lnode_succ->end(); ++i)
|
||||
{
|
||||
tmp =
|
||||
static_cast<duplicator_node_delayed*>(*i)->get_progress_measure();
|
||||
if (tmp > tmpmax)
|
||||
tmpmax = tmp;
|
||||
if (static_cast<duplicator_node_delayed*>(*i)->get_lead_2_acc_all() &&
|
||||
(tmp > tmpmaxwin))
|
||||
tmpmaxwin = tmp;
|
||||
}
|
||||
|
||||
if (tmpmaxwin != -1)
|
||||
tmpmax = tmpmaxwin;
|
||||
|
||||
// If the priority of the node is 1
|
||||
// acceptance_condition_visited_ != bddfalse
|
||||
// then we increment the progress measure of 1.
|
||||
if ((acceptance_condition_visited_ != bddfalse) &&
|
||||
(tmpmax < (nb_spoiler_loose_ + 1)))
|
||||
++tmpmax;
|
||||
|
||||
change = (progress_measure_ < tmpmax);
|
||||
|
||||
progress_measure_ = tmpmax;
|
||||
return change;
|
||||
}
|
||||
|
||||
bool
|
||||
spoiler_node_delayed::compare(spoiler_node* n)
|
||||
{
|
||||
return (this->spoiler_node::compare(n) &&
|
||||
(acceptance_condition_visited_ ==
|
||||
static_cast<spoiler_node_delayed*>(n)->
|
||||
get_acceptance_condition_visited()));
|
||||
}
|
||||
|
||||
std::string
|
||||
spoiler_node_delayed::to_string(const tgba* a)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
// print the node.
|
||||
os << num_
|
||||
<< " [shape=box, label=\"("
|
||||
<< a->format_state(sc_->first)
|
||||
<< ", "
|
||||
<< a->format_state(sc_->second)
|
||||
<< ", ";
|
||||
//bdd_print_acc(os, a->get_dict(), acceptance_condition_visited_);
|
||||
if (acceptance_condition_visited_ == bddfalse)
|
||||
{
|
||||
os << "false";
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "ACC";
|
||||
}
|
||||
os << ")"
|
||||
<< " pm = " << progress_measure_;
|
||||
if (lead_2_acc_all_)
|
||||
os << ", 1\"]";
|
||||
else
|
||||
os << ", 0\"]";
|
||||
os << std::endl;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bdd
|
||||
spoiler_node_delayed::get_acceptance_condition_visited() const
|
||||
{
|
||||
return acceptance_condition_visited_;
|
||||
}
|
||||
|
||||
int
|
||||
spoiler_node_delayed::get_progress_measure() const
|
||||
{
|
||||
if ((acceptance_condition_visited_ == bddfalse) &&
|
||||
(progress_measure_ != (nb_spoiler_loose_ + 1)))
|
||||
return 0;
|
||||
else
|
||||
return progress_measure_;
|
||||
}
|
||||
|
||||
bool
|
||||
spoiler_node_delayed::get_lead_2_acc_all()
|
||||
{
|
||||
return lead_2_acc_all_;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
spoiler_node_delayed::set_lead_2_acc_all(bdd acc)
|
||||
{
|
||||
if (!seen_)
|
||||
{
|
||||
seen_ = true;
|
||||
for (sn_v::iterator i = lnode_succ->begin();
|
||||
i != lnode_succ->end(); ++i)
|
||||
static_cast<duplicator_node_delayed*>(*i)->set_lead_2_acc_all(acc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (acc == all_acc_cond)
|
||||
lead_2_acc_all_ = true;
|
||||
}
|
||||
return lead_2_acc_all_;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// duplicator_node_delayed
|
||||
|
||||
duplicator_node_delayed::duplicator_node_delayed(const state* d_node,
|
||||
const state* s_node,
|
||||
bdd l,
|
||||
bdd a,
|
||||
int num)
|
||||
: duplicator_node(d_node, s_node, l, a, num)
|
||||
{
|
||||
++nb_duplicator;
|
||||
progress_measure_ = 0;
|
||||
all_acc_cond |= a;
|
||||
lead_2_acc_all_ = false;
|
||||
|
||||
seen_ = false;
|
||||
}
|
||||
|
||||
duplicator_node_delayed::~duplicator_node_delayed()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node_delayed::set_win()
|
||||
{
|
||||
// We take the min of the progress measure of the successor node
|
||||
// because we are on a duplicator.
|
||||
|
||||
if (lnode_succ->empty())
|
||||
progress_measure_ = nb_spoiler_loose_ + 1;
|
||||
|
||||
if (progress_measure_ >= nb_spoiler_loose_ + 1)
|
||||
return false;
|
||||
|
||||
bool change;
|
||||
int tmpmin = 0;
|
||||
int tmp = 0;
|
||||
int tmpminwin = -1;
|
||||
sn_v::iterator i = lnode_succ->begin();
|
||||
if (i != lnode_succ->end())
|
||||
{
|
||||
tmpmin =
|
||||
static_cast<spoiler_node_delayed*>(*i)->get_progress_measure();
|
||||
if (static_cast<spoiler_node_delayed*>(*i)->get_lead_2_acc_all())
|
||||
tmpminwin = tmpmin;
|
||||
++i;
|
||||
}
|
||||
for (; i != lnode_succ->end(); ++i)
|
||||
{
|
||||
tmp = static_cast<spoiler_node_delayed*>(*i)->get_progress_measure();
|
||||
if (tmp < tmpmin)
|
||||
tmpmin = tmp;
|
||||
if (static_cast<spoiler_node_delayed*>(*i)->get_lead_2_acc_all() &&
|
||||
(tmp > tmpminwin))
|
||||
tmpminwin = tmp;
|
||||
}
|
||||
if (tmpminwin != -1)
|
||||
tmpmin = tmpminwin;
|
||||
|
||||
change = (progress_measure_ < tmpmin);
|
||||
progress_measure_ = tmpmin;
|
||||
return change;
|
||||
}
|
||||
|
||||
std::string
|
||||
duplicator_node_delayed::to_string(const tgba* a)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
// print the node.
|
||||
os << num_
|
||||
<< " [shape=box, label=\"("
|
||||
<< a->format_state(sc_->first)
|
||||
<< ", "
|
||||
<< a->format_state(sc_->second)
|
||||
<< ", ";
|
||||
if (label_ == bddfalse)
|
||||
os << "0";
|
||||
else if (label_ == bddtrue)
|
||||
os << "1";
|
||||
else
|
||||
bdd_print_acc(os, a->get_dict(), label_);
|
||||
//<< ", ";
|
||||
//bdd_print_acc(os, a->get_dict(), acc_);
|
||||
os << ")"
|
||||
<< " pm = " << progress_measure_;
|
||||
if (lead_2_acc_all_)
|
||||
os << ", 1\"]";
|
||||
else
|
||||
os << ", 0\"]";
|
||||
os << std::endl;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node_delayed::implies_label(bdd l)
|
||||
{
|
||||
return ((l | !label_) == bddtrue);
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node_delayed::implies_acc(bdd a)
|
||||
{
|
||||
return ((a | !acc_) == bddtrue);
|
||||
}
|
||||
|
||||
int
|
||||
duplicator_node_delayed::get_progress_measure()
|
||||
{
|
||||
return progress_measure_;
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node_delayed::get_lead_2_acc_all()
|
||||
{
|
||||
return lead_2_acc_all_;
|
||||
}
|
||||
|
||||
bool
|
||||
duplicator_node_delayed::set_lead_2_acc_all(bdd acc)
|
||||
{
|
||||
acc |= acc_;
|
||||
if (!seen_)
|
||||
{
|
||||
seen_ = true;
|
||||
for (sn_v::iterator i = lnode_succ->begin();
|
||||
i != lnode_succ->end(); ++i)
|
||||
lead_2_acc_all_
|
||||
|= static_cast<spoiler_node_delayed*>(*i)->set_lead_2_acc_all(acc);
|
||||
}
|
||||
return lead_2_acc_all_;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// parity_game_graph_delayed
|
||||
|
||||
int
|
||||
parity_game_graph_delayed::nb_set_acc_cond()
|
||||
{
|
||||
return aut_->number_of_acceptance_conditions();
|
||||
}
|
||||
|
||||
// We build only node which are reachable
|
||||
void
|
||||
parity_game_graph_delayed::build_graph()
|
||||
{
|
||||
// We build only some "basic" spoiler node.
|
||||
sn_v tab_temp;
|
||||
s_v::iterator i1;
|
||||
for (i1 = tgba_state_.begin(); i1 != tgba_state_.end(); ++i1)
|
||||
{
|
||||
|
||||
// spoiler node are all state couple (i,j)
|
||||
s_v::iterator i2;
|
||||
for (i2 = tgba_state_.begin();
|
||||
i2 != tgba_state_.end(); ++i2)
|
||||
{
|
||||
//std::cout << "add spoiler node" << std::endl;
|
||||
++nb_spoiler;
|
||||
spoiler_node_delayed* n1
|
||||
= new spoiler_node_delayed(*i1, *i2,
|
||||
bddfalse,
|
||||
nb_node_parity_game++);
|
||||
spoiler_vertice_.push_back(n1);
|
||||
tab_temp.push_back(n1);
|
||||
}
|
||||
}
|
||||
|
||||
sn_v::iterator j;
|
||||
std::ostringstream os;
|
||||
for (j = tab_temp.begin(); j != tab_temp.end(); ++j)
|
||||
{
|
||||
// We add a link between a spoiler and a (new) duplicator.
|
||||
// The acc of the duplicator must contains the
|
||||
// acceptance_condition_visited_ of the spoiler.
|
||||
//std::cout << "build_link : iter " << ++n << std::endl;
|
||||
build_recurse_successor_spoiler(*j, os);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
parity_game_graph_delayed::
|
||||
build_recurse_successor_spoiler(spoiler_node* sn,
|
||||
std::ostringstream& os)
|
||||
{
|
||||
assert(sn);
|
||||
|
||||
tgba_succ_iterator* si = aut_->succ_iter(sn->get_spoiler_node());
|
||||
|
||||
for (si->first(); !si->done(); si->next())
|
||||
{
|
||||
bdd btmp = si->current_acceptance_conditions() |
|
||||
static_cast<spoiler_node_delayed*>(sn)->
|
||||
get_acceptance_condition_visited();
|
||||
|
||||
s_v::iterator i1;
|
||||
state* s;
|
||||
for (i1 = tgba_state_.begin();
|
||||
i1 != tgba_state_.end(); ++i1)
|
||||
{
|
||||
|
||||
s = si->current_state();
|
||||
if (s->compare(*i1) == 0)
|
||||
{
|
||||
s->destroy();
|
||||
duplicator_node_delayed* dn
|
||||
= add_duplicator_node_delayed(*i1,
|
||||
sn->get_duplicator_node(),
|
||||
si->current_condition(),
|
||||
btmp,
|
||||
nb_node_parity_game++);
|
||||
|
||||
if (!(sn->add_succ(dn)))
|
||||
continue;
|
||||
|
||||
std::ostringstream os2;
|
||||
os2 << os.str() << " ";
|
||||
build_recurse_successor_duplicator(dn, sn, os2);
|
||||
}
|
||||
else
|
||||
s->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
delete si;
|
||||
}
|
||||
|
||||
void
|
||||
parity_game_graph_delayed::
|
||||
build_recurse_successor_duplicator(duplicator_node* dn,
|
||||
spoiler_node* ,
|
||||
std::ostringstream& os)
|
||||
{
|
||||
tgba_succ_iterator* si = aut_->succ_iter(dn->get_duplicator_node());
|
||||
|
||||
for (si->first(); !si->done(); si->next())
|
||||
{
|
||||
|
||||
// if si->current_condition() doesn't implies dn->get_label()
|
||||
// then duplicator can't play.
|
||||
if ((si->current_condition() | !dn->get_label()) != bddtrue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bdd btmp = dn->get_acc() -
|
||||
(dn->get_acc() & si->current_acceptance_conditions());
|
||||
|
||||
s_v::iterator i1;
|
||||
state* s;
|
||||
for (i1 = tgba_state_.begin();
|
||||
i1 != tgba_state_.end(); ++i1)
|
||||
{
|
||||
s = si->current_state();
|
||||
|
||||
if (s->compare(*i1) == 0)
|
||||
{
|
||||
s->destroy();
|
||||
spoiler_node_delayed* sn_n
|
||||
= add_spoiler_node_delayed(dn->get_spoiler_node(),
|
||||
*i1,
|
||||
btmp,
|
||||
nb_node_parity_game++);
|
||||
|
||||
if (!(dn->add_succ(sn_n)))
|
||||
continue;
|
||||
|
||||
std::ostringstream os2;
|
||||
os2 << os.str() << " ";
|
||||
build_recurse_successor_spoiler(sn_n, os2);
|
||||
}
|
||||
else
|
||||
s->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
delete si;
|
||||
}
|
||||
|
||||
duplicator_node_delayed*
|
||||
parity_game_graph_delayed::add_duplicator_node_delayed(const spot::state* sn,
|
||||
const spot::state* dn,
|
||||
bdd acc,
|
||||
bdd label,
|
||||
int nb)
|
||||
{
|
||||
bool exist = false;
|
||||
|
||||
duplicator_node_delayed* dn_n
|
||||
= new duplicator_node_delayed(sn, dn, acc, label, nb);
|
||||
|
||||
for (std::vector<duplicator_node*>::iterator i
|
||||
= duplicator_vertice_.begin();
|
||||
i != duplicator_vertice_.end(); ++i)
|
||||
{
|
||||
if (dn_n->compare(*i))
|
||||
{
|
||||
exist = true;
|
||||
delete dn_n;
|
||||
dn_n = static_cast<duplicator_node_delayed*>(*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exist)
|
||||
duplicator_vertice_.push_back(dn_n);
|
||||
|
||||
return dn_n;
|
||||
}
|
||||
|
||||
spoiler_node_delayed*
|
||||
parity_game_graph_delayed::add_spoiler_node_delayed(const spot::state* sn,
|
||||
const spot::state* dn,
|
||||
bdd acc,
|
||||
int nb)
|
||||
{
|
||||
bool exist = false;
|
||||
|
||||
//bool l2a = (acc != aut_->all_acceptance_conditions());
|
||||
spoiler_node_delayed* sn_n
|
||||
= new spoiler_node_delayed(sn, dn, acc, nb);
|
||||
|
||||
for (std::vector<spoiler_node*>::iterator i
|
||||
= spoiler_vertice_.begin();
|
||||
i != spoiler_vertice_.end(); ++i)
|
||||
{
|
||||
if (sn_n->compare(*i))
|
||||
{
|
||||
exist = true;
|
||||
delete sn_n;
|
||||
sn_n = static_cast<spoiler_node_delayed*>(*i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exist)
|
||||
spoiler_vertice_.push_back(sn_n);
|
||||
|
||||
return sn_n;
|
||||
}
|
||||
|
||||
void
|
||||
parity_game_graph_delayed::lift()
|
||||
{
|
||||
// Jurdzinski's algorithm
|
||||
bool change = true;
|
||||
|
||||
while (change)
|
||||
{
|
||||
//std::cout << "lift::change = true" << std::endl;
|
||||
change = false;
|
||||
for (std::vector<duplicator_node*>::iterator i
|
||||
= duplicator_vertice_.begin();
|
||||
i != duplicator_vertice_.end(); ++i)
|
||||
{
|
||||
change |= (*i)->set_win();
|
||||
}
|
||||
for (std::vector<spoiler_node*>::iterator i
|
||||
= spoiler_vertice_.begin();
|
||||
i != spoiler_vertice_.end(); ++i)
|
||||
{
|
||||
change |= (*i)->set_win();
|
||||
}
|
||||
}
|
||||
//std::cout << "lift::change = false" << std::endl;
|
||||
}
|
||||
|
||||
delayed_simulation_relation*
|
||||
parity_game_graph_delayed::get_relation()
|
||||
{
|
||||
delayed_simulation_relation* rel = new delayed_simulation_relation;
|
||||
state_couple* p = 0;
|
||||
seen_map::iterator j;
|
||||
|
||||
// This does not work for generalized automata. A tarjan-like
|
||||
// algorithm is required to tell whether a state can lead to an
|
||||
// acceptance cycle.
|
||||
if (this->nb_set_acc_cond() > 1)
|
||||
return rel;
|
||||
|
||||
for (std::vector<spoiler_node*>::iterator i
|
||||
= spoiler_vertice_.begin();
|
||||
i != spoiler_vertice_.end(); ++i)
|
||||
{
|
||||
if ((static_cast<spoiler_node_delayed*>(*i)->get_progress_measure()
|
||||
< nb_spoiler_loose_ + 1) &&
|
||||
(static_cast<spoiler_node_delayed*>(*i)
|
||||
->get_acceptance_condition_visited() == bddfalse))
|
||||
{
|
||||
p = new state_couple((*i)->get_spoiler_node(),
|
||||
(*i)->get_duplicator_node());
|
||||
rel->push_back(p);
|
||||
|
||||
// We remove the state in rel from seen
|
||||
// because the destructor of
|
||||
// tgba_reachable_iterator_breadth_first
|
||||
// delete all the state.
|
||||
|
||||
if ((j = seen.find(p->first)) != seen.end())
|
||||
seen.erase(j);
|
||||
if ((j = seen.find(p->second)) != seen.end())
|
||||
seen.erase(j);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return rel;
|
||||
}
|
||||
|
||||
parity_game_graph_delayed::~parity_game_graph_delayed()
|
||||
{
|
||||
}
|
||||
|
||||
parity_game_graph_delayed::parity_game_graph_delayed(const tgba* a)
|
||||
: parity_game_graph(a)
|
||||
{
|
||||
nb_spoiler_loose_ = 0;
|
||||
this->build_graph();
|
||||
this->lift();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
delayed_simulation_relation*
|
||||
get_delayed_relation_simulation(const tgba* f, std::ostream& os, int opt)
|
||||
{
|
||||
parity_game_graph_delayed* G = new parity_game_graph_delayed(f);
|
||||
delayed_simulation_relation* rel = G->get_relation();
|
||||
if (opt == 1)
|
||||
G->print(os);
|
||||
delete G;
|
||||
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;
|
||||
ptr->destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue