parity_type_to_parity: Add missing cases
* spot/twaalgos/toparity.cc: Correct some cases where the solution was not detected. * tests/python/toparity.py: Update tests.
This commit is contained in:
parent
abe7222973
commit
7868115a8b
2 changed files with 56 additions and 21 deletions
|
|
@ -95,7 +95,8 @@ namespace spot
|
||||||
const bool need_equivalent,
|
const bool need_equivalent,
|
||||||
std::vector<edge_status> &status,
|
std::vector<edge_status> &status,
|
||||||
std::vector<acc_cond::mark_t> &res_colors,
|
std::vector<acc_cond::mark_t> &res_colors,
|
||||||
acc_cond &new_cond, bool &was_able_to_color)
|
acc_cond &new_cond, bool &was_able_to_color,
|
||||||
|
unsigned max_col)
|
||||||
{
|
{
|
||||||
auto& ev = aut->edge_vector();
|
auto& ev = aut->edge_vector();
|
||||||
const auto ev_size = ev.size();
|
const auto ev_size = ev.size();
|
||||||
|
|
@ -134,7 +135,7 @@ namespace spot
|
||||||
kind == cond_kind::INF_PARITY;
|
kind == cond_kind::INF_PARITY;
|
||||||
unsigned max_iter = want_parity ? -1U : 1;
|
unsigned max_iter = want_parity ? -1U : 1;
|
||||||
|
|
||||||
unsigned color = want_parity ? SPOT_MAX_ACCSETS - 1 : 0;
|
unsigned color = max_col;
|
||||||
// Do we want always accepting transitions?
|
// Do we want always accepting transitions?
|
||||||
// Don't consider CO_BUCHI as it is done by Büchi
|
// Don't consider CO_BUCHI as it is done by Büchi
|
||||||
bool search_inf = kind != cond_kind::FIN_PARITY;
|
bool search_inf = kind != cond_kind::FIN_PARITY;
|
||||||
|
|
@ -167,14 +168,15 @@ namespace spot
|
||||||
auto filter_data = filter_data_t{aut, status};
|
auto filter_data = filter_data_t{aut, status};
|
||||||
scc_info si(aut, aut_init, filter, &filter_data,
|
scc_info si(aut, aut_init, filter, &filter_data,
|
||||||
scc_info_options::TRACK_STATES);
|
scc_info_options::TRACK_STATES);
|
||||||
|
if (search_inf)
|
||||||
|
si.determine_unknown_acceptance();
|
||||||
bool worked = false;
|
bool worked = false;
|
||||||
unsigned ssc_size = si.scc_count();
|
unsigned ssc_size = si.scc_count();
|
||||||
for (unsigned scc = 0; scc < ssc_size; ++scc)
|
for (unsigned scc = 0; scc < ssc_size; ++scc)
|
||||||
{
|
{
|
||||||
// scc_info can detect that we will not be able to find an
|
// scc_info can detect that we will not be able to find an
|
||||||
// accepting/rejecting cycle.
|
// accepting cycle.
|
||||||
if (!((search_inf && !si.is_accepting_scc(scc)) ||
|
if ((search_inf && si.is_accepting_scc(scc)) || !search_inf)
|
||||||
(!search_inf && !si.is_rejecting_scc(scc))))
|
|
||||||
{
|
{
|
||||||
accepting_transitions_scc(si, scc, cond, {},
|
accepting_transitions_scc(si, scc, cond, {},
|
||||||
not_decidable_transitions, *keep);
|
not_decidable_transitions, *keep);
|
||||||
|
|
@ -224,6 +226,8 @@ namespace spot
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_cond = acc_cond(new_code);
|
||||||
|
|
||||||
// We check parity
|
// We check parity
|
||||||
if (need_equivalent)
|
if (need_equivalent)
|
||||||
{
|
{
|
||||||
|
|
@ -269,19 +273,19 @@ namespace spot
|
||||||
aut->set_acceptance(acc_cond(aut_acc_comp));
|
aut->set_acceptance(acc_cond(aut_acc_comp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_cond = acc_cond(new_code);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static twa_graph_ptr
|
static twa_graph_ptr
|
||||||
cond_type_main(const twa_graph_ptr &aut, const cond_kind kind,
|
cond_type_main(const twa_graph_ptr &aut, const cond_kind kind,
|
||||||
bool &was_able_to_color)
|
bool &was_able_to_color, unsigned max_color)
|
||||||
{
|
{
|
||||||
std::vector<acc_cond::mark_t> res_colors;
|
std::vector<acc_cond::mark_t> res_colors;
|
||||||
std::vector<edge_status> status;
|
std::vector<edge_status> status;
|
||||||
acc_cond new_cond;
|
acc_cond new_cond;
|
||||||
if (cond_type_main_aux(aut, kind, true, status, res_colors, new_cond,
|
if (cond_type_main_aux(aut, kind, true, status, res_colors, new_cond,
|
||||||
was_able_to_color))
|
was_able_to_color, max_color))
|
||||||
{
|
{
|
||||||
auto res = make_twa_graph(aut, twa::prop_set::all());
|
auto res = make_twa_graph(aut, twa::prop_set::all());
|
||||||
auto &res_vector = res->edge_vector();
|
auto &res_vector = res->edge_vector();
|
||||||
|
|
@ -311,14 +315,19 @@ namespace spot
|
||||||
bool was_able_to_color;
|
bool was_able_to_color;
|
||||||
// If the automaton is parity-type with a condition that has Inf as
|
// If the automaton is parity-type with a condition that has Inf as
|
||||||
// outermost term
|
// outermost term
|
||||||
auto res = cond_type_main(aut, cond_kind::INF_PARITY, was_able_to_color);
|
auto res = cond_type_main(aut, cond_kind::INF_PARITY,
|
||||||
|
was_able_to_color, SPOT_MAX_ACCSETS - 1);
|
||||||
|
|
||||||
// If it was impossible to find an accepting edge, it is perhaps possible
|
// If it was impossible to find an accepting edge, it is perhaps possible
|
||||||
// to find a rejecting transition
|
// to find a rejecting transition
|
||||||
if (res == nullptr && !was_able_to_color)
|
if (res == nullptr && !was_able_to_color)
|
||||||
res = cond_type_main(aut, cond_kind::FIN_PARITY, was_able_to_color);
|
res = cond_type_main(aut, cond_kind::FIN_PARITY,
|
||||||
|
was_able_to_color, SPOT_MAX_ACCSETS - 1);
|
||||||
if (res)
|
if (res)
|
||||||
|
{
|
||||||
|
res->prop_state_acc(false);
|
||||||
reduce_parity_here(res);
|
reduce_parity_here(res);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -326,14 +335,14 @@ namespace spot
|
||||||
buchi_type_to_buchi(const twa_graph_ptr &aut)
|
buchi_type_to_buchi(const twa_graph_ptr &aut)
|
||||||
{
|
{
|
||||||
bool useless;
|
bool useless;
|
||||||
return cond_type_main(aut, cond_kind::BUCHI, useless);
|
return cond_type_main(aut, cond_kind::BUCHI, useless, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
twa_graph_ptr
|
twa_graph_ptr
|
||||||
co_buchi_type_to_co_buchi(const twa_graph_ptr &aut)
|
co_buchi_type_to_co_buchi(const twa_graph_ptr &aut)
|
||||||
{
|
{
|
||||||
bool useless;
|
bool useless;
|
||||||
return cond_type_main(aut, cond_kind::CO_BUCHI, useless);
|
return cond_type_main(aut, cond_kind::CO_BUCHI, useless, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// New version for paritizing
|
// New version for paritizing
|
||||||
|
|
@ -1943,12 +1952,14 @@ namespace spot
|
||||||
// Is the maximal color accepting?
|
// Is the maximal color accepting?
|
||||||
bool start_inf = true;
|
bool start_inf = true;
|
||||||
cond_type_main_aux(sub_aut, cond_kind::INF_PARITY, false, status,
|
cond_type_main_aux(sub_aut, cond_kind::INF_PARITY, false, status,
|
||||||
res_colors, new_cond, was_able_to_color);
|
res_colors, new_cond, was_able_to_color,
|
||||||
|
SPOT_MAX_ACCSETS - 1);
|
||||||
// Otherwise we can try to find a rejecting transition as first step
|
// Otherwise we can try to find a rejecting transition as first step
|
||||||
if (!was_able_to_color)
|
if (!was_able_to_color)
|
||||||
{
|
{
|
||||||
cond_type_main_aux(sub_aut, cond_kind::FIN_PARITY, false, status,
|
cond_type_main_aux(sub_aut, cond_kind::FIN_PARITY, false, status,
|
||||||
res_colors, new_cond, was_able_to_color);
|
res_colors, new_cond, was_able_to_color,
|
||||||
|
SPOT_MAX_ACCSETS - 1);
|
||||||
if (!was_able_to_color)
|
if (!was_able_to_color)
|
||||||
return false;
|
return false;
|
||||||
start_inf = false;
|
start_inf = false;
|
||||||
|
|
@ -2127,11 +2138,11 @@ namespace spot
|
||||||
bool is_co_bu = false;
|
bool is_co_bu = false;
|
||||||
bool was_able_to_color;
|
bool was_able_to_color;
|
||||||
if (!cond_type_main_aux(sub_aut, cond_kind::BUCHI, true, status,
|
if (!cond_type_main_aux(sub_aut, cond_kind::BUCHI, true, status,
|
||||||
res_colors, new_cond, was_able_to_color))
|
res_colors, new_cond, was_able_to_color, 0))
|
||||||
{
|
{
|
||||||
is_co_bu = true;
|
is_co_bu = true;
|
||||||
if (!cond_type_main_aux(sub_aut, cond_kind::CO_BUCHI, true, status,
|
if (!cond_type_main_aux(sub_aut, cond_kind::CO_BUCHI, true, status,
|
||||||
res_colors, new_cond, was_able_to_color))
|
res_colors, new_cond, was_able_to_color, 0))
|
||||||
return false;
|
return false;
|
||||||
change_to_odd();
|
change_to_odd();
|
||||||
}
|
}
|
||||||
|
|
@ -2172,16 +2183,18 @@ namespace spot
|
||||||
acc_cond new_cond;
|
acc_cond new_cond;
|
||||||
bool was_able_to_color;
|
bool was_able_to_color;
|
||||||
if (!cond_type_main_aux(sub_aut, cond_kind::INF_PARITY, true, status,
|
if (!cond_type_main_aux(sub_aut, cond_kind::INF_PARITY, true, status,
|
||||||
res_colors, new_cond, was_able_to_color))
|
res_colors, new_cond, was_able_to_color,
|
||||||
|
SPOT_MAX_ACCSETS - 3))
|
||||||
{
|
{
|
||||||
if (!cond_type_main_aux(sub_aut, cond_kind::FIN_PARITY, true, status,
|
if (!cond_type_main_aux(sub_aut, cond_kind::FIN_PARITY, true, status,
|
||||||
res_colors, new_cond, was_able_to_color))
|
res_colors, new_cond, was_able_to_color,
|
||||||
|
SPOT_MAX_ACCSETS - 3))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool is_max, is_odd;
|
bool is_max, is_odd;
|
||||||
new_cond.is_parity(is_max, is_odd);
|
new_cond.is_parity(is_max, is_odd);
|
||||||
auto [min, max] =
|
auto min =
|
||||||
std::minmax_element(res_colors.begin() + 1, res_colors.end());
|
std::min_element(res_colors.begin() + 1, res_colors.end());
|
||||||
// cond_type_main_aux returns a parity max condition
|
// cond_type_main_aux returns a parity max condition
|
||||||
assert(is_max);
|
assert(is_max);
|
||||||
auto col_fun =
|
auto col_fun =
|
||||||
|
|
|
||||||
|
|
@ -547,4 +547,26 @@ State: 9 3 {4} 2 3 {4} 6 --END--
|
||||||
b = spot.iar_maybe(a)
|
b = spot.iar_maybe(a)
|
||||||
tc.assertEqual(b.num_states(), 87)
|
tc.assertEqual(b.num_states(), 87)
|
||||||
tc.assertTrue(a.equivalent_to(b))
|
tc.assertTrue(a.equivalent_to(b))
|
||||||
test(a, [87, 91, 91, 87, 87, 87, 51, 51, 21])
|
test(a, [87, 91, 91, 87, 87, 87, 51, 35, 21])
|
||||||
|
|
||||||
|
a = spot.automaton("""HOA: v1
|
||||||
|
States: 4
|
||||||
|
Start: 0
|
||||||
|
AP: 2 "p0" "p1"
|
||||||
|
Acceptance: 2 Fin(1) & Fin(0)
|
||||||
|
properties: trans-labels explicit-labels state-acc
|
||||||
|
--BODY--
|
||||||
|
State: 0
|
||||||
|
[!0&!1] 2
|
||||||
|
[!0&!1] 1
|
||||||
|
State: 1
|
||||||
|
[!0&1] 0
|
||||||
|
[0&1] 3
|
||||||
|
State: 2
|
||||||
|
[0&!1] 1
|
||||||
|
State: 3 {0}
|
||||||
|
[!0&1] 3
|
||||||
|
[!0&!1] 1
|
||||||
|
--END--""")
|
||||||
|
b = spot.parity_type_to_parity(a)
|
||||||
|
tc.assertTrue(spot.are_equivalent(a, b))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue