Commit 9cc1bdf1 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz
Browse files

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.
parent 72c492b0
Pipeline #22037 failed with stage
in 91 minutes and 52 seconds
......@@ -55,6 +55,32 @@ New in spot 2.9.4.dev (not yet released)
file. With this refactoring, we can retrieve both a kripke or a
kripkecube from a PINS file.
- The postprocessor::set_type() method can now accept
options postprocessor::Buchi and postprocessor::GeneralizedBuchi.
These syntaxes is more homogeneous with the rest of the supported
types. Note that postprocessor::BA and postprocessor::TGBA, while
still supported and not yet marked as deprecated, are best avoided
in new code.
postprocessor::set_type(postprocessor::TGBA)
can be replaced by
postprocessor::set_type(postprocessor::BA)
and
postprocessor::set_type(postprocessor::Buchi)
postprocessor::set_pref(postprocessor::Small
| postprocessor::SBAcc)
Note that the old postprocessor::BA option implied state-based
acceptance (and was unique in that way), but the new
postprocessor::Buchi specifies Büchi acceptance without requiring
state-based acceptance (something that postprocessor did not
permit before).
- Translations for formulas such as FGp1 & FGp2 &...& FGp32 which
used to take ages are now instantaneous. (Issue #412.)
......
......@@ -686,17 +686,17 @@ ensure_deterministic(const spot::twa_graph_ptr& aut, bool nonalt = false)
static spot::twa_graph_ptr ensure_tba(spot::twa_graph_ptr aut)
{
spot::postprocessor p;
p.set_type(spot::postprocessor::TGBA);
p.set_type(spot::postprocessor::Buchi);
p.set_pref(spot::postprocessor::Any);
p.set_level(spot::postprocessor::Low);
return spot::degeneralize_tba(p.run(aut));
return p.run(aut);
}
static spot::twa_graph_ptr
product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
{
if ((type == spot::postprocessor::BA)
if ((type == spot::postprocessor::Buchi)
&& (left->num_sets() + right->num_sets() >
spot::acc_cond::mark_t::max_accsets()))
{
......@@ -709,7 +709,7 @@ product(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
static spot::twa_graph_ptr
product_or(spot::twa_graph_ptr left, spot::twa_graph_ptr right)
{
if ((type == spot::postprocessor::BA)
if ((type == spot::postprocessor::Buchi)
&& (left->num_sets() + right->num_sets() >
spot::acc_cond::mark_t::max_accsets()))
{
......
......@@ -340,7 +340,8 @@ int parse_opt_aoutput(int key, char* arg, struct argp_state*)
case 's':
automaton_format = Spin;
if (type != spot::postprocessor::Monitor)
type = spot::postprocessor::BA;
type = spot::postprocessor::Buchi;
sbacc = spot::postprocessor::SBAcc;
automaton_format_opt = arg;
break;
case OPT_CHECK:
......
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2016, 2018-2019 Laboratoire de Recherche et
// Copyright (C) 2012-2016, 2018-2020 Laboratoire de Recherche et
// Développement de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
......@@ -24,7 +24,7 @@
#include "error.h"
#include "argmatch.h"
spot::postprocessor::output_type type = spot::postprocessor::TGBA;
spot::postprocessor::output_type type = spot::postprocessor::GeneralizedBuchi;
spot::postprocessor::output_pref pref = spot::postprocessor::Small;
spot::postprocessor::output_pref comp = spot::postprocessor::Any;
spot::postprocessor::output_pref sbacc = spot::postprocessor::Any;
......@@ -165,7 +165,7 @@ parse_opt_post(int key, char* arg, struct argp_state*)
pref_set = true;
break;
case 'B':
type = spot::postprocessor::BA;
type = spot::postprocessor::Buchi;
colored = spot::postprocessor::Any;
sbacc = spot::postprocessor::SBAcc;
break;
......@@ -250,7 +250,7 @@ parse_opt_post(int key, char* arg, struct argp_state*)
case OPT_TGBA:
if (automaton_format == Spin)
error(2, 0, "--spin and --tgba are incompatible");
type = spot::postprocessor::TGBA;
type = spot::postprocessor::GeneralizedBuchi;
colored = spot::postprocessor::Any;
break;
default:
......
// -*- coding: utf-8 -*-
// Copyright (C) 2012-2019 Laboratoire de Recherche et Développement
// Copyright (C) 2012-2020 Laboratoire de Recherche et Développement
// de l'Epita (LRDE).
//
// This file is part of Spot, a model checking library.
......@@ -126,15 +126,16 @@ parse_opt(int key, char* arg, struct argp_state*)
break;
case OPT_TGTA:
ta_type = TGTA;
type = spot::postprocessor::TGBA;
type = spot::postprocessor::GeneralizedBuchi;
break;
case OPT_GTA:
ta_type = GTA;
type = spot::postprocessor::TGBA;
type = spot::postprocessor::GeneralizedBuchi;
break;
case OPT_TA:
ta_type = TA;
type = spot::postprocessor::BA;
type = spot::postprocessor::Buchi;
sbacc = spot::postprocessor::SBAcc;
break;
case OPT_INIT:
opt_with_artificial_initial_state = false;
......@@ -196,7 +197,7 @@ namespace
if (ta_type != TGTA)
{
auto testing_automaton =
tgba_to_ta(aut, ap_set, type == spot::postprocessor::BA,
tgba_to_ta(aut, ap_set, type == spot::postprocessor::Buchi,
opt_with_artificial_initial_state,
opt_single_pass_emptiness_check,
opt_with_artificial_livelock);
......
......@@ -88,7 +88,7 @@ that takes a formula (possibly as a string) as first argument:
#+BEGIN_SRC python
import spot
print(spot.translate('GFa -> GFb', 'BA').to_str('spin'))
print(spot.translate('GFa -> GFb', 'buchi', 'sbacc').to_str('spin'))
#+END_SRC
#+RESULTS:
......@@ -120,15 +120,16 @@ T0_S3:
* C++
All the translation pipeline (this include simplifying the formula,
All the translation pipeline (this includes simplifying the formula,
translating the simplified formula into an automaton, and simplifying
the resulting automaton) is handled by the =spot::translator= class.
An instance of this class can configured by calling =set_type()= to
chose the type of automaton to output, =set_level()= to set the level
of optimization (it's high by default), and =set_pref()= to set
various preferences (like small or deterministic) or characteristic
(complete, unambiguous) for the resulting automaton. Finally, the
output as a never claim is done via the =print_never_claim= function.
(complete, unambiguous, state-based acceptance) for the resulting
automaton. Finally, the output as a never claim is done via the
=print_never_claim= function.
#+BEGIN_SRC C++
#include <iostream>
......@@ -138,11 +139,13 @@ output as a never claim is done via the =print_never_claim= function.
int main()
{
spot::parsed_formula pf = spot::parse_infix_psl("[]<>p0 || <>[]p1");
spot::parsed_formula pf = spot::parse_infix_psl("[]<>a || <>[]b");
if (pf.format_errors(std::cerr))
return 1;
spot::translator trans;
trans.set_type(spot::postprocessor::BA);
trans.set_type(spot::postprocessor::Buchi);
trans.set_pref(spot::postprocessor::SBAcc
| spot::postprocessor::Small);
spot::twa_graph_ptr aut = trans.run(pf.f);
print_never_claim(std::cout, aut) << '\n';
return 0;
......@@ -155,24 +158,25 @@ never {
T0_init:
if
:: (true) -> goto T0_init
:: (p0) -> goto accept_S1
:: (p1) -> goto accept_S2
:: (a) -> goto accept_S1
:: (b) -> goto accept_S2
fi;
accept_S1:
if
:: (p0) -> goto accept_S1
:: (!(p0)) -> goto T0_S3
:: (a) -> goto accept_S1
:: (!(a)) -> goto T0_S3
fi;
accept_S2:
if
:: (p1) -> goto accept_S2
:: (b) -> goto accept_S2
fi;
T0_S3:
if
:: (p0) -> goto accept_S1
:: (!(p0)) -> goto T0_S3
:: (a) -> goto accept_S1
:: (!(a)) -> goto T0_S3
fi;
}
#+end_example
* Additional comments
......@@ -188,17 +192,17 @@ help(spot.translate)
#+begin_example
Help on function translate in module spot:
translate(formula, *args, dict=<spot.impl.bdd_dict; proxy of <Swig Object of type 'std::shared_ptr< spot::bdd_dict > *' at 0x7f1f9541c090> >, xargs=None)
translate(formula, *args, dict=<spot.impl.bdd_dict; proxy of <Swig Object of type 'std::shared_ptr< spot::bdd_dict > *' at 0x7f42f4cea030> >, xargs=None)
Translate a formula into an automaton.
Keep in mind that 'Deterministic' expresses just a preference that
may not be satisfied.
The optional arguments should be strings among the following:
- at most one in 'TGBA', 'BA', or 'Monitor', 'generic',
'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to
build), 'coBuchi'
- at most one in 'GeneralizedBuchi', 'Buchi', or 'Monitor',
'generic', 'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even', 'coBuchi'
(type of acceptance condition to build)
- at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High'
......
......@@ -121,7 +121,7 @@ more simplification opportunities.)
#+begin_src python
import spot
# Translate LTLf to Büchi.
aut = spot.from_ltlf('(a U b) & Fc').translate('ba')
aut = spot.from_ltlf('(a U b) & Fc').translate('small', 'buchi', 'sbacc')
# Remove "alive" atomic proposition
rem = spot.remove_ap()
rem.add_ap('alive')
......@@ -141,7 +141,7 @@ AP: 3 "b" "a" "c"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic
properties: very-weak
properties: terminal
--BODY--
State: 0
[!2] 0
......@@ -171,36 +171,38 @@ wrappers around the =spot::translator= and =spot::postprocessor=
objects that we need to use here.
#+begin_src C++
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/ltlf.hh>
#include <spot/twaalgos/translate.hh>
#include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/remprop.hh>
#include <iostream>
#include <spot/tl/parse.hh>
#include <spot/tl/ltlf.hh>
#include <spot/twaalgos/translate.hh>
#include <spot/twaalgos/hoa.hh>
#include <spot/twaalgos/remprop.hh>
int main()
{
spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc");
if (pf.format_errors(std::cerr))
return 1;
int main()
{
spot::parsed_formula pf = spot::parse_infix_psl("(a U b) & Fc");
if (pf.format_errors(std::cerr))
return 1;
spot::translator trans;
trans.set_type(spot::postprocessor::BA);
trans.set_pref(spot::postprocessor::Small);
spot::twa_graph_ptr aut = trans.run(spot::from_ltlf(pf.f));
spot::translator trans;
trans.set_type(spot::postprocessor::Buchi);
trans.set_pref(spot::postprocessor::SBAcc
| spot::postprocessor::Small);
spot::twa_graph_ptr aut = trans.run(spot::from_ltlf(pf.f));
spot::remove_ap rem;
rem.add_ap("alive");
aut = rem.strip(aut);
spot::remove_ap rem;
rem.add_ap("alive");
aut = rem.strip(aut);
spot::postprocessor post;
post.set_type(spot::postprocessor::BA);
post.set_pref(spot::postprocessor::Small); // or ::Deterministic
aut = post.run(aut);
spot::postprocessor post;
post.set_type(spot::postprocessor::Buchi);
post.set_pref(spot::postprocessor::SBAcc
| spot::postprocessor::Small); // or ::Deterministic
aut = post.run(aut);
print_hoa(std::cout, aut) << '\n';
return 0;
}
print_hoa(std::cout, aut) << '\n';
return 0;
}
#+end_src
#+RESULTS:
......@@ -212,7 +214,7 @@ AP: 3 "b" "a" "c"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc deterministic
properties: very-weak
properties: terminal
--BODY--
State: 0
[!2] 0
......
......@@ -94,11 +94,11 @@ The Python version uses the =postprocess()= routine:
#+BEGIN_SRC python :wrap SRC hoa
import spot
aut = spot.automaton('tut30.hoa').postprocess('BA', 'deterministic')
aut = spot.automaton('tut30.hoa').postprocess('buchi', 'sbacc', 'deterministic')
print(aut.to_str('hoa'))
#+END_SRC
#+RESULTS:
#+BEGIN_SRC hoa
#+begin_SRC hoa
HOA: v1
States: 5
Start: 1
......@@ -106,7 +106,7 @@ AP: 1 "p1"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete
properties: deterministic weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[t] 0
......@@ -122,7 +122,7 @@ State: 4
[!0] 0
[0] 4
--END--
#+END_SRC
#+end_SRC
The =postprocess()= function has an interface similar to
[[file:tut10.org][the =translate()= function discussed previously]]:
......@@ -145,10 +145,10 @@ postprocess(automaton, *args, formula=None, xargs=None)
not already 'Deterministic'.
The optional arguments should be strings among the following:
- at most one in 'Generic', 'TGBA', 'BA', or 'Monitor',
'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to
build), 'coBuchi'
- at most one in 'Generic', 'GeneralizedBuchi', 'Buchi', or
'Monitor', 'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even', 'coBuchi'
(type of acceptance condition to build)
- at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High'
......@@ -195,8 +195,9 @@ automaton to process.
return 1;
}
spot::postprocessor post;
post.set_type(spot::postprocessor::BA);
post.set_pref(spot::postprocessor::Deterministic);
post.set_type(spot::postprocessor::Buchi);
post.set_pref(spot::postprocessor::SBAcc
| spot::postprocessor::Deterministic);
post.set_level(spot::postprocessor::High);
auto aut = post.run(pa->aut);
spot::print_hoa(std::cout, aut) << '\n';
......@@ -213,7 +214,7 @@ AP: 1 "p1"
acc-name: Buchi
Acceptance: 1 Inf(0)
properties: trans-labels explicit-labels state-acc complete
properties: deterministic very-weak
properties: deterministic terminal
--BODY--
State: 0 {0}
[t] 0
......
......@@ -584,12 +584,17 @@ def _postproc_translate_options(obj, default_type, *args):
if type_ is not None and type_name_ != val:
raise ValueError("type cannot be both {} and {}"
.format(type_name_, val))
elif val == 'generic':
elif val == 'generic' or val == 'gen' or val == 'g':
type_ = postprocessor.Generic
elif val == 'tgba':
type_ = postprocessor.TGBA
elif val == 'ba':
type_ = postprocessor.BA
elif val == 'tgba': # historical
type_ = postprocessor.GeneralizedBuchi
elif val == 'generalizedbuchi':
type_ = postprocessor.GeneralizedBuchi
elif val == 'ba': # historical
type_ = postprocessor.Buchi
sbac_ = postprocessor.SBAcc
elif val == 'buchi':
type_ = postprocessor.Buchi
elif val == 'cobuchi' or val == 'nca':
type_ = postprocessor.CoBuchi
elif val == 'dca':
......@@ -652,7 +657,8 @@ def _postproc_translate_options(obj, default_type, *args):
colo_ = postprocessor.Colored
elif val == 'complete':
comp_ = postprocessor.Complete
elif val == 'sbacc' or val == 'state-based-acceptance':
elif (val == 'sbacc' or val == 'statebasedacceptance'
or val == 'state-based-acceptance'):
sbac_ = postprocessor.SBAcc
else:
assert(val == 'unambiguous')
......@@ -661,12 +667,16 @@ def _postproc_translate_options(obj, default_type, *args):
options = {
'any': pref_set,
'ba': type_set,
'buchi': type_set,
'cobuchi': type_set,
'colored': misc_set,
'complete': misc_set,
'dca': type_set,
'deterministic': pref_set,
'g': type_set,
'gen': type_set,
'generic': type_set,
'generalizedbuchi': type_set,
'high': optm_set,
'low': optm_set,
'medium': optm_set,
......@@ -684,6 +694,7 @@ def _postproc_translate_options(obj, default_type, *args):
'sbacc': misc_set,
'small': pref_set,
'statebasedacceptance': misc_set,
'state-based-acceptance': misc_set,
'tgba': type_set,
'unambiguous': misc_set,
}
......@@ -730,10 +741,10 @@ def translate(formula, *args, dict=_bdd_dict, xargs=None):
may not be satisfied.
The optional arguments should be strings among the following:
- at most one in 'TGBA', 'BA', or 'Monitor', 'generic',
'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to
build), 'coBuchi'
- at most one in 'GeneralizedBuchi', 'Buchi', or 'Monitor',
'generic', 'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even', 'coBuchi'
(type of acceptance condition to build)
- at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High'
......@@ -748,6 +759,7 @@ def translate(formula, *args, dict=_bdd_dict, xargs=None):
string (that will be converted to `spot.option_map`), as the `xargs`
argument. This is similar to the `-x` option of command-line tools;
so check out the spot-x(7) man page for details.
"""
if type(xargs) is str:
xargs = option_map(xargs)
......@@ -786,10 +798,10 @@ def postprocess(automaton, *args, formula=None, xargs=None):
not already 'Deterministic'.
The optional arguments should be strings among the following:
- at most one in 'Generic', 'TGBA', 'BA', or 'Monitor',
'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even' (type of automaton to
build), 'coBuchi'
- at most one in 'Generic', 'GeneralizedBuchi', 'Buchi', or
'Monitor', 'parity', 'parity min odd', 'parity min even',
'parity max odd', 'parity max even', 'coBuchi'
(type of acceptance condition to build)
- at most one in 'Small', 'Deterministic', 'Any'
(preferred characteristics of the produced automaton)
- at most one in 'Low', 'Medium', 'High'
......@@ -808,7 +820,8 @@ def postprocess(automaton, *args, formula=None, xargs=None):
string (that will be converted to `spot.option_map`), as the `xargs`
argument. This is similar to the `-x` option of command-line tools;
so check out the spot-x(7) man page for details.
"""
"""
if type(xargs) is str:
xargs = option_map(xargs)
p = postprocessor(xargs)
......
......@@ -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_)