ltlsynt: fix the construction of the arena

* bin/ltlsynt.cc: implement it
* tests/core/ltlsynt.test: update tests
This commit is contained in:
Maximilien Colange 2018-03-13 11:58:48 +01:00
parent 5d80cc556c
commit 0e29d30d1b
2 changed files with 40 additions and 27 deletions

View file

@ -185,32 +185,47 @@ namespace
return split; return split;
} }
// Generates a vector indicating the owner of each state, with the // Ensures that the game is complete for player 0.
// convention that false is player 0 (the environment) and true is player 1 // Also computes the owner of each state (false for player 0, i.e. env).
// (the controller). Starting with player 0 on the initial state, the owner // Initial state belongs to Player 0 and the game is turn-based.
// is switched after each transition.
static std::vector<bool> static std::vector<bool>
make_alternating_owner(const spot::twa_graph_ptr& dpa, complete_env(spot::twa_graph_ptr& arena)
bool init_owner = false)
{ {
std::vector<bool> seen(dpa->num_states(), false); unsigned sink_env = arena->new_state();
std::vector<unsigned> todo({dpa->get_init_state_number()}); unsigned sink_con = arena->new_state();
std::vector<bool> owner(dpa->num_states());
owner[dpa->get_init_state_number()] = init_owner; auto um = arena->acc().unsat_mark();
if (!um.first)
throw std::runtime_error("game winning condition is a tautology");
arena->new_edge(sink_con, sink_env, bddtrue, um.second);
arena->new_edge(sink_env, sink_con, bddtrue, um.second);
std::vector<bool> seen(arena->num_states(), false);
std::vector<unsigned> todo({arena->get_init_state_number()});
std::vector<bool> owner(arena->num_states(), false);
owner[arena->get_init_state_number()] = false;
owner[sink_env] = true;
while (!todo.empty()) while (!todo.empty())
{ {
unsigned src = todo.back(); unsigned src = todo.back();
todo.pop_back(); todo.pop_back();
seen[src] = true; seen[src] = true;
for (auto& e: dpa->out(src)) bdd missing = bddtrue;
for (const auto& e: arena->out(src))
{ {
if (!owner[src])
missing -= e.cond;
if (!seen[e.dst]) if (!seen[e.dst])
{ {
owner[e.dst] = !owner[src]; owner[e.dst] = !owner[src];
todo.push_back(e.dst); todo.push_back(e.dst);
} }
} }
if (!owner[src] && missing != bddfalse)
arena->new_edge(src, sink_con, missing, um.second);
} }
return owner; return owner;
} }
@ -219,12 +234,11 @@ namespace
{ {
auto dpa = spot::tgba_determinize(split); auto dpa = spot::tgba_determinize(split);
dpa->merge_edges(); dpa->merge_edges();
spot::complete_here(dpa); if (opt_print_pg)
dpa = spot::sbacc(dpa);
spot::colorize_parity_here(dpa, true); spot::colorize_parity_here(dpa, true);
spot::change_parity_here(dpa, spot::parity_kind_max, spot::change_parity_here(dpa, spot::parity_kind_max,
spot::parity_style_odd); spot::parity_style_odd);
if (opt_print_pg)
dpa = spot::sbacc(dpa);
bool max, odd; bool max, odd;
dpa->acc().is_parity(max, odd); dpa->acc().is_parity(max, odd);
assert(max && odd); assert(max && odd);
@ -330,7 +344,7 @@ namespace
auto dpa = to_dpa(split); auto dpa = to_dpa(split);
if (verbose) if (verbose)
std::cerr << "determinization done" << std::endl; std::cerr << "determinization done" << std::endl;
auto owner = make_alternating_owner(dpa); auto owner = complete_env(dpa);
auto pg = spot::parity_game(dpa, owner); auto pg = spot::parity_game(dpa, owner);
if (verbose) if (verbose)
std::cerr << "parity game built" << std::endl; std::cerr << "parity game built" << std::endl;

View file

@ -23,24 +23,23 @@
set -e set -e
cat >exp <<EOF cat >exp <<EOF
parity 15; parity 16;
0 4294967295 0 1,2 "INIT"; 0 0 0 1,2 "INIT";
2 4 1 3; 2 0 1 3;
3 2 0 4,5; 3 2 0 4,5;
5 4294967295 1 3,6; 5 0 1 3,6;
6 3 0 4,5; 6 3 0 4,5;
4 4294967295 1 7,8; 4 0 1 7,8;
8 2 0 9,10; 8 2 0 9,10;
10 3 1 3,11; 10 3 1 3,11;
11 0 0 4,5; 11 0 0 4,5;
9 0 1 8,12; 9 0 1 8,12;
12 1 0 10,13; 12 1 0 9,10;
13 4294967295 1 8,12; 7 1 0 4,13;
7 1 0 4,14; 13 2 1 3,6;
14 2 1 3,6; 4 0 1 7,8;
4 4294967295 1 7,8; 1 3 1 3,14;
1 3 1 3,15; 14 3 0 1,2;
15 3 0 1,2;
EOF EOF
ltlsynt --ins='a' --outs='b' -f 'GFa <-> GFb' --print-pg > out ltlsynt --ins='a' --outs='b' -f 'GFa <-> GFb' --print-pg > out
diff out exp diff out exp