13#ifndef MCRL2_PG_SCC_IMPL_H
14#define MCRL2_PG_SCC_IMPL_H
16#include "mcrl2/pg/Graph.h"
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34template<
class Callback>
48 info.insert( info.end(), graph_.V(),
57 assert(stack.empty());
66 assert(stack.empty());
74 info[v].first = info[v].second = next_index++;
75 component.push_back(v);
78 stack.emplace_back(v, 0);
82
83
84
89 while (res == 0 && !stack.empty())
91 verti v = stack.back().first;
92 StaticGraph::const_iterator edge_it =
93 graph_.succ_begin(v) + stack.back().second++;
95 if (edge_it != graph_.succ_end(v))
108
109 info[v].second = std::min(info[v].second, info[w].first);
120
121 int u = stack.back().first;
122 info[u].second = std::min(info[u].second, info[v].second);
126 if (info[v].first == info[v].second)
129 std::vector<verti>::iterator it = component.end();
131 assert(it != component.begin());
136 res = callback_((
const verti*)&*it, component.end() - it);
139 component.erase(it, component.end());
162
163
164
165
166
167
void swap(StaticGraph &a, StaticGraph &b) noexcept
void merge_strategies(std::vector< verti > &strategy, const std::vector< verti > &substrat, const std::vector< verti > &vertex_map)
void merge_vertex_maps(ForwardIterator begin, ForwardIterator end, const verti *old_map, verti old_map_size)
void swap(ParityGame &a, ParityGame &b) noexcept
player_t opponent(const player_t p)
bool operator==(const ParityGameVertex &a, const ParityGameVertex &b)
bool operator!=(const ParityGameVertex &a, const ParityGameVertex &b)
Factory class for ComponentSolver instances.
const int max_depth_
Maximum recursion depth.
~ComponentSolverFactory() override
ParityGameSolver * create(const ParityGame &game, const verti *vertex_map, verti vertex_map_size) override
Return a new ComponentSolver instance.
ParityGameSolverFactory & pgsf_
Factory used to create subsolvers.
ComponentSolverFactory(ParityGameSolverFactory &pgsf, int max_depth=10)
ParityGame::Strategy solve() override
const verti vmap_size_
Size of vertex map.
const int max_depth_
Max. recusion depth.
std::array< DenseSet< verti > *, 2 > winning_
Resulting winning sets.
ParityGameSolverFactory & pgsf_
Solver factory to use.
~ComponentSolver() override
ComponentSolver(const ParityGame &game, ParityGameSolverFactory &pgsf, int max_depth, const verti *vmap=nullptr, verti vmap_size=0)
const verti * vmap_
Current vertex map.
int operator()(const verti *vertices, std::size_t num_vertices)
ParityGame::Strategy strategy_
Resulting strategy.
void set_vec_to_top(verti v) override
const verti * vec(verti v) const override
void set_vec(verti v, const verti *src, bool carry) override
verti * spm_
array storing the SPM vector data
DenseSPM(const ParityGame &game, ParityGame::Player player, LiftingStatistics *stats=nullptr, const verti *vertex_map=nullptr, verti vertex_map_size=0)
bool operator>(const Iterator &other) const
bool operator<=(const Iterator &other) const
Iterator(const Iterator &it)
bool operator!=(const Iterator &other) const
Iterator & operator=(const Iterator &it)=default
bool operator==(const Iterator &other) const
Iterator & operator++(int)
bool operator>=(const Iterator &other) const
Iterator(const DenseSet *set, Key key)
bool operator<(const Iterator &other) const
const_iterator end() const
DenseSet(Key begin, Key end, const Alloc &alloc=Alloc())
DenseSet(const DenseSet &)=delete
const_iterator begin() const
size_type count(const Key &k) const
iterator find(const Key &k)
std::pair< iterator, bool > insert(const Key &k)
const size_type range_size_
void insert(InputIterator it, InputIterator end)
const_iterator find(const Key &k) const
DenseSet & operator=(const DenseSet &)=delete
long long lifts_attempted() const
LiftingStatistics(const ParityGame &game, long long max_lifts=-1)
void add_lifts_succeeded(long long count)
void add_lifts_attempted(long long count)
void add_lifts_succeeded(verti v, long long count)
long long lifts_attempted_
long long lifts_succeeded_
long long lifts_attempted(verti v) const
void record_lift(verti v, bool success)
long long lifts_succeeded() const
long long lifts_succeeded(verti v) const
void add_lifts_attempted(verti v, long long count)
virtual void push(verti vertex)=0
virtual void bump(verti vertex)=0
virtual ~LiftingStrategy2()=default
~LiftingStrategyFactory() override
virtual LiftingStrategy * create(const ParityGame &game, const SmallProgressMeasures &spm)=0
static LiftingStrategyFactory * create(const std::string &description)
static const char * usage()
virtual bool supports_version(int version)
virtual LiftingStrategy2 * create2(const ParityGame &, const SmallProgressMeasures &)
virtual void lifted(verti vertex)=0
virtual ~LiftingStrategy()=default
virtual ParityGameSolver * create(const ParityGame &game, const verti *vertex_map=nullptr, verti vertex_map_size=0)=0
~ParityGameSolverFactory() override=default
const ParityGame & game() const
~ParityGameSolver() override=default
const ParityGame & game_
Game being solved.
ParityGameSolver(const ParityGame &game)
virtual ParityGame::Strategy solve()=0
priority_t priority(verti v) const
void compress_priorities(const verti *cardinality=nullptr, bool preserve_parity=true)
void read_pbes(const std::string &file_path, verti *goal_vertex=nullptr, StaticGraph::EdgeDirection edge_dir=StaticGraph::EdgeDirection::EDGE_BIDIRECTIONAL, const std::string &rewrite_strategy="jitty")
void read_pgsolver(std::istream &is, StaticGraph::EdgeDirection edge_dir=StaticGraph::EdgeDirection::EDGE_BIDIRECTIONAL)
verti cardinality(int p) const
void make_subgame(const ParityGame &game, ForwardIterator vertices_begin, ForwardIterator vertices_end, bool proper, StaticGraph::EdgeDirection edge_dir=StaticGraph::EdgeDirection::EDGE_NONE)
Player player(verti v) const
ParityGame(const ParityGame &game)
void swap(ParityGame &pg) noexcept
void reset(verti V, int d)
long long propagate_priorities()
ParityGame & operator=(const ParityGame &game)
void write_pgsolver(std::ostream &os) const
void assign(const ParityGame &game)
void write_dot(std::ostream &os) const
void shuffle(const std::vector< verti > &perm)
void assign_pbes(mcrl2::pbes_system::pbes &pbes, verti *goal_vertex=nullptr, StaticGraph::EdgeDirection edge_dir=StaticGraph::EdgeDirection::EDGE_BIDIRECTIONAL, const std::string &rewrite_strategy="jitty")
void read_raw(std::istream &is)
void write_debug(const Strategy &s=Strategy(), std::ostream &os=std::cerr) const
void write_raw(std::ostream &os) const
void recalculate_cardinalities(verti num_vertices)
bool verify(const Strategy &s, verti *error) const
Player winner(const StrategyT &s, verti v) const
int propagate_priority(verti v, StaticGraph::const_iterator it, StaticGraph::const_iterator end)
ParityGameVertex * vertex_
void assign(const StaticGraph &g, ParityGameVertex *na)
const StaticGraph & graph() const
void make_random(verti V, unsigned clustersize, unsigned outdeg, StaticGraph::EdgeDirection edge_dir, int d)
verti next_index
Index of next vertex to be labelled by inorder traversal.
const StaticGraph & graph_
SCC(const StaticGraph &graph, Callback &callback)
std::vector< verti > component
Vertex indices of the current component.
int operator()(const verti *scc, std::size_t size)
const std::vector< verti > & operator[](std::size_t i) const
std::vector< verti > & operator[](std::size_t i)
void clear()
Clear the list of collected SCCs.
ParityGame::Strategy solve_normal() override
ParityGame::Strategy solve_alternate() override
SmallProgressMeasuresSolver2 & operator=(const SmallProgressMeasuresSolver2 &)=delete
SmallProgressMeasuresSolver2(const ParityGame &game, std::shared_ptr< LiftingStrategyFactory > lsf, bool alternate=false, LiftingStatistics *stats=nullptr, const verti *vmap=nullptr, verti vmap_size=0)
SmallProgressMeasuresSolver2(const SmallProgressMeasuresSolver2 &)=delete
LiftingStatistics * stats_
std::shared_ptr< LiftingStrategyFactory > lsf_
ParityGameSolver * create(const ParityGame &game, const verti *vmap, verti vmap_size) override
SmallProgressMeasuresSolverFactory(std::shared_ptr< LiftingStrategyFactory > lsf, int version=1, bool alt=false, LiftingStatistics *stats=nullptr)
SetToTopIterator(SmallProgressMeasures &spm)
SetToTopIterator & operator*()
SetToTopIterator & operator=(verti v)
SetToTopIterator & operator++(int)
SetToTopIterator & operator++()
SmallProgressMeasures & spm
bool alternate_
whether to use the alternate algorithm
ParityGame::Strategy solve() override
const verti vmap_size_
size of vertex map
virtual ParityGame::Strategy solve_normal()
std::shared_ptr< LiftingStrategyFactory > lsf_
factory used to create lifting strategy
SmallProgressMeasuresSolver(const ParityGame &game, std::shared_ptr< LiftingStrategyFactory > lsf, bool alternate=false, LiftingStatistics *stats=nullptr, const verti *vmap=nullptr, verti vmap_size=0)
SmallProgressMeasuresSolver & operator=(const SmallProgressMeasuresSolver &)=delete
virtual ParityGame::Strategy solve_alternate()
LiftingStatistics * stats_
object to record lifting statistics
const verti * vmap_
current vertex map
static void preprocess_game(ParityGame &game)
SmallProgressMeasuresSolver(const SmallProgressMeasuresSolver &)=delete
void debug_print_vertex(int v) const
long long solve_some(LiftingStrategy2 &ls, long long attempts=work_size)
long long solve_some(LiftingStrategy &ls, long long attempts=work_size)
bool less_than(verti v, const verti *vec2, bool carry=false)
const verti * vmap_
active vertex map (if any)
LiftingStatistics * stats_
statistics object to record lifts
const std::size_t p_
the player to solve for
verti solve_one(LiftingStrategy2 &ls)
SmallProgressMeasures & operator=(const SmallProgressMeasures &)
bool is_top(const verti *vec) const
void get_strategy(ParityGame::Strategy &strat) const
verti * M_
bounds on the SPM vector components
virtual void set_vec(verti v, const verti *src, bool carry)=0
bool take_max(verti v) const
verti get_max_succ(verti v) const
void set_M(const verti *new_M)
std::size_t len_
length of SPM vectors
SmallProgressMeasures(const ParityGame &game, ParityGame::Player player, LiftingStatistics *stats=nullptr, const verti *vmap=nullptr, verti vmap_size=0)
virtual void set_vec_to_top(verti v)=0
verti get_min_succ(verti v) const
SmallProgressMeasures(const SmallProgressMeasures &)
virtual ~SmallProgressMeasures()
bool is_top(verti v) const
bool compare_strict(verti v) const
int vector_cmp(verti v, verti w, int N) const
verti get_ext_succ(verti v) const
bool is_dirty(verti v) const
int vector_cmp(const verti *vec1, const verti *vec2, int N) const
void get_winning_set(ParityGame::Player player, OutputIterator result)
const ParityGame & game() const
bool * dirty_
marks unstable vertices
ParityGame::Player player() const
std::pair< verti, bool > solve_one(LiftingStrategy &ls)
verti vmap_size_
size of vertex map
bool lift_to_top(verti v)
static const int work_size
Maximum number of lifting attempts in a row before checking timer.
verti get_successor(verti v) const
verti get_strategy(verti v) const
void initialize_lifting_strategy(LiftingStrategy2 &ls)
const ParityGame & game_
the game being solved
verti get_ext_succ(verti v, bool take_max) const
bool lift_to(verti v, const verti *vec2, bool carry=false)
ParityGame::Strategy strategy_
current strategy
virtual const verti * vec(verti v) const =0
StaticGraph(const StaticGraph &graph)=delete
void make_random(verti V, unsigned outdeg, EdgeDirection edge_dir, bool scc)
void swap(StaticGraph &g) noexcept
edgei degree(verti v) const
const_iterator succ_end(verti v) const
void reset(verti V, edgei E, EdgeDirection edge_dir)
edgei indegree(verti v) const
EdgeDirection edge_dir() const
void make_subgraph_threads(const StaticGraph &graph, const verti *verts, verti nvert, bool proper, EdgeDirection edge_dir=EdgeDirection::EDGE_NONE)
edgei * predecessor_index_
void make_random_clustered(verti cluster_size, verti V, unsigned outdeg, EdgeDirection edge_dir)
void read_raw(std::istream &is)
const_iterator succ_begin(verti v) const
void assign(edge_list edges, EdgeDirection edge_dir)
void make_subgraph(const StaticGraph &graph, ForwardIterator vertices_begin, ForwardIterator vertices_end, VertexMapT &vertex_map, bool proper, EdgeDirection edge_dir=EdgeDirection::EDGE_NONE)
void make_random_scc(edge_list &edges)
bool has_succ(verti v, verti w) const
void write_raw(std::ostream &os) const
friend constexpr bool operator&(EdgeDirection a, EdgeDirection b)
edge_list get_edges() const
void assign(const StaticGraph &graph)
void remove_edges(edge_list &edges)
StaticGraph & operator=(const StaticGraph &graph)=delete
void make_subgraph(const StaticGraph &graph, ForwardIterator vertices_begin, ForwardIterator vertices_end, bool proper, EdgeDirection edge_dir=EdgeDirection::EDGE_NONE)
void shuffle_vertices(const std::vector< verti > &perm)
const_iterator pred_begin(verti v) const
bool has_pred(verti w, verti v) const
const_iterator pred_end(verti v) const
edgei outdegree(verti v) const
parameterized boolean equation system
int decompose_graph(const StaticGraph &graph, Callback &callback)
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
player_t player
the vertex owner (i.e. next player to move)
priority_t priority
the priority of the vertex between 0 and d (exclusive).
std::size_t operator()(const std::vector< X > &v) const