Remove do_simplify opt from split_2step
Removing this option to guarante that all arenas are alternating * spot/twaalgos/synthesis.hh: Here * spot/twaalgos/synthesis.cc: Here * spot/twaalgos/mealy_machine.cc: API change * tests/python/aiger.py: API change * tests/python/mealy.py: API change * tests/python/split.py: API change
This commit is contained in:
parent
ddda68403f
commit
406bc8ed17
6 changed files with 27 additions and 63 deletions
|
|
@ -507,7 +507,7 @@ namespace spot
|
||||||
// Split if the initial aut was split
|
// Split if the initial aut was split
|
||||||
if (orig_is_split)
|
if (orig_is_split)
|
||||||
{
|
{
|
||||||
mmc = split_2step(mmc, outs, false, false);
|
mmc = split_2step(mmc, outs, false);
|
||||||
bool orig_init_player =
|
bool orig_init_player =
|
||||||
mm->get_named_prop<std::vector<bool>>("state-player")
|
mm->get_named_prop<std::vector<bool>>("state-player")
|
||||||
->at(mm->get_init_state_number());
|
->at(mm->get_init_state_number());
|
||||||
|
|
@ -582,7 +582,7 @@ namespace spot
|
||||||
mm->purge_unreachable_states();
|
mm->purge_unreachable_states();
|
||||||
if (orig_is_split)
|
if (orig_is_split)
|
||||||
{
|
{
|
||||||
mm = split_2step(mm, outs, false, false);
|
mm = split_2step(mm, outs, false);
|
||||||
alternate_players(mm, init_player, false);
|
alternate_players(mm, init_player, false);
|
||||||
mm->set_named_prop("synthesis-outputs", new bdd(outs));
|
mm->set_named_prop("synthesis-outputs", new bdd(outs));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,7 @@ namespace spot
|
||||||
{
|
{
|
||||||
twa_graph_ptr
|
twa_graph_ptr
|
||||||
split_2step(const const_twa_graph_ptr& aut,
|
split_2step(const const_twa_graph_ptr& aut,
|
||||||
const bdd& output_bdd, bool complete_env,
|
const bdd& output_bdd, bool complete_env)
|
||||||
bool do_simplify)
|
|
||||||
{
|
{
|
||||||
auto split = make_twa_graph(aut->get_dict());
|
auto split = make_twa_graph(aut->get_dict());
|
||||||
split->copy_ap_of(aut);
|
split->copy_ap_of(aut);
|
||||||
|
|
@ -216,25 +215,6 @@ namespace spot
|
||||||
e_cache.clear();
|
e_cache.clear();
|
||||||
|
|
||||||
auto out_cont = aut->out(src);
|
auto out_cont = aut->out(src);
|
||||||
// Short-cut if we do not want to
|
|
||||||
// split the edges of nodes that have
|
|
||||||
// a single outgoing edge
|
|
||||||
if (do_simplify
|
|
||||||
&& (++out_cont.begin()) == out_cont.end())
|
|
||||||
{
|
|
||||||
// "copy" the edge
|
|
||||||
const auto& e = *out_cont.begin();
|
|
||||||
split->new_edge(src, e.dst, e.cond, e.acc);
|
|
||||||
// Check if it needs to be completed
|
|
||||||
if (complete_env)
|
|
||||||
{
|
|
||||||
bdd missing = bddtrue - bdd_exist(e.cond, output_bdd);
|
|
||||||
if (missing != bddfalse)
|
|
||||||
split->new_edge(src, get_sink_con_state(), missing);
|
|
||||||
}
|
|
||||||
// We are done for this state
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid looping over all minterms
|
// Avoid looping over all minterms
|
||||||
// we only loop over the minterms that actually exist
|
// we only loop over the minterms that actually exist
|
||||||
|
|
@ -433,9 +413,11 @@ namespace spot
|
||||||
out->copy_acceptance_of(aut);
|
out->copy_acceptance_of(aut);
|
||||||
out->copy_ap_of(aut);
|
out->copy_ap_of(aut);
|
||||||
|
|
||||||
// split_2step is not guaranteed to produce
|
// split_2step is guaranteed to produce an alternating arena
|
||||||
// states that alternate between env and player do to do_simplify
|
|
||||||
auto owner = get_state_players(aut);
|
auto owner = get_state_players(aut);
|
||||||
|
#ifndef NDEGUB
|
||||||
|
(void) owner;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::vector<unsigned> state_map(aut->num_states(), unseen_mark);
|
std::vector<unsigned> state_map(aut->num_states(), unseen_mark);
|
||||||
auto seen = [&](unsigned s){return state_map[s] != unseen_mark; };
|
auto seen = [&](unsigned s){return state_map[s] != unseen_mark; };
|
||||||
|
|
@ -456,31 +438,17 @@ namespace spot
|
||||||
todo.pop_front();
|
todo.pop_front();
|
||||||
|
|
||||||
for (const auto& i : aut->out(cur))
|
for (const auto& i : aut->out(cur))
|
||||||
{
|
|
||||||
// if the dst is also owned env
|
|
||||||
if (!owner[i.dst])
|
|
||||||
{
|
|
||||||
// This can only happen if there is only
|
|
||||||
// one outgoing edges for cur
|
|
||||||
assert(([&aut, cur]()->bool
|
|
||||||
{
|
|
||||||
auto out_cont = aut->out(cur);
|
|
||||||
return (++(out_cont.begin()) == out_cont.end());
|
|
||||||
})());
|
|
||||||
if (!seen(i.dst))
|
|
||||||
todo.push_back(i.dst);
|
|
||||||
out->new_edge(cur_m, map_s(i.dst), i.cond, i.acc);
|
|
||||||
continue; // Done with cur
|
|
||||||
}
|
|
||||||
for (const auto& o : aut->out(i.dst))
|
for (const auto& o : aut->out(i.dst))
|
||||||
{
|
{
|
||||||
|
assert((owner.at(cur) != owner.at(o.src))
|
||||||
|
&& (owner.at(cur) == owner.at(o.dst)
|
||||||
|
&& "Arena is not alternating!"));
|
||||||
if (!seen(o.dst))
|
if (!seen(o.dst))
|
||||||
todo.push_back(o.dst);
|
todo.push_back(o.dst);
|
||||||
out->new_edge(cur_m, map_s(o.dst),
|
out->new_edge(cur_m, map_s(o.dst),
|
||||||
i.cond & o.cond, i.acc | o.acc);
|
i.cond & o.cond, i.acc | o.acc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
out->set_init_state(map_s(aut->get_init_state_number()));
|
out->set_init_state(map_s(aut->get_init_state_number()));
|
||||||
// Try to set outputs
|
// Try to set outputs
|
||||||
if (bdd* outptr = aut->get_named_prop<bdd>("synthesis-outputs"))
|
if (bdd* outptr = aut->get_named_prop<bdd>("synthesis-outputs"))
|
||||||
|
|
@ -952,7 +920,7 @@ namespace spot
|
||||||
<< bv->paritize_time << " seconds\n";
|
<< bv->paritize_time << " seconds\n";
|
||||||
if (bv)
|
if (bv)
|
||||||
sw.start();
|
sw.start();
|
||||||
dpa = split_2step(tmp, outs, true, false);
|
dpa = split_2step(tmp, outs, true);
|
||||||
colorize_parity_here(dpa, true);
|
colorize_parity_here(dpa, true);
|
||||||
if (bv)
|
if (bv)
|
||||||
bv->split_time += sw.stop();
|
bv->split_time += sw.stop();
|
||||||
|
|
@ -975,7 +943,7 @@ namespace spot
|
||||||
<< " states\n";
|
<< " states\n";
|
||||||
if (bv)
|
if (bv)
|
||||||
sw.start();
|
sw.start();
|
||||||
dpa = split_2step(aut, outs, true, false);
|
dpa = split_2step(aut, outs, true);
|
||||||
colorize_parity_here(dpa, true);
|
colorize_parity_here(dpa, true);
|
||||||
if (bv)
|
if (bv)
|
||||||
bv->split_time += sw.stop();
|
bv->split_time += sw.stop();
|
||||||
|
|
@ -988,8 +956,7 @@ namespace spot
|
||||||
case solver::SPLIT_DET:
|
case solver::SPLIT_DET:
|
||||||
{
|
{
|
||||||
sw.start();
|
sw.start();
|
||||||
auto split = split_2step(aut, outs,
|
auto split = split_2step(aut, outs, true);
|
||||||
true, false);
|
|
||||||
if (bv)
|
if (bv)
|
||||||
bv->split_time += sw.stop();
|
bv->split_time += sw.stop();
|
||||||
if (vs)
|
if (vs)
|
||||||
|
|
@ -1045,7 +1012,7 @@ namespace spot
|
||||||
|
|
||||||
if (bv)
|
if (bv)
|
||||||
sw.start();
|
sw.start();
|
||||||
dpa = split_2step(dpa, outs, true, false);
|
dpa = split_2step(dpa, outs, true);
|
||||||
colorize_parity_here(dpa, true);
|
colorize_parity_here(dpa, true);
|
||||||
if (bv)
|
if (bv)
|
||||||
bv->split_time += sw.stop();
|
bv->split_time += sw.stop();
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
namespace spot
|
namespace spot
|
||||||
{
|
{
|
||||||
/// \brief make each transition (conditionally, see do_simplify)
|
/// \brief make each transition a 2-step transition, transforming
|
||||||
/// a 2-step transition
|
/// the graph into an alternating arena
|
||||||
///
|
///
|
||||||
/// Given a set of atomic propositions I, split each transition
|
/// Given a set of atomic propositions I, split each transition
|
||||||
/// p -- cond --> q cond in 2^2^AP
|
/// p -- cond --> q cond in 2^2^AP
|
||||||
|
|
@ -45,16 +45,13 @@ namespace spot
|
||||||
/// are treated as inputs
|
/// are treated as inputs
|
||||||
/// \param complete_env Whether the automaton should be complete for the
|
/// \param complete_env Whether the automaton should be complete for the
|
||||||
/// environment, i.e. the player of I
|
/// environment, i.e. the player of I
|
||||||
/// \param do_simplify If a state has a single outgoing transition
|
|
||||||
/// we do not necessarily have to split it
|
|
||||||
/// to solve the game
|
|
||||||
/// \note: This function also computes the state players
|
/// \note: This function also computes the state players
|
||||||
/// \note: If the automaton is to be completed for both env and player
|
/// \note: If the automaton is to be completed for both env and player
|
||||||
/// then egdes between the sinks will be added
|
/// then egdes between the sinks will be added
|
||||||
/// (assuming that the environnement/player of I) plays first
|
/// (assuming that the environnement/player of I) plays first
|
||||||
SPOT_API twa_graph_ptr
|
SPOT_API twa_graph_ptr
|
||||||
split_2step(const const_twa_graph_ptr& aut,
|
split_2step(const const_twa_graph_ptr& aut,
|
||||||
const bdd& output_bdd, bool complete_env, bool do_simplify);
|
const bdd& output_bdd, bool complete_env);
|
||||||
|
|
||||||
|
|
||||||
/// \brief make each transition a 2-step transition.
|
/// \brief make each transition a 2-step transition.
|
||||||
|
|
|
||||||
|
|
@ -3333,7 +3333,7 @@ for strat_string, (ins_str, outs_str) in strats:
|
||||||
outs &= buddy.bdd_ithvar(strat.register_ap(aout))
|
outs &= buddy.bdd_ithvar(strat.register_ap(aout))
|
||||||
|
|
||||||
spot.set_synthesis_outputs(strat, outs)
|
spot.set_synthesis_outputs(strat, outs)
|
||||||
strat_s = spot.split_2step(strat, outs, False, False)
|
strat_s = spot.split_2step(strat, outs, False)
|
||||||
|
|
||||||
for m in ["isop", "ite", "both"]:
|
for m in ["isop", "ite", "both"]:
|
||||||
for ss in [""] + [f"+sub{ii}" for ii in range(3)]:
|
for ss in [""] + [f"+sub{ii}" for ii in range(3)]:
|
||||||
|
|
|
||||||
|
|
@ -378,7 +378,7 @@ for (mealy_str, nenv_min) in test_auts:
|
||||||
ins = ins & buddy.bdd_ithvar(mealy.register_ap(aap.ap_name()))
|
ins = ins & buddy.bdd_ithvar(mealy.register_ap(aap.ap_name()))
|
||||||
else:
|
else:
|
||||||
assert("""Aps must start with either "i" or "o".""")
|
assert("""Aps must start with either "i" or "o".""")
|
||||||
mealy_min_us_s = spot.split_2step(mealy_min_us, outs, False, False)
|
mealy_min_us_s = spot.split_2step(mealy_min_us, outs, False)
|
||||||
assert(spot.is_mealy_specialization(mealy, mealy_min_us_s, True))
|
assert(spot.is_mealy_specialization(mealy, mealy_min_us_s, True))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ def do_split(f, out_list):
|
||||||
outputs = spot.buddy.bddtrue
|
outputs = spot.buddy.bddtrue
|
||||||
for a in out_list:
|
for a in out_list:
|
||||||
outputs &= spot.buddy.bdd_ithvar(aut.get_dict().varnum(spot.formula(a)))
|
outputs &= spot.buddy.bdd_ithvar(aut.get_dict().varnum(spot.formula(a)))
|
||||||
s = spot.split_2step(aut, outputs, False, False)
|
s = spot.split_2step(aut, outputs, False)
|
||||||
return aut, s
|
return aut, s
|
||||||
|
|
||||||
aut, s = do_split('(FG !a) <-> (GF b)', ['b'])
|
aut, s = do_split('(FG !a) <-> (GF b)', ['b'])
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue