Skip to content

Commit

Permalink
Slight refactor of Verifier
Browse files Browse the repository at this point in the history
  • Loading branch information
trolando committed Jul 25, 2024
1 parent cab61ec commit 691db00
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 29 deletions.
4 changes: 2 additions & 2 deletions src/tools/solve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,11 @@ int main(int argc, char **argv)
if (options.count("v")) {
try {
out << "verifying solution..." << std::endl;
Verifier v(&pg, out);
Verifier v(pg, out);
double vbegin = wctime();
v.verify(true, true, true);
double vend = wctime();
out << "solution verified (" << v.n_strategies << " strategies)." << std::endl;
out << "solution verified (" << v.numberOfStrategies() << " strategies)." << std::endl;
out << "verification took " << std::fixed << (vend - vbegin) << " sec." << std::endl;
} catch (const char *err) {
out << "verification error: " << err << std::endl;
Expand Down
2 changes: 1 addition & 1 deletion src/tools/verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ main(int argc, const char **argv)

pg.sort();

Verifier v(&pg, std::cout);
Verifier v(pg, std::cout);
auto begin = wctime();
v.verify(true);
auto end = wctime();
Expand Down
44 changes: 22 additions & 22 deletions src/verifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ void
Verifier::verify(bool fullgame, bool even, bool odd)
{
// ensure the vertices are ordered properly
game->ensure_sorted();
game.ensure_sorted();
// ensure that the arrays are built
game->build_in_array(false);
game.build_in_array(false);

const int n_vertices = game->vertexcount();
const int n_vertices = game.vertexcount();

/**
* The first loop removes all edges from "won" vertices that are not the strategy.
Expand All @@ -47,38 +47,38 @@ Verifier::verify(bool fullgame, bool even, bool odd)
*/
for (int i=0; i<n_vertices; i++) {
// (for full solutions) check whether every vertex is won
if (!game->solved[i]) {
if (!game.solved[i]) {
if (fullgame) throw "not every vertex is won";
else continue;
}

const bool winner = game->winner[i];
const bool winner = game.winner[i];

if (winner == 0 and !even) continue; // whatever
if (winner == 1 and !odd) continue; // whatever

if (winner == game->owner(i)) {
if (winner == game.owner(i)) {
// if winner, check whether the strategy stays in the dominion
int str = game->strategy[i];
int str = game.strategy[i];
if (str == -1) {
throw "winning vertex has no strategy";
} else if (!game->has_edge(i, str)) {
} else if (!game.has_edge(i, str)) {
throw "strategy is not a valid move";
} else if (!game->solved[str] or game->winner[str] != winner) {
} else if (!game.solved[str] or game.winner[str] != winner) {
throw "strategy leaves dominion";
}
n_strategies++; // number of checked strategies
} else {
// if loser, check whether the loser can escape
for (auto curedge = game->outs(i); *curedge != -1; curedge++) {
for (auto curedge = game.outs(i); *curedge != -1; curedge++) {
int to = *curedge;
if (!game->solved[to] or game->winner[to] != winner) {
logger << "escape edge from " << game->label_vertex(i) << " to " << game->label_vertex(to) << std::endl;
if (!game.solved[to] or game.winner[to] != winner) {
logger << "escape edge from " << game.label_vertex(i) << " to " << game.label_vertex(to) << std::endl;
throw "loser can escape";
}
}
// and of course check that no strategy is set
if (game->strategy[i] != -1) throw "losing vertex has strategy";
if (game.strategy[i] != -1) throw "losing vertex has strategy";
}
}

Expand All @@ -95,10 +95,10 @@ Verifier::verify(bool fullgame, bool even, bool odd)

for (int i=n_vertices-1; i>=0; i--) {
// only if a dominion
if (!game->solved[i]) continue;
if (!game.solved[i]) continue;

int prio = game->priority(i);
int winner = game->winner[i];
int prio = game.priority(i);
int winner = game.winner[i];

// only compute SCC for a (probably) top vertex
if (winner == 0 and !even) continue; // don't check even dominions
Expand Down Expand Up @@ -134,8 +134,8 @@ Verifier::verify(bool fullgame, bool even, bool odd)
*/
int min = low[v];
bool pushed = false;
if (game->strategy[v] != -1) {
int to = game->strategy[v];
if (game.strategy[v] != -1) {
int to = game.strategy[v];
if (to > i) {
// skip if to higher priority
} else if (done[to] == prio) {
Expand All @@ -149,7 +149,7 @@ Verifier::verify(bool fullgame, bool even, bool odd)
if (low[to] < min) min = low[to];
}
} else {
for (auto curedge = game->outs(v); *curedge != -1; curedge++) {
for (auto curedge = game.outs(v); *curedge != -1; curedge++) {
int to = *curedge;
// skip if to higher priority
if (to > i) continue;
Expand Down Expand Up @@ -187,14 +187,14 @@ Verifier::verify(bool fullgame, bool even, bool odd)
int scc_size = 0;
for (auto it=res.rbegin(); it!=res.rend(); it++) {
int n = *it;
if (game->priority(n) > max_prio) max_prio = game->priority(n);
if (game.priority(n) > max_prio) max_prio = game.priority(n);
scc_size++;
done[n] = prio; // mark as done at prio
if (n == v) break;
}

bool cycles = scc_size > 1 or game->strategy[v] == v or
(game->strategy[v] == -1 and game->has_edge(v, v));
bool cycles = scc_size > 1 or game.strategy[v] == v or
(game.strategy[v] == -1 and game.has_edge(v, v));

if (cycles && (max_prio&1) == (prio&1)) {
/**
Expand Down
13 changes: 10 additions & 3 deletions src/verifier.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,22 @@ namespace pg {
class Verifier
{
public:
Verifier(Game* pg, std::ostream &lgr) : game(pg), logger(lgr) { }
Verifier(Game& game, std::ostream &logger) : game(game), logger(logger) { }

/**
* Verify the game strategy.
*/
void verify(bool fullgame=true, bool even=true, bool odd=true);

int n_strategies = 0;
/**
* Return the number of checked strategies in the game.
*/
int numberOfStrategies(void) { return n_strategies; }

protected:
Game *game;
Game& game; // TODO: this should be "const"
std::ostream &logger;
int n_strategies = 0;
};

}
Expand Down
2 changes: 1 addition & 1 deletion test/test_solvers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ test_solver(Game &game, const std::string& solverid, double &time, std::ostream
game.copy_solution(copy);

try {
Verifier v(&game, log);
Verifier v(game, log);
v.verify(true, true, true);
} catch (const char *err) {
log << "verification error: " << err << std::endl;
Expand Down

0 comments on commit 691db00

Please sign in to comment.