rename game_info to synthesis_info; move it with the synthesis code
* spot/twaalgos/game.cc, spot/twaalgos/game.hh (game_info): Move... * spot/twaalgos/synthesis.cc, spot/twaalgos/synthesis.hh (synthesis_info): ... here, because this structure contains only synthesis stuff. Also rename "solver" to "algo" to match the ltlsynt option. (solve_game): Move the two argument version of this function here, since that's the only game-related generic function that use synthesis_info. * bin/ltlsynt.cc, tests/core/ltlsynt.test, tests/python/games.ipynb, tests/python/synthesis.py, NEWS: Adjust all uses and mentions.
This commit is contained in:
parent
0ac5bbc05d
commit
bdd20bd1a1
9 changed files with 217 additions and 225 deletions
|
|
@ -1,6 +1,6 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2017, 2018, 2020 Laboratoire de Recherche et Développement
|
||||
// de l'Epita (LRDE).
|
||||
// Copyright (C) 2017-2018, 2020-2021 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
//
|
||||
|
|
@ -768,80 +768,21 @@ namespace spot
|
|||
} // anonymous
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, game_info::solver s)
|
||||
{
|
||||
using solver = game_info::solver;
|
||||
switch (s)
|
||||
{
|
||||
case (solver::DET_SPLIT):
|
||||
os << "ds";
|
||||
break;
|
||||
case (solver::SPLIT_DET):
|
||||
os << "sd";
|
||||
break;
|
||||
case (solver::DPA_SPLIT):
|
||||
os << "ps";
|
||||
break;
|
||||
case (solver::LAR):
|
||||
os << "lar";
|
||||
break;
|
||||
case (solver::LAR_OLD):
|
||||
os << "lar.old";
|
||||
break;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const game_info& gi)
|
||||
{
|
||||
os << "force sbacc: " << gi.force_sbacc << '\n'
|
||||
<< "solver: " << gi.s << '\n'
|
||||
<< "minimization-lvl: " << gi.minimize_lvl << '\n'
|
||||
<< (gi.verbose_stream ? "Is verbose\n" : "Is not verbose\n")
|
||||
<< "the bdd_dict used is " << gi.dict.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
bool solve_parity_game(const twa_graph_ptr& arena)
|
||||
{
|
||||
parity_game pg;
|
||||
return pg.solve(arena);
|
||||
}
|
||||
|
||||
bool solve_game(twa_graph_ptr arena, game_info& gi)
|
||||
bool solve_game(twa_graph_ptr arena)
|
||||
{
|
||||
stopwatch sw;
|
||||
if (gi.bv)
|
||||
sw.start();
|
||||
bool dummy1, dummy2;
|
||||
bool ret;
|
||||
|
||||
if (arena->acc().is_parity(dummy1, dummy2, true))
|
||||
{
|
||||
if (gi.verbose_stream)
|
||||
*(gi.verbose_stream) << "Identified as parity game.\n";
|
||||
ret = solve_parity_game(arena);
|
||||
}
|
||||
else
|
||||
throw std::runtime_error("No solver available for this arena due to its"
|
||||
"acceptance condition.");
|
||||
if (gi.bv)
|
||||
gi.bv->solve_time += sw.stop();
|
||||
if (gi.verbose_stream)
|
||||
*(gi.verbose_stream) << "game solved in "
|
||||
<< gi.bv->solve_time << " seconds\n";
|
||||
return ret;
|
||||
if (!arena->acc().is_parity(dummy1, dummy2, true))
|
||||
throw std::runtime_error
|
||||
("solve_game(): unsupported acceptance condition.");
|
||||
return solve_parity_game(arena);
|
||||
}
|
||||
|
||||
bool
|
||||
solve_game(twa_graph_ptr arena)
|
||||
{
|
||||
game_info dummy1;
|
||||
return solve_game(arena, dummy1);
|
||||
}
|
||||
|
||||
|
||||
void pg_print(std::ostream& os, const const_twa_graph_ptr& arena)
|
||||
{
|
||||
auto owner = ensure_parity_game(arena, "pg_print");
|
||||
|
|
|
|||
|
|
@ -95,83 +95,6 @@ namespace spot
|
|||
SPOT_API
|
||||
bool solve_safety_game(twa_graph_ptr game);
|
||||
|
||||
/// \ingroup games
|
||||
/// \brief Benchmarking and options structure for games and synthesis
|
||||
///
|
||||
/// \note This structure is designed to interface with the algorithms
|
||||
/// found in spot/twaalgos/synthesis.hh and spot/twaalgos/game.hh
|
||||
struct SPOT_API game_info
|
||||
{
|
||||
enum class solver
|
||||
{
|
||||
DET_SPLIT=0,
|
||||
SPLIT_DET,
|
||||
DPA_SPLIT,
|
||||
LAR,
|
||||
LAR_OLD,
|
||||
};
|
||||
|
||||
struct bench_var
|
||||
{
|
||||
double total_time = 0.0;
|
||||
double trans_time = 0.0;
|
||||
double split_time = 0.0;
|
||||
double paritize_time = 0.0;
|
||||
double solve_time = 0.0;
|
||||
double strat2aut_time = 0.0;
|
||||
double aig_time = 0.0;
|
||||
unsigned nb_states_arena = 0;
|
||||
unsigned nb_states_arena_env = 0;
|
||||
unsigned nb_strat_states = 0;
|
||||
unsigned nb_strat_edges = 0;
|
||||
unsigned nb_latches = 0;
|
||||
unsigned nb_gates = 0;
|
||||
bool realizable = false;
|
||||
};
|
||||
|
||||
game_info()
|
||||
: force_sbacc{false},
|
||||
s{solver::LAR},
|
||||
minimize_lvl{2},
|
||||
bv{},
|
||||
verbose_stream{nullptr},
|
||||
dict(make_bdd_dict())
|
||||
{
|
||||
}
|
||||
|
||||
bool force_sbacc;
|
||||
solver s;
|
||||
int minimize_lvl;
|
||||
std::optional<bench_var> bv;
|
||||
std::ostream* verbose_stream;
|
||||
option_map opt;
|
||||
bdd_dict_ptr dict;
|
||||
};
|
||||
|
||||
/// \ingroup games
|
||||
/// \brief Stream solvers
|
||||
SPOT_API std::ostream&
|
||||
operator<<(std::ostream& os, game_info::solver s);
|
||||
|
||||
/// \ingroup games
|
||||
/// \brief Stream benchmarks and options
|
||||
SPOT_API std::ostream &
|
||||
operator<<(std::ostream &os, const game_info &gi);
|
||||
|
||||
/// \ingroup games
|
||||
/// \brief Generic interface for game solving
|
||||
///
|
||||
/// Calls the most suitable solver, depending on the type of game/
|
||||
/// acceptance condition
|
||||
///
|
||||
/// \param arena The game arena
|
||||
/// \param gi struct for options and benchmarking
|
||||
/// \return Whether the initial state is won by player or not
|
||||
/// \pre Relies on the named properties "state-player"
|
||||
/// \post The named properties "strategy" and "state-winner" are set
|
||||
SPOT_API bool
|
||||
solve_game(twa_graph_ptr arena, game_info& gi);
|
||||
|
||||
/// \ingroup games
|
||||
/// \brief Generic interface for game solving
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
// -*- coding: utf-8 -*-
|
||||
// Copyright (C) 2020 Laboratoire de Recherche et
|
||||
// Copyright (C) 2020, 2021 Laboratoire de Recherche et
|
||||
// Développement de l'Epita (LRDE).
|
||||
//
|
||||
// This file is part of Spot, a model checking library.
|
||||
|
|
@ -771,12 +771,49 @@ namespace spot
|
|||
return strat_split;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, synthesis_info::algo s)
|
||||
{
|
||||
using algo = synthesis_info::algo;
|
||||
const char* name = nullptr;
|
||||
switch (s)
|
||||
{
|
||||
case (algo::DET_SPLIT):
|
||||
name = "ds";
|
||||
break;
|
||||
case (algo::SPLIT_DET):
|
||||
name = "sd";
|
||||
break;
|
||||
case (algo::DPA_SPLIT):
|
||||
name = "ps";
|
||||
break;
|
||||
case (algo::LAR):
|
||||
name = "lar";
|
||||
break;
|
||||
case (algo::LAR_OLD):
|
||||
name = "lar.old";
|
||||
break;
|
||||
}
|
||||
return os << name;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& os, const synthesis_info& gi)
|
||||
{
|
||||
os << "force sbacc: " << gi.force_sbacc << '\n'
|
||||
<< "solver: " << gi.s << '\n'
|
||||
<< "minimization-lvl: " << gi.minimize_lvl << '\n'
|
||||
<< (gi.verbose_stream ? "Is verbose\n" : "Is not verbose\n")
|
||||
<< "the bdd_dict used is " << gi.dict.get();
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
namespace // Anonymous create_game
|
||||
{
|
||||
static translator
|
||||
create_translator(game_info& gi)
|
||||
create_translator(synthesis_info& gi)
|
||||
{
|
||||
using solver = game_info::solver;
|
||||
using algo = synthesis_info::algo;
|
||||
|
||||
option_map& extra_options = gi.opt;
|
||||
auto sol = gi.s;
|
||||
|
|
@ -793,19 +830,19 @@ namespace spot
|
|||
translator trans(dict, &extra_options);
|
||||
switch (sol)
|
||||
{
|
||||
case solver::LAR:
|
||||
case algo::LAR:
|
||||
SPOT_FALLTHROUGH;
|
||||
case solver::LAR_OLD:
|
||||
case algo::LAR_OLD:
|
||||
trans.set_type(postprocessor::Generic);
|
||||
trans.set_pref(postprocessor::Deterministic);
|
||||
break;
|
||||
case solver::DPA_SPLIT:
|
||||
case algo::DPA_SPLIT:
|
||||
trans.set_type(postprocessor::ParityMaxOdd);
|
||||
trans.set_pref(postprocessor::Deterministic | postprocessor::Colored);
|
||||
break;
|
||||
case solver::DET_SPLIT:
|
||||
case algo::DET_SPLIT:
|
||||
SPOT_FALLTHROUGH;
|
||||
case solver::SPLIT_DET:
|
||||
case algo::SPLIT_DET:
|
||||
break;
|
||||
}
|
||||
return trans;
|
||||
|
|
@ -838,9 +875,9 @@ namespace spot
|
|||
twa_graph_ptr
|
||||
create_game(const formula& f,
|
||||
const std::vector<std::string>& all_outs,
|
||||
game_info& gi)
|
||||
synthesis_info& gi)
|
||||
{
|
||||
using solver = game_info::solver;
|
||||
using algo = synthesis_info::algo;
|
||||
|
||||
[](std::vector<std::string> sv, std::string msg)
|
||||
{
|
||||
|
|
@ -901,7 +938,7 @@ namespace spot
|
|||
|
||||
switch (gi.s)
|
||||
{
|
||||
case solver::DET_SPLIT:
|
||||
case algo::DET_SPLIT:
|
||||
{
|
||||
if (bv)
|
||||
sw.start();
|
||||
|
|
@ -930,7 +967,7 @@ namespace spot
|
|||
<< tmp->num_states() << " states\n";
|
||||
break;
|
||||
}
|
||||
case solver::DPA_SPLIT:
|
||||
case algo::DPA_SPLIT:
|
||||
{
|
||||
if (bv)
|
||||
sw.start();
|
||||
|
|
@ -953,7 +990,7 @@ namespace spot
|
|||
<< dpa->num_states() << " states\n";
|
||||
break;
|
||||
}
|
||||
case solver::SPLIT_DET:
|
||||
case algo::SPLIT_DET:
|
||||
{
|
||||
sw.start();
|
||||
auto split = split_2step(aut, outs, true);
|
||||
|
|
@ -983,13 +1020,13 @@ namespace spot
|
|||
alternate_players(dpa);
|
||||
break;
|
||||
}
|
||||
case solver::LAR:
|
||||
case algo::LAR:
|
||||
SPOT_FALLTHROUGH;
|
||||
case solver::LAR_OLD:
|
||||
case algo::LAR_OLD:
|
||||
{
|
||||
if (bv)
|
||||
sw.start();
|
||||
if (gi.s == solver::LAR)
|
||||
if (gi.s == algo::LAR)
|
||||
{
|
||||
dpa = to_parity(aut);
|
||||
// reduce_parity is called by to_parity(),
|
||||
|
|
@ -1034,7 +1071,7 @@ namespace spot
|
|||
create_game(const formula& f,
|
||||
const std::vector<std::string>& all_outs)
|
||||
{
|
||||
game_info dummy;
|
||||
synthesis_info dummy;
|
||||
return create_game(f, all_outs, dummy);
|
||||
}
|
||||
|
||||
|
|
@ -1048,7 +1085,7 @@ namespace spot
|
|||
twa_graph_ptr
|
||||
create_game(const std::string& f,
|
||||
const std::vector<std::string>& all_outs,
|
||||
game_info& gi)
|
||||
synthesis_info& gi)
|
||||
{
|
||||
return create_game(parse_formula(f), all_outs, gi);
|
||||
}
|
||||
|
|
@ -1119,7 +1156,7 @@ namespace spot
|
|||
}
|
||||
|
||||
twa_graph_ptr
|
||||
create_strategy(twa_graph_ptr arena, game_info& gi)
|
||||
create_strategy(twa_graph_ptr arena, synthesis_info& gi)
|
||||
{
|
||||
if (!arena)
|
||||
throw std::runtime_error("Arena can not be null");
|
||||
|
|
@ -1158,7 +1195,7 @@ namespace spot
|
|||
twa_graph_ptr
|
||||
create_strategy(twa_graph_ptr arena)
|
||||
{
|
||||
game_info dummy;
|
||||
synthesis_info dummy;
|
||||
return create_strategy(arena, dummy);
|
||||
}
|
||||
|
||||
|
|
@ -1210,7 +1247,7 @@ namespace spot
|
|||
strategy_like_t
|
||||
try_create_direct_strategy(formula f,
|
||||
const std::vector<std::string>& output_aps,
|
||||
game_info &gi)
|
||||
synthesis_info &gi)
|
||||
{
|
||||
formula_2_inout_props form2props(output_aps);
|
||||
auto vs = gi.verbose_stream;
|
||||
|
|
@ -1303,7 +1340,7 @@ namespace spot
|
|||
bool is_ok = ((is_gf_bool_right && left.is_syntactic_recurrence())
|
||||
|| (is_fg_bool_right && left.is_syntactic_guarantee()));
|
||||
|
||||
// TODO: game_info not updated
|
||||
// TODO: synthesis_info not updated
|
||||
// TODO: Verbose
|
||||
auto& bv = gi.bv;
|
||||
stopwatch sw;
|
||||
|
|
@ -1820,4 +1857,29 @@ namespace spot
|
|||
return split_independant_formulas(parse_formula(f), outs);
|
||||
}
|
||||
|
||||
bool
|
||||
solve_game(twa_graph_ptr arena, synthesis_info& gi)
|
||||
{
|
||||
stopwatch sw;
|
||||
if (gi.bv)
|
||||
sw.start();
|
||||
if (gi.verbose_stream)
|
||||
{
|
||||
*(gi.verbose_stream) << "solving game with acceptance: ";
|
||||
std::string name = arena->acc().name();
|
||||
if (!name.empty())
|
||||
*(gi.verbose_stream) << name;
|
||||
else
|
||||
*(gi.verbose_stream) << arena->get_acceptance();
|
||||
*(gi.verbose_stream) << '\n';
|
||||
}
|
||||
bool res = solve_game(arena);
|
||||
if (gi.bv)
|
||||
gi.bv->solve_time += sw.stop();
|
||||
if (gi.verbose_stream)
|
||||
*(gi.verbose_stream) << "game solved in "
|
||||
<< gi.bv->solve_time << " seconds\n";
|
||||
return res;
|
||||
}
|
||||
|
||||
} // spot
|
||||
|
|
|
|||
|
|
@ -85,6 +85,66 @@ namespace spot
|
|||
SPOT_API twa_graph_ptr
|
||||
unsplit_2step(const const_twa_graph_ptr& aut);
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief Benchmarking data and options for synthesis
|
||||
struct SPOT_API synthesis_info
|
||||
{
|
||||
enum class algo
|
||||
{
|
||||
DET_SPLIT=0,
|
||||
SPLIT_DET,
|
||||
DPA_SPLIT,
|
||||
LAR,
|
||||
LAR_OLD,
|
||||
};
|
||||
|
||||
struct bench_var
|
||||
{
|
||||
double total_time = 0.0;
|
||||
double trans_time = 0.0;
|
||||
double split_time = 0.0;
|
||||
double paritize_time = 0.0;
|
||||
double solve_time = 0.0;
|
||||
double strat2aut_time = 0.0;
|
||||
double aig_time = 0.0;
|
||||
unsigned nb_states_arena = 0;
|
||||
unsigned nb_states_arena_env = 0;
|
||||
unsigned nb_strat_states = 0;
|
||||
unsigned nb_strat_edges = 0;
|
||||
unsigned nb_latches = 0;
|
||||
unsigned nb_gates = 0;
|
||||
bool realizable = false;
|
||||
};
|
||||
|
||||
synthesis_info()
|
||||
: force_sbacc{false},
|
||||
s{algo::LAR},
|
||||
minimize_lvl{2},
|
||||
bv{},
|
||||
verbose_stream{nullptr},
|
||||
dict(make_bdd_dict())
|
||||
{
|
||||
}
|
||||
|
||||
bool force_sbacc;
|
||||
algo s;
|
||||
int minimize_lvl;
|
||||
std::optional<bench_var> bv;
|
||||
std::ostream* verbose_stream;
|
||||
option_map opt;
|
||||
bdd_dict_ptr dict;
|
||||
};
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief Stream algo
|
||||
SPOT_API std::ostream&
|
||||
operator<<(std::ostream& os, synthesis_info::algo s);
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief Stream benchmarks and options
|
||||
SPOT_API std::ostream &
|
||||
operator<<(std::ostream &os, const synthesis_info &gi);
|
||||
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief Creates a game from a specification and a set of
|
||||
|
|
@ -92,13 +152,13 @@ namespace spot
|
|||
///
|
||||
/// \param f The specification given as LTL/PSL formula
|
||||
/// \param all_outs The names of all output propositions
|
||||
/// \param gi game_info structure
|
||||
/// \param gi synthesis_info structure
|
||||
/// \note All propositions in the formula that do not appear in all_outs
|
||||
/// arer treated as input variables.
|
||||
SPOT_API twa_graph_ptr
|
||||
create_game(const formula& f,
|
||||
const std::vector<std::string>& all_outs,
|
||||
game_info& gi);
|
||||
synthesis_info& gi);
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief create_game called with default options
|
||||
|
|
@ -111,7 +171,7 @@ namespace spot
|
|||
SPOT_API twa_graph_ptr
|
||||
create_game(const std::string& f,
|
||||
const std::vector<std::string>& all_outs,
|
||||
game_info& gi);
|
||||
synthesis_info& gi);
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief create_game called with default options
|
||||
|
|
@ -159,7 +219,7 @@ namespace spot
|
|||
/// options given in \a gi
|
||||
/// @{
|
||||
SPOT_API twa_graph_ptr
|
||||
create_strategy(twa_graph_ptr arena, game_info& gi);
|
||||
create_strategy(twa_graph_ptr arena, synthesis_info& gi);
|
||||
SPOT_API twa_graph_ptr
|
||||
create_strategy(twa_graph_ptr arena);
|
||||
/// @}
|
||||
|
|
@ -215,6 +275,14 @@ namespace spot
|
|||
SPOT_API strategy_like_t
|
||||
try_create_direct_strategy(formula f,
|
||||
const std::vector<std::string>& output_aps,
|
||||
game_info& gi);
|
||||
synthesis_info& gi);
|
||||
|
||||
/// \ingroup synthesis
|
||||
/// \brief Solve a game, and update synthesis_info
|
||||
///
|
||||
/// This is just a wrapper around the solve_game() function with a
|
||||
/// single argument. This one measure the runtime and update \a gi.
|
||||
SPOT_API bool
|
||||
solve_game(twa_graph_ptr arena, synthesis_info& gi);
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue