postprocess, translate: add support for Büchi (not state-based)
spot/twaalgos/postproc.hh: Introduce options Buchi and GeneralizedBuchi. The latter is similar to TGBA but the former differs from BA in that it does not imply state-based acceptance, since that can be specified separately. Also all other acceptance types are not abbreviated, so those new names make more sense. * NEWS: Mention that. * spot/twaalgos/postproc.cc, spot/twaalgos/translate.cc: Adjust to support Buchi and GeneralizedBuchi without breaking BA and TGBA. * bin/autfilt.cc, bin/common_aoutput.cc, bin/common_post.cc, bin/ltl2tgta.cc, doc/org/tut10.org, doc/org/tut12.org, doc/org/tut30.org, python/spot/__init__.py, tests/python/automata.ipynb, tests/python/langmap.py, tests/python/misc-ec.py, tests/python/satmin.ipynb, tests/python/satmin.py, tests/python/toweak.py: Use the new names. * tests/Makefile.am: Add missing langmap.py.
This commit is contained in:
parent
72c492b0cf
commit
9cc1bdf10f
19 changed files with 274 additions and 201 deletions
|
|
@ -48,7 +48,7 @@ namespace spot
|
|||
static twa_graph_ptr
|
||||
ensure_ba(twa_graph_ptr& a)
|
||||
{
|
||||
if (a->num_sets() == 0)
|
||||
if (a->acc().is_t())
|
||||
{
|
||||
auto m = a->set_buchi();
|
||||
for (auto& t: a->edges())
|
||||
|
|
@ -154,6 +154,15 @@ namespace spot
|
|||
}
|
||||
}
|
||||
|
||||
twa_graph_ptr
|
||||
postprocessor::choose_degen(const twa_graph_ptr& a) const
|
||||
{
|
||||
if (state_based_)
|
||||
return do_degen(a);
|
||||
else
|
||||
return do_degen_tba(a);
|
||||
}
|
||||
|
||||
twa_graph_ptr
|
||||
postprocessor::do_degen(const twa_graph_ptr& a) const
|
||||
{
|
||||
|
|
@ -173,15 +182,6 @@ namespace spot
|
|||
degen_lowinit_, degen_remscc_);
|
||||
}
|
||||
|
||||
static void
|
||||
force_buchi(twa_graph_ptr& a)
|
||||
{
|
||||
assert(a->acc().is_t());
|
||||
acc_cond::mark_t m = a->set_buchi();
|
||||
for (auto& e: a->edges())
|
||||
e.acc = m;
|
||||
}
|
||||
|
||||
twa_graph_ptr
|
||||
postprocessor::do_scc_filter(const twa_graph_ptr& a, bool arg) const
|
||||
{
|
||||
|
|
@ -212,11 +212,12 @@ namespace spot
|
|||
tmp = complete(tmp);
|
||||
bool want_parity = type_ & Parity;
|
||||
if (want_parity && tmp->acc().is_generalized_buchi())
|
||||
tmp = SBACC_ ? do_degen(tmp) : do_degen_tba(tmp);
|
||||
if (SBACC_)
|
||||
tmp = choose_degen(tmp);
|
||||
assert(!!SBACC_ == state_based_);
|
||||
if (state_based_)
|
||||
tmp = sbacc(tmp);
|
||||
if (type_ == BA && tmp->acc().is_t())
|
||||
force_buchi(tmp);
|
||||
if (type_ == Buchi)
|
||||
tmp = ensure_ba(tmp);
|
||||
if (want_parity)
|
||||
{
|
||||
reduce_parity_here(tmp, COLORED_);
|
||||
|
|
@ -244,10 +245,18 @@ namespace spot
|
|||
ba_simul_ = (level_ == High) ? 3 : 0;
|
||||
if (scc_filter_ < 0)
|
||||
scc_filter_ = 1;
|
||||
if (type_ == BA || SBACC_)
|
||||
if (type_ == BA)
|
||||
{
|
||||
pref_ |= SBAcc;
|
||||
type_ = Buchi;
|
||||
}
|
||||
if (SBACC_)
|
||||
state_based_ = true;
|
||||
else if (state_based_)
|
||||
pref_ |= SBAcc;
|
||||
|
||||
bool via_gba = (type_ == BA) || (type_ == TGBA) || (type_ == Monitor);
|
||||
bool via_gba =
|
||||
(type_ == Buchi) || (type_ == GeneralizedBuchi) || (type_ == Monitor);
|
||||
bool want_parity = type_ & Parity;
|
||||
if (COLORED_ && !want_parity)
|
||||
throw std::runtime_error("postprocessor: the Colored setting only works "
|
||||
|
|
@ -317,8 +326,8 @@ namespace spot
|
|||
|
||||
if (PREF_ == Any && level_ == Low
|
||||
&& (type_ == Generic
|
||||
|| type_ == TGBA
|
||||
|| (type_ == BA && a->is_sba())
|
||||
|| type_ == GeneralizedBuchi
|
||||
|| (type_ == Buchi && a->acc().is_buchi())
|
||||
|| (type_ == Monitor && a->num_sets() == 0)
|
||||
|| (want_parity && a->acc().is_parity())
|
||||
|| (type_ == CoBuchi && a->acc().is_co_buchi())))
|
||||
|
|
@ -362,8 +371,8 @@ namespace spot
|
|||
|
||||
if (PREF_ == Any)
|
||||
{
|
||||
if (type_ == BA)
|
||||
a = do_degen(a);
|
||||
if (type_ == Buchi)
|
||||
a = choose_degen(a);
|
||||
else if (type_ == CoBuchi)
|
||||
a = to_nca(a);
|
||||
return finalize(a);
|
||||
|
|
@ -402,8 +411,6 @@ namespace spot
|
|||
if (!ab && PREF_ != Deterministic)
|
||||
ab = &wdba_aborter;
|
||||
dba = minimize_obligation(a, f, nullptr, reject_bigger, ab);
|
||||
if (!dba)
|
||||
std::cerr << "DBA aborted\n";
|
||||
|
||||
if (dba
|
||||
&& dba->prop_inherently_weak().is_true()
|
||||
|
|
@ -412,7 +419,7 @@ namespace spot
|
|||
// The WDBA is a BA, so no degeneralization is required.
|
||||
// We just need to add an acceptance set if there is none.
|
||||
dba_is_minimal = dba_is_wdba = true;
|
||||
if (type_ == BA)
|
||||
if (type_ == Buchi)
|
||||
ensure_ba(dba);
|
||||
}
|
||||
else
|
||||
|
|
@ -426,9 +433,9 @@ namespace spot
|
|||
// at hard levels if we want a small output.
|
||||
if (!dba || (level_ == High && PREF_ == Small))
|
||||
{
|
||||
if (((SBACC_ && a->prop_state_acc().is_true())
|
||||
|| (type_ == BA && a->is_sba()))
|
||||
&& !tba_determinisation_)
|
||||
if ((state_based_ && a->prop_state_acc().is_true())
|
||||
&& !tba_determinisation_
|
||||
&& (type_ != Buchi || a->acc().is_buchi()))
|
||||
{
|
||||
sim = do_sba_simul(a, ba_simul_);
|
||||
}
|
||||
|
|
@ -437,11 +444,11 @@ namespace spot
|
|||
sim = do_simul(a, simul_);
|
||||
// Degeneralize the result of the simulation if needed.
|
||||
// No need to do that if tba_determinisation_ will be used.
|
||||
if (type_ == BA && !tba_determinisation_)
|
||||
sim = do_degen(sim);
|
||||
if (type_ == Buchi && !tba_determinisation_)
|
||||
sim = choose_degen(sim);
|
||||
else if (want_parity && !sim->acc().is_parity())
|
||||
sim = do_degen_tba(sim);
|
||||
else if (SBACC_ && !tba_determinisation_)
|
||||
else if (state_based_ && !tba_determinisation_)
|
||||
sim = sbacc(sim);
|
||||
}
|
||||
}
|
||||
|
|
@ -452,21 +459,16 @@ namespace spot
|
|||
if (!dba && is_deterministic(sim))
|
||||
{
|
||||
std::swap(sim, dba);
|
||||
// We postponed degeneralization above i case we would need
|
||||
// We postponed degeneralization above in case we would need
|
||||
// to perform TBA-determinisation, but now it is clear
|
||||
// that we won't perform it. So do degeneralize.
|
||||
if (tba_determinisation_)
|
||||
{
|
||||
if (type_ == BA)
|
||||
{
|
||||
dba = do_degen(dba);
|
||||
assert(is_deterministic(dba));
|
||||
}
|
||||
else if (SBACC_)
|
||||
{
|
||||
dba = sbacc(dba);
|
||||
assert(is_deterministic(dba));
|
||||
}
|
||||
if (type_ == Buchi)
|
||||
dba = choose_degen(dba);
|
||||
else if (state_based_)
|
||||
dba = sbacc(dba);
|
||||
assert(is_deterministic(dba));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -513,8 +515,8 @@ namespace spot
|
|||
else
|
||||
{
|
||||
// degeneralize sim, because we did not do it earlier
|
||||
if (type_ == BA)
|
||||
sim = do_degen(sim);
|
||||
if (type_ == Buchi)
|
||||
sim = choose_degen(sim);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -552,7 +554,7 @@ namespace spot
|
|||
throw std::runtime_error
|
||||
("postproc() not yet updated to mix sat-minimize and Generic");
|
||||
unsigned target_acc;
|
||||
if (type_ == BA)
|
||||
if (type_ == Buchi)
|
||||
target_acc = 1;
|
||||
else if (sat_acc_ != -1)
|
||||
target_acc = sat_acc_;
|
||||
|
|
@ -634,8 +636,8 @@ namespace spot
|
|||
|
||||
// Degeneralize the dba resulting from tba-determinization or
|
||||
// sat-minimization (which is a TBA) if requested and needed.
|
||||
if (dba && !dba_is_wdba && type_ == BA
|
||||
&& !(dba_is_minimal && state_based_ && dba->num_sets() == 1))
|
||||
if (dba && !dba_is_wdba && type_ == Buchi && state_based_
|
||||
&& !(dba_is_minimal && dba->num_sets() == 1))
|
||||
dba = degeneralize(dba);
|
||||
|
||||
if (dba && sim)
|
||||
|
|
|
|||
|
|
@ -72,26 +72,29 @@ namespace spot
|
|||
/// options used for debugging or benchmarking.
|
||||
postprocessor(const option_map* opt = nullptr);
|
||||
|
||||
enum output_type { TGBA = 0, // should be renamed GeneralizedBuchi
|
||||
BA = 1, // should be renamed Buchi and not imply SBAcc
|
||||
Monitor = 2,
|
||||
Generic = 3,
|
||||
Parity = 4,
|
||||
ParityMin = Parity | 8,
|
||||
ParityMax = Parity | 16,
|
||||
ParityOdd = Parity | 32,
|
||||
ParityEven = Parity | 64,
|
||||
ParityMinOdd = ParityMin | ParityOdd,
|
||||
ParityMaxOdd = ParityMax | ParityOdd,
|
||||
ParityMinEven = ParityMin | ParityEven,
|
||||
ParityMaxEven = ParityMax | ParityEven,
|
||||
CoBuchi = 128,
|
||||
enum output_type {
|
||||
TGBA = 0, // Historical. Use GeneralizedBuchi instead
|
||||
GeneralizedBuchi = 0, // Introduced in Spot 2.10 to replace TGBA
|
||||
BA = 1, // Historical. Implies Buchi and SBAcc.
|
||||
Monitor = 2,
|
||||
Generic = 3,
|
||||
Parity = 4,
|
||||
ParityMin = Parity | 8,
|
||||
ParityMax = Parity | 16,
|
||||
ParityOdd = Parity | 32,
|
||||
ParityEven = Parity | 64,
|
||||
ParityMinOdd = ParityMin | ParityOdd,
|
||||
ParityMaxOdd = ParityMax | ParityOdd,
|
||||
ParityMinEven = ParityMin | ParityEven,
|
||||
ParityMaxEven = ParityMax | ParityEven,
|
||||
CoBuchi = 128,
|
||||
Buchi = 256, // introduced in Spot 2.10, does not imply SBAcc
|
||||
};
|
||||
|
||||
/// \brief Select the desired output type.
|
||||
///
|
||||
/// \c TGBA requires transition-based generalized Büchi acceptance
|
||||
/// while \c BA requests state-based Büchi acceptance. In both
|
||||
/// \c GeneralizedBuchi requires generalized Büchi acceptance
|
||||
/// while \c Buchi requests Büchi acceptance. In both
|
||||
/// cases, automata with more complex acceptance conditions will
|
||||
/// be converted into these simpler acceptance. For references
|
||||
/// about the algorithms used behind these options, see section 5
|
||||
|
|
@ -116,17 +119,22 @@ namespace spot
|
|||
/// not all TGBA can be degeneralized, using \c Generic will allow
|
||||
/// parity acceptance to be used instead).
|
||||
///
|
||||
/// \a Parity and its variants request the acceptance condition to
|
||||
/// \c Parity and its variants request the acceptance condition to
|
||||
/// be of some parity type. Note that the determinization
|
||||
/// algorithm used by Spot produces "parity min odd" acceptance,
|
||||
/// but other parity types can be obtained from there by minor
|
||||
/// adjustments.
|
||||
///
|
||||
/// \a CoBuchi requests a Co-Büchi automaton equivalent to
|
||||
/// \c CoBuchi requests a Co-Büchi automaton equivalent to
|
||||
/// the input, when possible, or a Co-Büchi automaton that
|
||||
/// recognize a larger language otherwise.
|
||||
///
|
||||
/// If set_type() is not called, the default \c output_type is \c TGBA.
|
||||
/// \c BA is a historical type that means Buchi and additionally
|
||||
/// set state-based acceptance (this should normally be set
|
||||
/// with `set_pref(SBAcc)`).
|
||||
///
|
||||
/// If set_type() is not called, the default \c output_type is \c
|
||||
/// GeneralizedBuchi.
|
||||
void
|
||||
set_type(output_type type)
|
||||
{
|
||||
|
|
@ -221,6 +229,7 @@ namespace spot
|
|||
protected:
|
||||
twa_graph_ptr do_simul(const twa_graph_ptr& input, int opt) const;
|
||||
twa_graph_ptr do_sba_simul(const twa_graph_ptr& input, int opt) const;
|
||||
twa_graph_ptr choose_degen(const twa_graph_ptr& input) const;
|
||||
twa_graph_ptr do_degen(const twa_graph_ptr& input) const;
|
||||
twa_graph_ptr do_degen_tba(const twa_graph_ptr& input) const;
|
||||
twa_graph_ptr do_scc_filter(const twa_graph_ptr& a, bool arg) const;
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ namespace spot
|
|||
r2 = r2[0];
|
||||
++leading_x;
|
||||
}
|
||||
if (type_ == Generic || type_ == TGBA)
|
||||
if (type_ == Generic || type_ == GeneralizedBuchi)
|
||||
{
|
||||
// F(q|u|f) = q|F(u)|F(f) only for generic acceptance
|
||||
// G(q&e&f) = q&G(e)&G(f)
|
||||
|
|
@ -174,7 +174,7 @@ namespace spot
|
|||
// with disjunction, but it seems to generate larger automata
|
||||
// in many cases and it needs to be further investigated. Maybe
|
||||
// this could be relaxed in the case of deterministic output.
|
||||
(!r2.is(op::And) && (type_ == TGBA || type_ == BA)))
|
||||
(!r2.is(op::And) && (type_ == GeneralizedBuchi || type_ == Buchi)))
|
||||
goto nosplit;
|
||||
|
||||
op topop = r2.kind();
|
||||
|
|
@ -182,7 +182,7 @@ namespace spot
|
|||
std::vector<formula> oblg;
|
||||
std::vector<formula> susp;
|
||||
std::vector<formula> rest;
|
||||
bool want_g = type_ == TGBA || type_ == BA;
|
||||
bool want_g = type_ == GeneralizedBuchi || type_ == Buchi;
|
||||
for (formula child: r2)
|
||||
{
|
||||
if (child.is_syntactic_obligation())
|
||||
|
|
@ -213,7 +213,8 @@ namespace spot
|
|||
{
|
||||
// The only cases where we accept susp and rest to be both
|
||||
// non-empty is when doing Generic acceptance or TGBA.
|
||||
if (!rest.empty() && !(type_ == Generic || type_ == TGBA))
|
||||
if (!rest.empty()
|
||||
&& !(type_ == Generic || type_ == GeneralizedBuchi))
|
||||
{
|
||||
rest.insert(rest.end(), susp.begin(), susp.end());
|
||||
susp.clear();
|
||||
|
|
@ -225,7 +226,7 @@ namespace spot
|
|||
}
|
||||
// For TGBA and BA, we only split if there is something to
|
||||
// suspend.
|
||||
if (susp.empty() && (type_ == TGBA || type_ == BA))
|
||||
if (susp.empty() && (type_ == GeneralizedBuchi || type_ == Buchi))
|
||||
goto nosplit;
|
||||
|
||||
option_map om_wos;
|
||||
|
|
@ -375,17 +376,19 @@ namespace spot
|
|||
if (gf_guarantee_ && PREF_ != Any)
|
||||
{
|
||||
bool det = unambiguous || (PREF_ == Deterministic);
|
||||
bool sba = type_ == BA || (pref_ & SBAcc);
|
||||
if ((type_ & (BA | Parity | Generic)) || type_ == TGBA)
|
||||
if ((type_ & (Buchi | Parity))
|
||||
|| type_ == Generic
|
||||
|| type_ == GeneralizedBuchi)
|
||||
aut2 = gf_guarantee_to_ba_maybe(r, simpl_->get_dict(),
|
||||
det, sba);
|
||||
if (aut2 && ((type_ == BA) || (type_ & Parity))
|
||||
det, state_based_);
|
||||
if (aut2 && (type_ & (Buchi | Parity))
|
||||
&& (pref_ & Deterministic))
|
||||
return finalize(aut2);
|
||||
if (!aut2 && (type_ == Generic
|
||||
|| type_ & (Parity | CoBuchi)))
|
||||
{
|
||||
aut2 = fg_safety_to_dca_maybe(r, simpl_->get_dict(), sba);
|
||||
aut2 = fg_safety_to_dca_maybe(r, simpl_->get_dict(),
|
||||
state_based_);
|
||||
if (aut2
|
||||
&& (type_ & (CoBuchi | Parity))
|
||||
&& (pref_ & Deterministic))
|
||||
|
|
@ -418,6 +421,16 @@ namespace spot
|
|||
|
||||
twa_graph_ptr translator::run(formula* f)
|
||||
{
|
||||
if (type_ == BA)
|
||||
{
|
||||
pref_ |= SBAcc;
|
||||
type_ = Buchi;
|
||||
}
|
||||
if (pref_ & SBAcc)
|
||||
state_based_ = true;
|
||||
else if (state_based_)
|
||||
pref_ |= SBAcc;
|
||||
|
||||
if (simpl_owned_)
|
||||
{
|
||||
// Modify the options according to set_pref() and set_type().
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue