mCRL2
Loading...
Searching...
No Matches
ParityGame_verify.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
10#include "mcrl2/pg/ParityGame.h"
11#include "mcrl2/pg/SCC.h"
12
27struct VerifySCC // used by ParityGame::verify()
28{
32 verti * const error;
33
34 int operator() (const verti *scc, std::size_t scc_size)
35 {
36 // Search vertices in this SCC for a vertex with priority `prio`:
37 for (std::size_t i = 0; i < scc_size; ++i)
38 {
39 verti v = scc[i];
40 if (game.priority(v) == prio)
41 {
42 // Cycle detected if |SCC| > 1 or v has a self-edge:
43 if (scc_size > 1 || graph.has_succ(v, v))
44 {
45 if (error) *error = v;
46 return 1;
47 }
48 }
49 }
50 return 0;
51 }
52};
53
54bool ParityGame::verify(const Strategy &s, verti *error) const
55{
56 assert(s.size() == graph_.V());
57
58 /* Make sure winning sets are consistently defined; i.e. only existent
59 edges are used, and there are no transitions that cross winning sets. */
60 for (verti v = 0; v < graph_.V(); ++v)
61 {
62 Player pl = winner(s, v);
63
64 if (pl == player(v)) /* vertex won by owner */
65 {
66 /* Verify that:
67 1. the vertex owner has a strategy (necessarily passes)
68 2. the strategy uses an existing edge
69 3. the strategy doesn't move outside the owner's winning set */
70 if ( s[v] == NO_VERTEX || !graph_.has_succ(v, s[v]) ||
71 winner(s, s[v]) != pl )
72 {
73 if (error) *error = v;
74 return false;
75 }
76 }
77 else /* vertex lost by owner */
78 {
79 // Verify owner has no strategy: (necessarily passes)
80 if (s[v] != NO_VERTEX)
81 {
82 if (error) *error = v;
83 return false;
84 }
85
86 // Verify owner cannot move outside this winning set:
88 it != graph_.succ_end(v); ++it)
89 {
90 if (winner(s, *it) != pl)
91 {
92 if (error) *error = v;
93 return false;
94 }
95 }
96 }
97 }
98
99 // Verify absence of cycles owned by opponent in winning sets
100 for (priority_t prio = 0; prio < d(); ++prio)
101 {
102 /* Create set of edges incident with vertices in the winning set of
103 player (1 - prio%2) consistent with strategy s and incident with
104 vertices of priorities >= prio only. */
106 for (verti v = 0; v < graph_.V(); ++v)
107 {
108 if (priority(v) >= prio && (int)winner(s, v) == (1 - prio%2))
109 {
110 if (s[v] != NO_VERTEX)
111 {
112 if (priority(s[v]) >= prio)
113 {
114 edges.push_back(std::make_pair(v, s[v]));
115 }
116 }
117 else
118 {
120 it != graph_.succ_end(v); ++it)
121 {
122 if (priority(*it) >= prio)
123 {
124 edges.push_back(std::make_pair(v, *it));
125 }
126 }
127 }
128 }
129 }
130
131 /* NOTE: we should NOT compact vertices here, because then we cannot
132 use their indices to determine the priority of vertices in
133 VerifySCC::operator().
134
135 Alternatively, we could compress the priority vector as well.
136 We could share some code with make_subgame() to do this (except that
137 we don't need the player vector, and we don't need bidirectional
138 edges, which require sorting).
139 */
140
141 // Create a subgraph storing successors only:
142 StaticGraph subgraph;
143 subgraph.assign(edges, StaticGraph::EDGE_SUCCESSOR);
144
145 // Find a vertex with priority prio on a cycle:
146 VerifySCC verifier = { *this, subgraph, prio, error };
147 if (decompose_graph(subgraph, verifier) != 0)
148 {
149 // VerifySCC has already set *error here.
150 return false;
151 }
152 }
153 if (error) *error = NO_VERTEX;
154 return true;
155}
std::size_t verti
type used to number vertices
Definition Graph.h:24
#define NO_VERTEX
Definition Graph.h:27
std::size_t priority_t
Definition ParityGame.h:32
player_t
Definition ParityGame.h:35
priority_t priority(verti v) const
Definition ParityGame.h:259
priority_t d() const
Definition ParityGame.h:253
Player player(verti v) const
Definition ParityGame.h:262
StaticGraph graph_
Definition ParityGame.h:318
bool verify(const Strategy &s, verti *error) const
Player winner(const StrategyT &s, verti v) const
std::vector< verti > Strategy
Definition ParityGame.h:97
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 assign(const StaticGraph &graph)
Definition Graph.cpp:288
@ EDGE_SUCCESSOR
Definition Graph.h:86
const verti * const_iterator
Definition Graph.h:66
int decompose_graph(const StaticGraph &graph, Callback &callback)
Definition SCC.h:32
@ error
Definition linearise.cpp:73
const StaticGraph & graph
const ParityGame & game
int operator()(const verti *scc, std::size_t scc_size)
verti *const error
const priority_t prio