ltlsynt: rework synthesis algorithms

ltlsynt now offers two algorithms: one where splitting occurs before
determinization (the historical one) and one where determinization
occurs before splitting.

* bin/ltlsynt.cc: here
* tests/core/ltlsynt.test: test it and refactor test file
* NEWS: document it
* spot/misc/game.hh, spot/misc/game.cc: remove Calude's algorithm
This commit is contained in:
Maximilien Colange 2018-05-04 18:12:47 +02:00
parent 516e9536df
commit bd75ab5b39
5 changed files with 101 additions and 423 deletions

View file

@ -108,31 +108,6 @@ public:
\endverbatim */
void solve(region_t (&w)[2], strategy_t (&s)[2]) const;
/// Whether player 1 has a winning strategy from the initial state.
/// Implements Calude et al.'s quasipolynomial time algorithm.
/** \verbatim
@inproceedings{calude.17.stoc,
author = {Calude, Cristian S. and Jain, Sanjay and Khoussainov,
Bakhadyr and Li, Wei and Stephan, Frank},
title = {Deciding Parity Games in Quasipolynomial Time},
booktitle = {Proceedings of the 49th Annual ACM SIGACT Symposium on
Theory of Computing},
series = {STOC 2017},
year = {2017},
isbn = {978-1-4503-4528-6},
location = {Montreal, Canada},
pages = {252--263},
numpages = {12},
url = {http://doi.acm.org/10.1145/3055399.3055409},
doi = {10.1145/3055399.3055409},
acmid = {3055409},
publisher = {ACM},
address = {New York, NY, USA},
keywords = {Muller Games, Parity Games, Quasipolynomial Time Algorithm},
}
\endverbatim */
bool solve_qp() const;
private:
typedef twa_graph::graph_t::edge_storage_t edge_t;
@ -149,159 +124,4 @@ private:
region_t (&w)[2], strategy_t (&s)[2]) const;
};
class reachability_state: public state
{
private:
unsigned num_;
std::vector<unsigned> b_;
bool anke_;
public:
reachability_state(unsigned state, const std::vector<unsigned>& b,
bool anke)
: num_(state), b_(b), anke_(anke)
{
}
int compare(const state* other) const override;
bool operator==(const reachability_state& o) const
{
return compare(&o) == 0;
}
bool operator!=(const reachability_state& o) const
{
return compare(&o) != 0;
}
bool operator<(const reachability_state& o) const;
size_t hash() const override
{
size_t hash = wang32_hash(num_);
for (unsigned i = 0; i < b_.size(); ++i)
hash ^= wang32_hash(b_[i]) ^ wang32_hash(i);
return hash;
}
reachability_state* clone() const override
{
return new reachability_state(*this);
}
std::vector<unsigned> b() const
{
return b_;
}
unsigned num() const
{
return num_;
}
bool anke() const
{
return anke_;
}
};
typedef std::shared_ptr<const reachability_state>
const_reachability_state_ptr;
struct reachability_state_hash
{
size_t operator()(const reachability_state& state) const
{
return state.hash();
}
};
class reachability_game_succ_iterator final: public twa_succ_iterator
{
private:
const parity_game& pg_;
const reachability_state& state_;
internal::edge_iterator<const twa_graph::graph_t> it_;
public:
reachability_game_succ_iterator(const parity_game& pg,
const reachability_state& s)
: pg_(pg), state_(s)
{
}
bool first() override
{
it_ = pg_.out(state_.num()).begin();
return it_ != pg_.out(state_.num()).end();
}
bool next() override
{
++it_;
return it_ != pg_.out(state_.num()).end();
}
bool done() const override
{
return it_ == pg_.out(state_.num()).end();
}
const reachability_state* dst() const override;
bdd cond() const override
{
return bddtrue;
}
acc_cond::mark_t acc() const override
{
return {};
}
};
// On-the-fly reachability game interface for a max even parity game such
// that a target is reachable iff there is a memoryless winning strategy
// in the parity game for player 1.
class reachability_game final: public twa
{
private:
typedef std::unordered_map<spot::reachability_state, unsigned,
spot::reachability_state_hash> wincount_t;
typedef std::unordered_map<spot::reachability_state,
std::vector<spot::reachability_state>,
spot::reachability_state_hash> parents_t;
const parity_game& pg_;
// number of successors that need to have a winning strategy in order for
// a given node to have a winning strategy.
wincount_t c_;
parents_t parents_;
const_reachability_state_ptr init_state_; // cache
public:
reachability_game(const parity_game& pg)
: twa(std::make_shared<bdd_dict>()), pg_(pg)
{
init_state_ = std::shared_ptr<const reachability_state>(get_init_state());
}
const reachability_state* get_init_state() const override;
reachability_game_succ_iterator* succ_iter(const state* s) const override;
std::string format_state(const state* s) const override;
bool is_reachable();
private:
bool mark(const spot::reachability_state& s);
bool is_target(const reachability_state& s);
};
}