improve readability of parity(false, true, 5)
* spot/twa/acc.hh: Introduce parity_min_odd(n) and friends. * spot/twaalgos/determinize.cc, spot/twaalgos/rabin2parity.cc, spot/twaalgos/toparity.cc: Use them. * tests/python/parity.py: Call each function exhaustively. * NEWS: Mention the new functions.
This commit is contained in:
parent
b2539e8399
commit
566a43dd17
6 changed files with 74 additions and 25 deletions
10
NEWS
10
NEWS
|
|
@ -30,6 +30,16 @@ New in spot 2.8.2.dev (not yet released)
|
||||||
variants of F[n:m] and G[n:m], but those four are only implemented
|
variants of F[n:m] and G[n:m], but those four are only implemented
|
||||||
as syntactic sugar.
|
as syntactic sugar.
|
||||||
|
|
||||||
|
- acc_cond::acc_code::parity(bool, bool, int) was not very readable,
|
||||||
|
as it was unclear to the reader what the boolean argument meant.
|
||||||
|
The following sister functions can now improve readability:
|
||||||
|
parity_max(is_odd, n) = parity(true, is_odd, n)
|
||||||
|
parity_max_odd(n) = parity_max(true, n)
|
||||||
|
parity_max_even(n) = parity_max(false, n)
|
||||||
|
parity_min(is_odd, n) = parity(false, is_odd, n)
|
||||||
|
parity_min_odd(n) = parity_min(true, n)
|
||||||
|
parity_min_even(n) = parity_min(false, n)
|
||||||
|
|
||||||
Python:
|
Python:
|
||||||
|
|
||||||
- Doing "import spot.foo" will now load any spot-extra/foo.py on
|
- Doing "import spot.foo" will now load any spot-extra/foo.py on
|
||||||
|
|
|
||||||
|
|
@ -816,11 +816,37 @@ namespace spot
|
||||||
|
|
||||||
/// \brief Build a parity acceptance condition
|
/// \brief Build a parity acceptance condition
|
||||||
///
|
///
|
||||||
/// In parity acceptance a word is accepting if the maximum (or
|
/// In parity acceptance a run is accepting if the maximum (or
|
||||||
/// minimum) set number that is seen infinitely often is odd (or
|
/// minimum) set number that is seen infinitely often is odd (or
|
||||||
/// even). This function will build a formula for that, as
|
/// even). These functions will build a formula for that, as
|
||||||
/// specified in the HOA format.
|
/// specified in the HOA format.
|
||||||
static acc_code parity(bool max, bool odd, unsigned sets);
|
/// @{
|
||||||
|
static acc_code parity(bool is_max, bool is_odd, unsigned sets);
|
||||||
|
static acc_code parity_max(bool is_odd, unsigned sets)
|
||||||
|
{
|
||||||
|
return parity(true, is_odd, sets);
|
||||||
|
}
|
||||||
|
static acc_code parity_max_odd(unsigned sets)
|
||||||
|
{
|
||||||
|
return parity_max(true, sets);
|
||||||
|
}
|
||||||
|
static acc_code parity_max_even(unsigned sets)
|
||||||
|
{
|
||||||
|
return parity_max(false, sets);
|
||||||
|
}
|
||||||
|
static acc_code parity_min(bool is_odd, unsigned sets)
|
||||||
|
{
|
||||||
|
return parity(false, is_odd, sets);
|
||||||
|
}
|
||||||
|
static acc_code parity_min_odd(unsigned sets)
|
||||||
|
{
|
||||||
|
return parity_min(true, sets);
|
||||||
|
}
|
||||||
|
static acc_code parity_min_even(unsigned sets)
|
||||||
|
{
|
||||||
|
return parity_min(false, sets);
|
||||||
|
}
|
||||||
|
/// @}
|
||||||
|
|
||||||
/// \brief Build a random acceptance condition
|
/// \brief Build a random acceptance condition
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -965,7 +965,7 @@ namespace spot
|
||||||
if (sets % 2 == 1)
|
if (sets % 2 == 1)
|
||||||
sets += 1;
|
sets += 1;
|
||||||
// Acceptance is now min(odd) since we can emit Red on paths 0 with new opti
|
// Acceptance is now min(odd) since we can emit Red on paths 0 with new opti
|
||||||
res->set_acceptance(sets, acc_cond::acc_code::parity(false, true, sets));
|
res->set_acceptance(sets, acc_cond::acc_code::parity_min_odd(sets));
|
||||||
res->prop_universal(true);
|
res->prop_universal(true);
|
||||||
res->prop_state_acc(false);
|
res->prop_state_acc(false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// -*- coding: utf-8 -*-
|
// -*- coding: utf-8 -*-
|
||||||
// Copyright (C) 2017-2018 Laboratoire de Recherche et Développement
|
// Copyright (C) 2017-2019 Laboratoire de Recherche et Développement
|
||||||
// de l'Epita.
|
// de l'Epita.
|
||||||
//
|
//
|
||||||
// This file is part of Spot, a model checking library.
|
// This file is part of Spot, a model checking library.
|
||||||
|
|
@ -77,19 +77,19 @@ namespace spot
|
||||||
|
|
||||||
build_iar_scc(scc_.initial());
|
build_iar_scc(scc_.initial());
|
||||||
|
|
||||||
// resulting automaton has acceptance condition: parity max odd
|
{
|
||||||
// with priorities ranging from 0 to 2*(nb pairs)
|
// resulting automaton has acceptance condition: parity max odd
|
||||||
// /!\ priorities are shifted by -1 compared to the original paper
|
// for Rabin-like input and parity max even for Streett-like input.
|
||||||
if (is_rabin)
|
// with priorities ranging from 0 to 2*(nb pairs)
|
||||||
res_->set_acceptance(2*pairs_.size() + 1,
|
// /!\ priorities are shifted by -1 compared to the original paper
|
||||||
acc_cond::acc_code::parity(true, true, 2*pairs_.size() + 1));
|
unsigned sets = 2 * pairs_.size() + 1;
|
||||||
else
|
res_->set_acceptance(sets, acc_cond::acc_code::parity_max(is_rabin,
|
||||||
res_->set_acceptance(2*pairs_.size() + 1,
|
sets));
|
||||||
acc_cond::acc_code::parity(true, false, 2*pairs_.size() + 1));
|
}
|
||||||
|
{
|
||||||
// set initial state
|
unsigned s = iar2num.at(state2iar.at(aut_->get_init_state_number()));
|
||||||
res_->set_init_state(
|
res_->set_init_state(s);
|
||||||
iar2num.at(state2iar.at(aut_->get_init_state_number())));
|
}
|
||||||
|
|
||||||
// there could be quite a number of unreachable states, prune them
|
// there could be quite a number of unreachable states, prune them
|
||||||
res_->purge_unreachable_states();
|
res_->purge_unreachable_states();
|
||||||
|
|
|
||||||
|
|
@ -128,18 +128,17 @@ namespace spot
|
||||||
lar_state dst{e.dst, new_perm};
|
lar_state dst{e.dst, new_perm};
|
||||||
unsigned dst_num = get_state(dst);
|
unsigned dst_num = get_state(dst);
|
||||||
|
|
||||||
// do the h last elements satisfy the acceptance condition?
|
// Do the h last elements satisfy the acceptance condition?
|
||||||
|
// If they do, emit 2h, if they don't emit 2h+1.
|
||||||
acc_cond::mark_t m(new_perm.end() - h, new_perm.end());
|
acc_cond::mark_t m(new_perm.end() - h, new_perm.end());
|
||||||
if (aut_->acc().accepting(m))
|
bool rej = !aut_->acc().accepting(m);
|
||||||
res_->new_edge(src_num, dst_num, e.cond, {2*h});
|
res_->new_edge(src_num, dst_num, e.cond, {2*h + rej});
|
||||||
else
|
|
||||||
res_->new_edge(src_num, dst_num, e.cond, {2*h+1});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parity max even
|
// parity max even
|
||||||
res_->set_acceptance(2*aut_->num_sets() + 2,
|
unsigned sets = 2*aut_->num_sets() + 2;
|
||||||
acc_cond::acc_code::parity(true, false, 2*aut_->num_sets() + 2));
|
res_->set_acceptance(sets, acc_cond::acc_code::parity_max_even(sets));
|
||||||
|
|
||||||
if (pretty_print)
|
if (pretty_print)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,20 @@
|
||||||
|
|
||||||
import spot
|
import spot
|
||||||
|
|
||||||
|
max_even_5 = spot.acc_code.parity(True, False, 5)
|
||||||
|
assert max_even_5 == spot.acc_code.parity_max_even(5)
|
||||||
|
assert max_even_5 == spot.acc_code.parity_max(False, 5)
|
||||||
|
min_even_5 = spot.acc_code.parity(False, False, 5)
|
||||||
|
assert min_even_5 == spot.acc_code.parity_min_even(5)
|
||||||
|
assert min_even_5 == spot.acc_code.parity_min(False, 5)
|
||||||
|
|
||||||
|
max_odd_5 = spot.acc_code.parity(True, True, 5)
|
||||||
|
assert max_odd_5 == spot.acc_code.parity_max_odd(5)
|
||||||
|
assert max_odd_5 == spot.acc_code.parity_max(True, 5)
|
||||||
|
min_odd_5 = spot.acc_code.parity(False, True, 5)
|
||||||
|
assert min_odd_5 == spot.acc_code.parity_min_odd(5)
|
||||||
|
assert min_odd_5 == spot.acc_code.parity_min(True, 5)
|
||||||
|
|
||||||
|
|
||||||
for f in ('FGa', 'GFa & GFb & FGc', 'XXX(a U b)'):
|
for f in ('FGa', 'GFa & GFb & FGc', 'XXX(a U b)'):
|
||||||
a1 = spot.translate(f, 'parity')
|
a1 = spot.translate(f, 'parity')
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue