mCRL2
Loading...
Searching...
No Matches
SmallProgressMeasures.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2013 University of Twente
2// Copyright (c) 2009-2013 Michael Weber <michaelw@cs.utwente.nl>
3// Copyright (c) 2009-2013 Maks Verver <maksverver@geocities.com>
4// Copyright (c) 2009-2013 Eindhoven University of Technology
5//
6// Distributed under the Boost Software License, Version 1.0.
7// (See accompanying file LICENSE_1_0.txt or copy at
8// http://www.boost.org/LICENSE_1_0.txt)
9
11#include "mcrl2/pg/attractor.h"
12#include "mcrl2/pg/SCC.h"
13
14#include <cstring>
15
17 long long max_lifts )
18 : lifts_attempted_(0), lifts_succeeded_(0), max_lifts_(max_lifts)
19{
20 vertex_stats_.resize(game.graph().V());
21}
22
24{
25 assert(v == NO_VERTEX || v < vertex_stats_.size());
26
29 if (v != NO_VERTEX) ++vertex_stats_[v].first;
30 if (success)
31 {
33 if (v != NO_VERTEX) ++vertex_stats_[v].second;
34 }
35}
36
38 const ParityGame &game, ParityGame::Player player,
39 LiftingStatistics *stats, const verti *vmap, verti vmap_size )
40 : game_(game), p_(player), stats_(stats),
41 vmap_(vmap), vmap_size_(vmap_size),
42 strategy_(game.graph().V(), NO_VERTEX), dirty_(0)
43{
44 assert(p_ == 0 || p_ == 1);
45
46 // Initialize SPM vector bounds
47 len_ = (game_.d() + p_)/2;
48 if (len_ < 1) len_ = 1; // ensure Top is representable
49 M_ = new verti[len_];
50 for (std::size_t n = 0; n < len_; ++n)
51 {
52 std::size_t prio = 2*n + 1 - p_;
53 M_[n] = (prio < game.d()) ? game_.cardinality(prio) + 1 : 0;
54 }
55}
56
58{
59 const verti V = game_.graph().V();
60
61 // Initialize vertices won by the opponent to Top. This is designed to
62 // work in conjunction with preprocess_game() which should have removed
63 // the non-loop outgoing edges for such vertices.
64
65 // N.B. The DecycleSolver and DeloopSolver make this obsolete, so if we
66 // always use those, this code may well be removed!
67
68 // (Alternatively, the winning set propagation in Friedmann's two-sided
69 // approach sets these to top, but in the current implementation this
70 // is only done after iteration, not before!)
71
72 verti cnt = 0;
73 for (verti v = 0; v < V; ++v)
74 {
75 if ( game_.priority(v)%2 == 1 - p_ &&
76 game_.graph().outdegree(v) == 1 &&
77 *game_.graph().succ_begin(v) == v )
78 {
79 strategy_[v] = v;
80 set_top(v);
81 ++cnt;
82 }
83 }
84 mCRL2log(mcrl2::log::debug) << "Initialized " << cnt
85 << "vert" << (cnt == 1 ? "ex" : "ices") << " to top" << std::endl;
86}
87
89{
90 const verti V = game_.graph().V();
91 if (!dirty_) dirty_ = new bool[V];
92 for (verti v = 0; v < V; ++v)
93 {
94 if (is_top(v))
95 {
96 // strategy may not be valid for top vertices!
97 dirty_[v] = false;
98 }
99 else
100 {
101 verti w = get_ext_succ(v, take_max(v));
102 bool dirty = less_than(v, vec(w), compare_strict(v));
103 strategy_[v] = w;
104 dirty_[v] = dirty;
105 if (dirty) ls.push(v);
106 }
107 }
108}
109
111{
112 delete[] M_;
113 delete[] dirty_;
114}
115
117 long long attempts )
118{
119 while (attempts > 0 && solve_one(ls).first != NO_VERTEX) --attempts;
120 return attempts;
121}
122
124 long long attempts )
125{
126 while (attempts > 0 && solve_one(ls) != NO_VERTEX) --attempts;
127 return attempts;
128}
129
131{
132 verti v = ls.next();
133 if (v == NO_VERTEX) return std::make_pair(NO_VERTEX, false);
134
135 bool success = false;
136 if (!is_top(v))
137 {
138 verti w = get_ext_succ(v, take_max(v));
139 if (lift_to(v, vec(w), compare_strict(v)))
140 {
141 ls.lifted(v);
142 success = true;
143 }
144 }
145 if (stats_ != NULL)
146 {
147 stats_->record_lift(vmap_ && v < vmap_size_ ? vmap_[v] : v, success);
148 }
149 return std::make_pair(v, success);
150}
151
153{
154 verti v = ls.pop();
155 if (v == NO_VERTEX) return NO_VERTEX;
156
157 assert(!is_top(v));
158
159 #ifndef NDEBUG
160 bool success =
161 #endif // NDEBUG
163 assert(success);
164 dirty_[v] = false;
165 // debug_print_vertex(v);
166
167 for ( const verti *it = game_.graph().pred_begin(v),
168 *end = game_.graph().pred_end(v); it != end; ++it )
169 {
170 verti u = *it;
171 if (is_top(u)) continue;
172
173 bool changed;
174 if (!take_max(u)) // even-controlled vertex: minimize
175 {
176 if (get_successor(u) == v) // minimum successor increased
177 {
178 verti w = get_min_succ(u);
179 strategy_[u] = w;
180 changed = true;
181 }
182 else // non-minimum successor increased -- no change!
183 {
184 changed = false;
185 }
186 }
187 else // odd-controlled vertex: maximize
188 {
189 if (get_successor(u) == v) // maximum successor increased
190 {
191 changed = true;
192 }
193 else
194 if (vector_cmp(vec(v), vec(get_successor(u)), len_) > 0)
195 { // maximum successor changed
196 strategy_[u] = v;
197 changed = true;
198 }
199 else // non-maximum successor doesn't beat current maximum
200 {
201 changed = false;
202 }
203 }
204 if (changed)
205 {
206 if (is_dirty(u))
207 {
208 ls.bump(u);
209 }
210 else
211 {
212 bool carry = game_.priority(u)%2 != p_;
213 bool dirty = less_than(u, vec(get_successor(u)), carry);
214 if (dirty)
215 {
216 dirty_[u] = true;
217 ls.push(u);
218 }
219 }
220 }
221 }
222
223 if (stats_ != NULL)
224 {
225 stats_->record_lift(vmap_ && v < vmap_size_ ? vmap_[v] : v, true);
226 }
227 return v;
228}
229
231{
232 return (!is_top(v) && game_.player(v) == p_) ? get_min_succ(v) : NO_VERTEX;
233}
234
236{
237 verti V = game_.graph().V();
238 assert(strat.size() == V);
239 for (verti v = 0; v < V; ++v)
240 {
241 verti w = get_strategy(v);
242 if (w != NO_VERTEX) strat[v] = w;
243 }
244}
245
246// Returns the same result as lift_to, but doesn't actually change anything:
247bool SmallProgressMeasures::less_than(verti v, const verti vec2[], bool carry)
248{
249 if (is_top(v)) return false;
250 if (is_top(vec2)) return true;
251 int comparison = vector_cmp(vec(v), vec2, len(v));
252 return comparison < 0 || (comparison <= 0 && carry);
253}
254
255bool SmallProgressMeasures::lift_to(verti v, const verti vec2[], bool carry)
256{
257 if (is_top(v)) return false;
258
259 if (is_top(vec2))
260 {
261 set_top(v);
262 }
263 else
264 {
265 int comparison = vector_cmp(vec(v), vec2, len(v));
266 if (comparison > 0 || (comparison >= 0 && !carry)) return false;
267 set_vec(v, vec2, carry);
268 }
269 return true;
270}
271
272#if 0
274{
275 printf ( "%6d %c p=%d:", (int)v,
276 game_.player(v) == ParityGame::PLAYER_EVEN ? 'E' :
277 game_.player(v) == ParityGame::PLAYER_ODD ? 'O' : '?',
278 (int)game_.priority(v) );
279 if (is_top(v))
280 {
281 printf(" T");
282 }
283 else
284 {
285 for (int p = 0; p < game_.d(); ++p)
286 {
287 printf(" %d", (p%2 == p_) ? 0 : vec(v)[p/2]);
288 }
289 }
290 printf("\n");
291}
292
294{
295 printf("M =");
296 for (int p = 0; p < game_.d(); ++p) printf(" %d", (p%2 == p_) ? 0 : M_[p/2]);
297 printf("\n");
298 for (verti v = 0; v < game_.graph().V(); ++v) debug_print_vertex(v);
299}
300
302{
303 const StaticGraph &graph = game_.graph();
304
305 for (verti v = 0; v < graph.V(); ++v)
306 {
307 if (!is_top(v))
308 {
309 for (int p = 0; p < game_.d(); ++p)
310 {
311 if (p%2 == p_) continue; /* this component is not stored */
312
313 /* Ensure vector values satisfy bounds */
314 if (vec(v)[p/2] >= M_[p/2])
315 {
316 printf( "%d-th component of SPM vector for vertex %d "
317 "out of bounds!\n", p, (int)v );
318 return false;
319 }
320
321 if (p > game_.priority(v) && vec(v)[p/2] != 0)
322 {
323 printf( "%d-th component of SPM vector for vertex %d "
324 "should be zero!\n", p/2, (int)v );
325 return false;
326 }
327 }
328 }
329
330 bool all_ok = true, one_ok = false;
331 for ( StaticGraph::const_iterator it = graph.succ_begin(v);
332 it != graph.succ_end(v); ++it )
333 {
334 bool ok = is_top(v) ||
335 vector_cmp(v, *it, len(v)) >= compare_strict(v);
336 one_ok = one_ok || ok;
337 all_ok = all_ok && ok;
338 }
339
340 if (!(game_.player(v) == p_ ? one_ok : all_ok))
341 {
342 printf( "order constraint not satisfied for vertex %d with "
343 "priority %d and player %s!\n", v, game_.priority(v),
344 game_.player(v) == PLAYER_EVEN ? "even" :
345 game_.player(v) == PLAYER_ODD ? "odd" : "???" );
346 return false;
347 }
348 }
349 return true;
350}
351#endif
352
353//
354// SmallProgressMeasuresSolver
355//
356
358 const ParityGame &game, std::shared_ptr<LiftingStrategyFactory> lsf, bool alternate,
359 LiftingStatistics *stats, const verti *vmap, verti vmap_size )
360 : ParityGameSolver(game), lsf_(lsf), alternate_(alternate),
361 stats_(stats), vmap_(vmap), vmap_size_(vmap_size)
362{}
363
365{
367}
368
370{
372 std::vector<verti> won_by_odd;
373
374 {
375 mCRL2log(mcrl2::log::verbose) << "Solving for Even..." << std::endl;
376 DenseSPM spm( game(), PLAYER_EVEN,
378 std::unique_ptr<LiftingStrategy> ls(lsf_->create(game_, spm));
379 while (spm.solve_some(*ls) == 0)
380 {
381 if (aborted()) return ParityGame::Strategy();
382 }
383 spm.get_strategy(strategy);
385 std::back_insert_iterator<std::vector<verti> >(won_by_odd) );
386#ifdef DEBUG
387 mCRL2log(mcrl2::log::verbose) << "Verifying small progress measures." << std::endl;
388 assert(spm.verify_solution());
389#endif
390 }
391
392 if (!won_by_odd.empty())
393 {
394 // Make a dual subgame of the vertices won by player Odd
395 ParityGame subgame;
396 mCRL2log(mcrl2::log::verbose) << "Constructing subgame of size "
397 << won_by_odd.size() << " to solve for Odd..." << std::endl;
398 subgame.make_subgame(game_, won_by_odd.begin(), won_by_odd.end(), true);
399 subgame.compress_priorities();
400
401 // Create vertex map to use:
402 std::vector<verti> submap_data;
403 verti *submap = &won_by_odd[0];
404 std::size_t submap_size = won_by_odd.size();
405 if (vmap_)
406 {
407 submap_data = won_by_odd;
408 submap = &submap_data[0];
409 merge_vertex_maps(submap, submap + submap_size, vmap_, vmap_size_);
410 }
411
412 // Second pass; solve subgame of vertices won by Odd:
413 mCRL2log(mcrl2::log::verbose) << "Solving for Odd..." << std::endl;
414 DenseSPM spm( subgame, PLAYER_ODD,
415 stats_, submap, submap_size );
416 std::unique_ptr<LiftingStrategy> ls(lsf_->create(subgame, spm));
417 while (spm.solve_some(*ls) == 0)
418 {
419 if (aborted()) return ParityGame::Strategy();
420 }
421 ParityGame::Strategy substrat(won_by_odd.size(), NO_VERTEX);
422 spm.get_strategy(substrat);
423 merge_strategies(strategy, substrat, won_by_odd);
424#ifdef DEBUG
425 mCRL2log(mcrl2::log::debug) << "Verifying small progress measures." << std::endl;
426 assert(spm.verify_solution());
427#endif
428 }
429
430 return strategy;
431}
432
434{
435 // Create two SPM and two lifting strategy instances:
436 std::unique_ptr<SmallProgressMeasures> spm[2];
437 spm[0].reset(new DenseSPM( game_, PLAYER_EVEN,
439 spm[1].reset(new DenseSPM( game_, PLAYER_ODD,
441
442 // Solve games alternatingly:
443 int player = 0;
444 bool half_solved = false;
445 while (!half_solved)
446 {
447 mCRL2log(mcrl2::log::verbose) << "Switching to "
448 << (player == 0 ? "normal" : "dual") << " game..." << std::endl;
449 std::unique_ptr<LiftingStrategy> ls(lsf_->create(game_, *spm[player]));
450
451 /* Note: work size should be large enough so that dumb strategies like
452 linear lifting are still able to detect termination! */
453 for ( long long work = game_.graph().V(); work > 0 && !half_solved;
455 {
456 half_solved = spm[player]->solve_some(*ls) > 0;
457 if (aborted()) return ParityGame::Strategy();
458 }
459
460 mCRL2log(mcrl2::log::verbose) << "Propagating solved vertices to other game..." << std::endl;
461 spm[player]->get_winning_set( (ParityGame::Player)player,
462 SetToTopIterator(*spm[1 - player]) );
463 player = 1 - player;
464 }
465
466 // One game is solved; solve other game completely too:
467 mCRL2log(mcrl2::log::verbose) << "Finishing " << (player == 0 ? "normal" : "dual") << "game..." << std::endl;
468 std::unique_ptr<LiftingStrategy> ls(lsf_->create(game_, *spm[player]));
469 while (spm[player]->solve_some(*ls) == 0)
470 {
471 if (aborted()) return ParityGame::Strategy();
472 }
473
474 // Retrieve combined strategies:
476 spm[0]->get_strategy(strategy);
477 spm[1]->get_strategy(strategy);
478
479 return strategy;
480}
481
483{
484 StaticGraph &graph = const_cast<StaticGraph&>(game.graph()); // HACK
485 StaticGraph::edge_list obsolete_edges;
486
487 for (verti v = 0; v < graph.V(); ++v)
488 {
489 if (graph.has_succ(v, v))
490 {
491 // Decide what to do with the edges:
492 if ((int)game.priority(v)%2 == (int)game.player(v))
493 {
494 // Self-edge is beneficial; remove other edges
495 for ( StaticGraph::const_iterator it = graph.succ_begin(v);
496 it != graph.succ_end(v); ++it )
497 {
498 if (*it != v)
499 {
500 obsolete_edges.push_back(std::make_pair(v, *it));
501 }
502 }
503 }
504 else
505 if (graph.outdegree(v) > 1)
506 {
507 // Self-edge is detrimental; remove it
508 obsolete_edges.push_back(std::make_pair(v, v));
509 }
510 }
511 }
512 graph.remove_edges(obsolete_edges);
513}
514
515
516//
517// SmallProgressMeasuresSolver2
518//
519
521 const ParityGame &game, std::shared_ptr<LiftingStrategyFactory> lsf, bool alternate,
522 LiftingStatistics *stats, const verti *vmap, verti vmap_size )
523 : SmallProgressMeasuresSolver( game, lsf, alternate,
524 stats, vmap, vmap_size)
525{
526}
527
529{
531 std::vector<verti> won_by_odd;
532
533 {
534 mCRL2log(mcrl2::log::verbose) << "Solving for Even..." << std::endl;
535 DenseSPM spm( game(), PLAYER_EVEN,
537 std::unique_ptr<LiftingStrategy2> ls(lsf_->create2(game_, spm));
539 while (spm.solve_some(*ls) == 0)
540 {
541 if (aborted()) return ParityGame::Strategy();
542 }
543 spm.get_strategy(strategy);
545 std::back_insert_iterator<std::vector<verti> >(won_by_odd) );
546#ifdef DEBUG
547 mCRL2log(mcrl2::log::debug) << "Verifying small progress measures." << std::endl;
548 assert(spm.verify_solution());
549#endif
550 }
551
552 if (!won_by_odd.empty())
553 {
554 // Make a dual subgame of the vertices won by player Odd
555 ParityGame subgame;
556 mCRL2log(mcrl2::log::verbose) << "Constructing subgame of size "
557 << won_by_odd.size() << " to solve for Odd..." << std::endl;
558 subgame.make_subgame(game_, won_by_odd.begin(), won_by_odd.end(), true);
559 subgame.compress_priorities();
560
561 // Create vertex map to use:
562 std::vector<verti> submap_data;
563 verti *submap = &won_by_odd[0];
564 std::size_t submap_size = won_by_odd.size();
565 if (vmap_)
566 {
567 submap_data = won_by_odd;
568 submap = &submap_data[0];
569 merge_vertex_maps(submap, submap + submap_size, vmap_, vmap_size_);
570 }
571
572 // Second pass; solve subgame of vertices won by Odd:
573 mCRL2log(mcrl2::log::verbose) << "Solving for Odd..." << std::endl;
574 DenseSPM spm( subgame, PLAYER_ODD,
575 stats_, submap, submap_size );
576 std::unique_ptr<LiftingStrategy2> ls(lsf_->create2(subgame, spm));
578 while (spm.solve_some(*ls) == 0)
579 {
580 if (aborted()) return ParityGame::Strategy();
581 }
582 ParityGame::Strategy substrat(won_by_odd.size(), NO_VERTEX);
583 spm.get_strategy(substrat);
584 merge_strategies(strategy, substrat, won_by_odd);
585#ifdef DEBUG
586 mCRL2log(mcrl2::log::debug) << "Verifying small progress measures." << std::endl;
587 assert(spm.verify_solution());
588#endif
589 }
590
591 return strategy;
592}
593
595{
596 // Create two SPM and two lifting strategy instances:
597 std::unique_ptr<SmallProgressMeasures> spm[2];
598 spm[0].reset(new DenseSPM( game_, PLAYER_EVEN,
600 spm[1].reset(new DenseSPM( game_, PLAYER_ODD,
602
603 // Solve games alternatingly:
604 int player = 0;
605 bool half_solved = false;
606 while (!half_solved)
607 {
608 mCRL2log(mcrl2::log::verbose) << "Switching to " << (player == 0 ? "normal" : "dual") << " game..." << std::endl;
609 std::unique_ptr<LiftingStrategy2> ls(lsf_->create2(game_, *spm[player]));
610 spm[player]->initialize_lifting_strategy(*ls);
611
612 for ( long long work = game_.graph().V(); work > 0 && !half_solved;
614 {
615 half_solved = spm[player]->solve_some(*ls) > 0;
616 if (aborted()) return ParityGame::Strategy();
617 }
618
619 mCRL2log(mcrl2::log::verbose) << "Propagating solved vertices to other game..." << std::endl;
620 spm[player]->get_winning_set( (ParityGame::Player)player,
621 SetToTopIterator(*spm[1 - player]) );
622 player = 1 - player;
623 }
624
625 // One game is solved; solve other game completely too:
626 mCRL2log(mcrl2::log::verbose) << "Finishing " << (player == 0 ? "normal" : "dual") << " game..." << std::endl;
627 std::unique_ptr<LiftingStrategy2> ls(lsf_->create2(game_, *spm[player]));
628 spm[player]->initialize_lifting_strategy(*ls);
629 while (spm[player]->solve_some(*ls) == 0)
630 {
631 if (aborted()) return ParityGame::Strategy();
632 }
633
634 // Retrieve combined strategies:
636 spm[0]->get_strategy(strategy);
637 spm[1]->get_strategy(strategy);
638
639 return strategy;
640}
641
642
643//
644// SmallProgressMeasuresSolverFactory
645//
646
648 std::shared_ptr<LiftingStrategyFactory> lsf, int version, bool alt,
649 LiftingStatistics *stats )
650 : lsf_(lsf), version_(version), alt_(alt), stats_(stats)
651{}
652
654 const ParityGame &game, const verti *vmap, verti vmap_size )
655{
656 assert(version_ == 1 || version_ == 2);
657 if (version_ == 1)
658 {
660 game, lsf_, alt_, stats_, vmap, vmap_size );
661 }
662 if (version_ == 2)
663 {
665 game, lsf_, alt_, stats_, vmap, vmap_size );
666 }
667 return 0;
668}
669
670//
671// DenseSPM
672//
673
675 LiftingStatistics *stats,
676 const verti *vertex_map, verti vertex_map_size )
677 : SmallProgressMeasures(game, player, stats, vertex_map, vertex_map_size),
678 spm_(new verti[(std::size_t)len_*game.graph().V()]())
679{
681}
682
684{
685 delete[] spm_;
686}
687
688void DenseSPM::set_vec(verti v, const verti src[], bool carry)
689{
690 verti *dst = &spm_[(std::size_t)len_*v];
691 const int l = len(v); // l: vector length
692 int k = l; // k: position of last overflow
693 for (int n = l - 1; n >= 0; --n)
694 {
695 dst[n] = src[n] + carry;
696 carry = (dst[n] >= M_[n]);
697 if (carry) k = n;
698 }
699 while (k < l) dst[k++] = 0;
700 if (carry) set_top(v);
701}
702
704{
705 spm_[(std::size_t)len_*v] = NO_VERTEX;
706}
std::size_t verti
type used to number vertices
Definition Graph.h:24
#define NO_VERTEX
Definition Graph.h:27
void merge_vertex_maps(ForwardIterator begin, ForwardIterator end, const verti *old_map, verti old_map_size)
void merge_strategies(std::vector< verti > &strategy, const std::vector< verti > &substrat, const std::vector< verti > &vertex_map)
player_t
Definition ParityGame.h:35
@ PLAYER_ODD
Odd (1)
Definition ParityGame.h:36
@ PLAYER_EVEN
Even (0)
Definition ParityGame.h:35
static void abort_all()
Abort all abortable processes.
Definition Abortable.h:22
bool aborted()
Returns whether this instance has been aborted.
Definition Abortable.h:25
verti * spm_
array storing the SPM vector data
DenseSPM(const ParityGame &game, ParityGame::Player player, LiftingStatistics *stats=0, const verti *vertex_map=0, verti vertex_map_size=0)
void set_vec_to_top(verti v)
void set_vec(verti v, const verti src[], bool carry)
LiftingStatistics(const ParityGame &game, long long max_lifts=-1)
std::vector< std::pair< long long, long long > > vertex_stats_
void record_lift(verti v, bool success)
virtual void push(verti vertex)=0
virtual verti pop()=0
virtual void bump(verti vertex)=0
virtual void lifted(verti vertex)=0
virtual verti next()=0
const ParityGame & game() const
const ParityGame & game_
Game being solved.
priority_t priority(verti v) const
Definition ParityGame.h:259
verti cardinality(int p) const
Definition ParityGame.h:266
priority_t d() const
Definition ParityGame.h:253
void make_subgame(const ParityGame &game, ForwardIterator vertices_begin, ForwardIterator vertices_end, bool proper, StaticGraph::EdgeDirection edge_dir=StaticGraph::EDGE_NONE)
Player player(verti v) const
Definition ParityGame.h:262
void compress_priorities(const verti cardinality[]=0, bool preserve_parity=true)
const StaticGraph & graph() const
Definition ParityGame.h:256
std::vector< verti > Strategy
Definition ParityGame.h:97
SmallProgressMeasuresSolver2(const ParityGame &game, std::shared_ptr< LiftingStrategyFactory > lsf, bool alternate=false, LiftingStatistics *stats=0, const verti *vmap=0, verti vmap_size=0)
SmallProgressMeasuresSolverFactory(std::shared_ptr< LiftingStrategyFactory > lsf, int version=1, bool alt=false, LiftingStatistics *stats=0)
ParityGameSolver * create(const ParityGame &game, const verti *vmap, verti vmap_size)
std::shared_ptr< LiftingStrategyFactory > lsf_
bool alternate_
whether to use the alternate algorithm
const verti vmap_size_
size of vertex map
virtual ParityGame::Strategy solve_normal()
std::shared_ptr< LiftingStrategyFactory > lsf_
factory used to create lifting strategy
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 ParityGame &game, std::shared_ptr< LiftingStrategyFactory > lsf, bool alternate=false, LiftingStatistics *stats=0, const verti *vmap=0, verti vmap_size=0)
void debug_print_vertex(int v) const
long long solve_some(LiftingStrategy &ls, long long attempts=work_size)
const verti * vmap_
active vertex map (if any)
LiftingStatistics * stats_
statistics object to record lifts
SmallProgressMeasures(const ParityGame &game, ParityGame::Player player, LiftingStatistics *stats=0, const verti *vmap=0, verti vmap_size=0)
const std::size_t p_
the player to solve for
verti * M_
bounds on the SPM vector components
bool take_max(verti v) const
std::size_t len_
length of SPM vectors
bool is_top(const verti vec[]) const
verti get_min_succ(verti v) const
void debug_print() const
bool less_than(verti v, const verti vec2[], bool carry=0)
bool compare_strict(verti v) const
bool is_dirty(verti v) const
bool lift_to(verti v, const verti vec2[], bool carry=0)
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
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
int vector_cmp(const verti vec1[], const verti vec2[], int N) const
void initialize_lifting_strategy(LiftingStrategy2 &ls)
const ParityGame & game_
the game being solved
verti get_ext_succ(verti v, bool take_max) const
virtual void set_vec(verti v, const verti src[], bool carry)=0
ParityGame::Strategy strategy_
current strategy
virtual const verti * vec(verti v) const =0
std::vector< std::pair< verti, verti > > edge_list
Definition Graph.h:74
const_iterator succ_end(verti v) const
Definition Graph.h:193
const_iterator succ_begin(verti v) const
Definition Graph.h:188
bool has_succ(verti v, verti w) const
Definition Graph.h:208
verti V() const
Definition Graph.h:179
void remove_edges(edge_list &edges)
Definition Graph.cpp:365
const_iterator pred_begin(verti v) const
Definition Graph.h:198
const_iterator pred_end(verti v) const
Definition Graph.h:203
edgei outdegree(verti v) const
Definition Graph.h:223
const verti * const_iterator
Definition Graph.h:66
#define mCRL2log(LEVEL)
mCRL2log(LEVEL) provides the stream used to log.
Definition logger.h:391
@ verbose
Definition logger.h:37
STL namespace.