Commit 4a5d7a39 authored by Alexandre Duret-Lutz's avatar Alexandre Duret-Lutz

rename is_deterministic to is_universal

For #212.

* spot/twa/twa.hh: Rename prop_deterministic() as prop_universal(),
and keep the old name as deprecated.
* spot/twaalgos/isdet.cc, spot/twaalgos/isdet.hh: Rename
is_deterministic() as is_universal(), and add a new function
for is_deterministic().
* doc/org/concepts.org, doc/org/hoa.org, doc/org/tut21.org,
spot/tl/hierarchy.cc, spot/twa/twagraph.cc,
spot/twaalgos/are_isomorphic.cc, spot/twaalgos/determinize.cc,
spot/twaalgos/dtbasat.cc, spot/twaalgos/dtwasat.cc,
spot/twaalgos/hoa.cc, spot/twaalgos/minimize.cc,
spot/twaalgos/postproc.cc, spot/twaalgos/product.cc,
spot/twaalgos/randomgraph.cc, spot/twaalgos/remfin.cc,
spot/twaalgos/simulation.cc, spot/twaalgos/totgba.cc,
spot/twaalgos/word.cc, tests/python/product.ipynb,
tests/python/remfin.py: Adjust.
* NEWS: Mention the change.
parent 4518724a
...@@ -36,6 +36,18 @@ New in spot 2.3.2.dev (not yet released) ...@@ -36,6 +36,18 @@ New in spot 2.3.2.dev (not yet released)
It was never used. You always want to use It was never used. You always want to use
spot::twa_graph::set_init_state(unsigned) in practice. spot::twa_graph::set_init_state(unsigned) in practice.
- The previous implementation of spot::is_deterministic() has been
renamed to spot::is_universal(). The new version of
spot::is_deterministic() requires the automaton to be both
universal and existential. This should not make any difference in
existing code unless you work with the recently added support for
alternating automata.
- The spot::twa::prop_deterministic() methods have been renamed to
spot::twa::prop_universal() for consistency with the above change.
We have kept spot::twa::prop_deterministic() as a deprecated
synonym for spot::twa::prop_universal() to help backward
compatibility.
New in spot 2.3.2 (2017-03-15) New in spot 2.3.2 (2017-03-15)
......
...@@ -1054,18 +1054,18 @@ better choices. ...@@ -1054,18 +1054,18 @@ better choices.
There are actually several property flags that are stored into each There are actually several property flags that are stored into each
automaton, and that can be queried or set by algorithms: automaton, and that can be queried or set by algorithms:
| flag name | meaning when =true= | | flag name | meaning when =true= |
|----------------------+----------------------------------------------------------------------------------------------| |----------------------+-------------------------------------------------------------------------------------------------------------------------------------------|
| =state_acc= | automaton should be considered as having state-based acceptance | | =state_acc= | automaton should be considered as having state-based acceptance |
| =inherently_weak= | accepting and rejecting cycles cannot be mixed in the same SCC | | =inherently_weak= | accepting and rejecting cycles cannot be mixed in the same SCC |
| =weak= | transitions of an SCC all belong to the same acceptance sets | | =weak= | transitions of an SCC all belong to the same acceptance sets |
| =very-weak= | weak automaton where all SCCs have size 1 | | =very-weak= | weak automaton where all SCCs have size 1 |
| =terminal= | automaton is weak, accepting SCCs are complete, accepting edges may not go to rejecting SCCs | | =terminal= | automaton is weak, accepting SCCs are complete, accepting edges may not go to rejecting SCCs |
| =complete= | it is always possible to move the automaton forward, using any letter | | =complete= | it is always possible to move the automaton forward, using any letter |
| =deterministic= | there is at most one run *recognizing* a word, but not necessarily accepting it | | =universal= | there is no non-determinism branching in the automaton (hence each word is *recognized* by at most one run, but not necessarily accepted) |
| =semi-deterministic= | any nondeterminism occurs before entering an accepting SCC | | =semi-deterministic= | any nondeterminism occurs before entering an accepting SCC |
| =unambiguous= | there is at most one run *accepting* a word (but it might be recognized several time) | | =unambiguous= | there is at most one run *accepting* a word (but it might be recognized several time) |
| =stutter_invariant= | the property recognized by the automaton is [[https://www.lrde.epita.fr/~adl/dl/adl/michaud.15.spin.pdf][stutter-invariant]] | | =stutter_invariant= | the property recognized by the automaton is [[https://www.lrde.epita.fr/~adl/dl/adl/michaud.15.spin.pdf][stutter-invariant]] |
For each flag =flagname=, the =twa= class has a method For each flag =flagname=, the =twa= class has a method
=prop_flagname()= that returns the value of the flag as an instance of =prop_flagname()= that returns the value of the flag as an instance of
...@@ -1083,12 +1083,14 @@ operator =X= does not prevent the formula from being ...@@ -1083,12 +1083,14 @@ operator =X= does not prevent the formula from being
stutter-invariant, but it would require additional work to check. stutter-invariant, but it would require additional work to check.
As another example, if you write an algorithm that must check whether As another example, if you write an algorithm that must check whether
an automaton is deterministic, do not call the an automaton is universal, do not call the =twa::prop_universal()=
=twa::prop_deterministic()= method, because that might return method, because that might return =trival::maybe=. Instead, call
=trival::maybe=. Instead, call =spot::is_deterministic(...)=: that =spot::is_universal(...)=: that will respond in constant time if the
will respond in constant time if the =deterministic= property flag was =universal= property flag was either =true= or =false=, otherwise it
either =true= or =false=, otherwise it will actually explore the will actually explore the automaton to decide its determinism. Note
automaton to decide its determinism. that there is also a =spot::is_deterministic(...)= function, which is
equivalent to testing that the automaton is both universal and
existential.
These automata properties are encoded into the [[file:hoa.org::#property-bits][HOA format]], so they can These automata properties are encoded into the [[file:hoa.org::#property-bits][HOA format]], so they can
be preserved when building a processing pipeline using the shell. be preserved when building a processing pipeline using the shell.
......
...@@ -609,11 +609,11 @@ double-checked by the parser. ...@@ -609,11 +609,11 @@ double-checked by the parser.
It should be noted that each property can take three values: true, It should be noted that each property can take three values: true,
false, or maybe. So actually two bits are used per property. For false, or maybe. So actually two bits are used per property. For
instance if in some algorithm you want to know whether an automaton is instance if in some algorithm you want to know whether an automaton is
deterministic (the equivalent of calling =autfilt -q complete (the equivalent of calling =autfilt -q
--is-deterministic aut.hoa= from the command-line), you should not --is-complete aut.hoa= from the command-line), you should not
call the method =aut->prop_deterministic()= because that only checks call the method =aut->prop_complete()= because that only checks
the property bits, and it might return =maybe= even if =aut= is the property bits, and it might return =maybe= even if =aut= is
deterministic. Instead, call the function =is_deterministic(aut)=. deterministic. Instead, call the function =is_complete(aut)=.
This function will first test the property bits, and do the actual This function will first test the property bits, and do the actual
check in case it is unknown. check in case it is unknown.
...@@ -639,12 +639,12 @@ this requests "verbose" properties. ...@@ -639,12 +639,12 @@ this requests "verbose" properties.
The following table summarizes how supported properties are handled. In The following table summarizes how supported properties are handled. In
particular: particular:
- for the parser =checked= means that the property is always inferred - For the parser, =checked= means that the property is always inferred
and checked against any declaration (if present), =trusted= means and checked against any declaration (if present), =trusted= means
that the property will be stored without being checked (unless that the property will be stored without being checked (unless
=--trust-hoa=no= is specified). =--trust-hoa=no= is specified).
- Stored properties are those represented as bits in the automaton. - Stored properties are those represented as bits in the automaton.
- the printer will sometime check some properties when it can do - The printer will sometime check some properties when it can do
it as part of its initial "survey scan" of the automaton; in that it as part of its initial "survey scan" of the automaton; in that
case the stored property is not used. This makes it possible case the stored property is not used. This makes it possible
to detect deterministic automata that have been output by algorithms to detect deterministic automata that have been output by algorithms
......
...@@ -132,7 +132,8 @@ corresponding BDD variable number, and then use for instance ...@@ -132,7 +132,8 @@ corresponding BDD variable number, and then use for instance
// example, the properties that are set come from the "properties:" // example, the properties that are set come from the "properties:"
// line of the input file. // line of the input file.
out << "Complete: " << aut->prop_complete() << '\n'; out << "Complete: " << aut->prop_complete() << '\n';
out << "Deterministic: " << aut->prop_deterministic() << '\n'; out << "Deterministic: " << (aut->prop_universal()
&& aut->is_existential()) << '\n';
out << "Unambiguous: " << aut->prop_unambiguous() << '\n'; out << "Unambiguous: " << aut->prop_unambiguous() << '\n';
out << "State-Based Acc: " << aut->prop_state_acc() << '\n'; out << "State-Based Acc: " << aut->prop_state_acc() << '\n';
out << "Terminal: " << aut->prop_terminal() << '\n'; out << "Terminal: " << aut->prop_terminal() << '\n';
...@@ -162,57 +163,6 @@ corresponding BDD variable number, and then use for instance ...@@ -162,57 +163,6 @@ corresponding BDD variable number, and then use for instance
#+END_SRC #+END_SRC
#+RESULTS: #+RESULTS:
#+begin_example
Acceptance: Inf(0)&Inf(1)
Number of sets: 2
Number of states: 4
Number of edges: 10
Initial state: 0
Atomic propositions: a (=0) b (=1) c (=2)
Name: Fa | G(Fb & Fc)
Complete: no
Deterministic: no
Unambiguous: yes
State-Based Acc: maybe
Terminal: maybe
Weak: maybe
Inherently Weak: maybe
Stutter Invariant: yes
State 0:
edge(0 -> 1)
label = a
acc sets = {}
edge(0 -> 2)
label = !a
acc sets = {}
edge(0 -> 3)
label = !a
acc sets = {}
State 1:
edge(1 -> 1)
label = 1
acc sets = {0,1}
State 2:
edge(2 -> 1)
label = a
acc sets = {}
edge(2 -> 2)
label = !a
acc sets = {}
State 3:
edge(3 -> 3)
label = !a & b & c
acc sets = {0,1}
edge(3 -> 3)
label = !a & !b & c
acc sets = {1}
edge(3 -> 3)
label = !a & b & !c
acc sets = {0}
edge(3 -> 3)
label = !a & !b & !c
acc sets = {}
#+end_example
* Python * Python
...@@ -239,7 +189,7 @@ Here is the very same example, but written in Python: ...@@ -239,7 +189,7 @@ Here is the very same example, but written in Python:
name = aut.get_name() name = aut.get_name()
if name: if name:
print("Name: ", name) print("Name: ", name)
print("Deterministic:", aut.prop_deterministic()) print("Deterministic:", aut.prop_universal() and aut.is_existential())
print("Unambiguous:", aut.prop_unambiguous()) print("Unambiguous:", aut.prop_unambiguous())
print("State-Based Acc:", aut.prop_state_acc()) print("State-Based Acc:", aut.prop_state_acc())
print("Terminal:", aut.prop_terminal()) print("Terminal:", aut.prop_terminal())
......
...@@ -34,7 +34,7 @@ namespace spot ...@@ -34,7 +34,7 @@ namespace spot
{ {
static bool is_recurrence(formula f, const twa_graph_ptr& aut) static bool is_recurrence(formula f, const twa_graph_ptr& aut)
{ {
if (f.is_syntactic_recurrence() || is_deterministic(aut)) if (f.is_syntactic_recurrence() || is_universal(aut))
return true; return true;
// If aut is a non-deterministic TGBA, we do // If aut is a non-deterministic TGBA, we do
// TGBA->DPA->DRA->(D?)BA. The conversion from DRA to // TGBA->DPA->DRA->(D?)BA. The conversion from DRA to
......
...@@ -987,7 +987,7 @@ namespace spot ...@@ -987,7 +987,7 @@ namespace spot
trival::repr_t inherently_weak:2; // Inherently Weak automaton. trival::repr_t inherently_weak:2; // Inherently Weak automaton.
trival::repr_t weak:2; // Weak automaton. trival::repr_t weak:2; // Weak automaton.
trival::repr_t terminal:2; // Terminal automaton. trival::repr_t terminal:2; // Terminal automaton.
trival::repr_t deterministic:2; // Deterministic automaton. trival::repr_t universal:2; // Universal automaton.
trival::repr_t unambiguous:2; // Unambiguous automaton. trival::repr_t unambiguous:2; // Unambiguous automaton.
trival::repr_t stutter_invariant:2; // Stutter invariant language. trival::repr_t stutter_invariant:2; // Stutter invariant language.
trival::repr_t very_weak:2; // very-weak, or 1-weak trival::repr_t very_weak:2; // very-weak, or 1-weak
...@@ -1292,37 +1292,55 @@ namespace spot ...@@ -1292,37 +1292,55 @@ namespace spot
is.complete = val.val(); is.complete = val.val();
} }
/// \brief Whether the automaton is deterministic. /// \brief Whether the automaton is universal.
/// ///
/// An automaton is deterministic if the conjunction between the /// An automaton is universal if the conjunction between the
/// labels of two transitions leaving a state is always false. /// labels of two transitions leaving a state is always false.
/// ///
/// Note that this method may return trival::maybe() when it is /// Note that this method may return trival::maybe() when it is
/// unknown whether the automaton is deterministic or not. If you /// unknown whether the automaton is universal or not. If you
/// need a true/false answer, prefer the is_deterministic() function. /// need a true/false answer, prefer the is_universal() function.
/// ///
/// \see prop_unambiguous() /// \see prop_unambiguous()
/// \see is_deterministic() /// \see is_universal()
trival prop_deterministic() const trival prop_universal() const
{ {
return is.deterministic; return is.universal;
} }
/// \brief Set the deterministic property. /// \brief Set the universal property.
/// ///
/// Setting the "deterministic" property automatically sets the /// Setting the "universal" property automatically sets the
/// "unambiguous" and "semi-deterministic" properties. /// "unambiguous" and "semi-deterministic" properties.
/// ///
/// \see prop_unambiguous() /// \see prop_unambiguous()
/// \see prop_semi_deterministic() /// \see prop_semi_deterministic()
void prop_deterministic(trival val) void prop_universal(trival val)
{ {
is.deterministic = val.val(); is.universal = val.val();
if (val) if (val)
// deterministic implies unambiguous and semi-deterministic // universal implies unambiguous and semi-deterministic
is.unambiguous = is.semi_deterministic = val.val(); is.unambiguous = is.semi_deterministic = val.val();
} }
// Starting with Spot 2.4, and automaton is deterministic if it is
// both universal and existential, but as we already have
// twa::is_existential(), we only need to additionally record the
// universal property. Before that, the deterministic property
// was just a synonym for universal, hence we keep the deprecated
// function prop_deterministic() with this meaning.
SPOT_DEPRECATED("use prop_universal() instead")
void prop_deterministic(trival val)
{
prop_universal(val);
}
SPOT_DEPRECATED("use prop_universal() instead")
trival prop_deterministic() const
{
return prop_universal();
}
/// \brief Whether the automaton is unambiguous /// \brief Whether the automaton is unambiguous
/// ///
/// An automaton is unambiguous if any accepted word is recognized /// An automaton is unambiguous if any accepted word is recognized
...@@ -1334,7 +1352,7 @@ namespace spot ...@@ -1334,7 +1352,7 @@ namespace spot
/// unknown whether the automaton is unambiguous or not. If you /// unknown whether the automaton is unambiguous or not. If you
/// need a true/false answer, prefer the is_unambiguous() function. /// need a true/false answer, prefer the is_unambiguous() function.
/// ///
/// \see prop_deterministic() /// \see prop_universal()
/// \see is_unambiguous() /// \see is_unambiguous()
trival prop_unambiguous() const trival prop_unambiguous() const
{ {
...@@ -1344,27 +1362,27 @@ namespace spot ...@@ -1344,27 +1362,27 @@ namespace spot
/// \brief Sets the unambiguous property /// \brief Sets the unambiguous property
/// ///
/// Marking an automaton as "non unambiguous" automatically /// Marking an automaton as "non unambiguous" automatically
/// marks it as "non deterministic". /// marks it as "non universal".
/// ///
/// \see prop_deterministic() /// \see prop_deterministic()
void prop_unambiguous(trival val) void prop_unambiguous(trival val)
{ {
is.unambiguous = val.val(); is.unambiguous = val.val();
if (!val) if (!val)
is.deterministic = val.val(); is.universal = val.val();
} }
/// \brief Whether the automaton is semi-deterministic /// \brief Whether the automaton is semi-deterministic
/// ///
/// An automaton is semi-deterministic if the sub-automaton /// An automaton is semi-deterministic if the sub-automaton
/// reachable from any accepting SCC is deterministic. /// reachable from any accepting SCC is universal.
/// ///
/// Note that this method may return trival::maybe() when it is /// Note that this method may return trival::maybe() when it is
/// unknown whether the automaton is semi-deterministic or not. /// unknown whether the automaton is semi-deterministic or not.
/// If you need a true/false answer, prefer the /// If you need a true/false answer, prefer the
/// is_semi_deterministic() function. /// is_semi_deterministic() function.
/// ///
/// \see prop_deterministic() /// \see prop_universal()
/// \see is_semi_deterministic() /// \see is_semi_deterministic()
trival prop_semi_deterministic() const trival prop_semi_deterministic() const
{ {
...@@ -1374,14 +1392,14 @@ namespace spot ...@@ -1374,14 +1392,14 @@ namespace spot
/// \brief Sets the semi-deterministic property /// \brief Sets the semi-deterministic property
/// ///
/// Marking an automaton as "non semi-deterministic" automatically /// Marking an automaton as "non semi-deterministic" automatically
/// marks it as "non deterministic". /// marks it as "non universal".
/// ///
/// \see prop_deterministic() /// \see prop_universal()
void prop_semi_deterministic(trival val) void prop_semi_deterministic(trival val)
{ {
is.semi_deterministic = val.val(); is.semi_deterministic = val.val();
if (!val) if (!val)
is.deterministic = val.val(); is.universal = val.val();
} }
/// \brief Whether the automaton is stutter-invariant. /// \brief Whether the automaton is stutter-invariant.
...@@ -1434,7 +1452,7 @@ namespace spot ...@@ -1434,7 +1452,7 @@ namespace spot
/// "stutter invariant" properties from \c other_aut to \c code. /// "stutter invariant" properties from \c other_aut to \c code.
/// ///
/// There are two flags for the determinism. If \code /// There are two flags for the determinism. If \code
/// deterministic is set, the deterministic, semi-deterministic, /// deterministic is set, the universal, semi-deterministic,
/// and unambiguous properties are copied as-is. If deterministic /// and unambiguous properties are copied as-is. If deterministic
/// is unset but improve_det is set, then those properties are /// is unset but improve_det is set, then those properties are
/// only copied if they are positive. /// only copied if they are positive.
...@@ -1542,15 +1560,15 @@ namespace spot ...@@ -1542,15 +1560,15 @@ namespace spot
} }
if (p.deterministic) if (p.deterministic)
{ {
prop_deterministic(other->prop_deterministic()); prop_universal(other->prop_universal());
prop_semi_deterministic(other->prop_semi_deterministic()); prop_semi_deterministic(other->prop_semi_deterministic());
prop_unambiguous(other->prop_unambiguous()); prop_unambiguous(other->prop_unambiguous());
} }
else if (p.improve_det) else if (p.improve_det)
{ {
if (other->prop_deterministic().is_true()) if (other->prop_universal().is_true())
{ {
prop_deterministic(true); prop_universal(true);
} }
else else
{ {
...@@ -1584,8 +1602,8 @@ namespace spot ...@@ -1584,8 +1602,8 @@ namespace spot
} }
if (!p.deterministic) if (!p.deterministic)
{ {
if (!(p.improve_det && prop_deterministic().is_true())) if (!(p.improve_det && prop_universal().is_true()))
prop_deterministic(trival::maybe()); prop_universal(trival::maybe());
if (!(p.improve_det && prop_semi_deterministic().is_true())) if (!(p.improve_det && prop_semi_deterministic().is_true()))
prop_semi_deterministic(trival::maybe()); prop_semi_deterministic(trival::maybe());
if (!(p.improve_det && prop_unambiguous().is_true())) if (!(p.improve_det && prop_unambiguous().is_true()))
......
...@@ -235,9 +235,9 @@ namespace spot ...@@ -235,9 +235,9 @@ namespace spot
return; // No unreachable state. return; // No unreachable state.
// Removing some non-deterministic dead state could make the // Removing some non-deterministic dead state could make the
// automaton deterministic. // automaton universal.
if (prop_deterministic().is_false()) if (prop_universal().is_false())
prop_deterministic(trival::maybe()); prop_universal(trival::maybe());
if (prop_complete().is_false()) if (prop_complete().is_false())
prop_complete(trival::maybe()); prop_complete(trival::maybe());
...@@ -403,9 +403,9 @@ namespace spot ...@@ -403,9 +403,9 @@ namespace spot
return; // No useless state. return; // No useless state.
// Removing some non-deterministic dead state could make the // Removing some non-deterministic dead state could make the
// automaton deterministic. Likewise for non-complete. // automaton universal. Likewise for non-complete.
if (prop_deterministic().is_false()) if (prop_universal().is_false())
prop_deterministic(trival::maybe()); prop_universal(trival::maybe());
if (prop_complete().is_false()) if (prop_complete().is_false())
prop_complete(trival::maybe()); prop_complete(trival::maybe());
......
...@@ -113,7 +113,7 @@ namespace spot ...@@ -113,7 +113,7 @@ namespace spot
isomorphism_checker::isomorphism_checker(const const_twa_graph_ptr ref) isomorphism_checker::isomorphism_checker(const const_twa_graph_ptr ref)
{ {
ref_ = make_twa_graph(ref, twa::prop_set::all()); ref_ = make_twa_graph(ref, twa::prop_set::all());
trival prop_det = ref_->prop_deterministic(); trival prop_det = ref_->prop_universal();
if (prop_det) if (prop_det)
{ {
ref_deterministic_ = true; ref_deterministic_ = true;
...@@ -135,10 +135,10 @@ namespace spot ...@@ -135,10 +135,10 @@ namespace spot
if (!aut->is_existential()) if (!aut->is_existential())
throw std::runtime_error throw std::runtime_error
("isomorphism_checker does not yet support alternation"); ("isomorphism_checker does not yet support alternation");
trival autdet = aut->prop_deterministic(); trival autdet = aut->prop_universal();
if (ref_deterministic_) if (ref_deterministic_)
{ {
if (!spot::is_deterministic(aut)) if (!spot::is_universal(aut))
return false; return false;
return are_isomorphic_det(ref_, aut); return are_isomorphic_det(ref_, aut);
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <spot/twaalgos/degen.hh> #include <spot/twaalgos/degen.hh>
#include <spot/twaalgos/sccfilter.hh> #include <spot/twaalgos/sccfilter.hh>
#include <spot/twaalgos/simulation.hh> #include <spot/twaalgos/simulation.hh>
#include <spot/twaalgos/isdet.hh>
namespace spot namespace spot
...@@ -582,7 +583,7 @@ namespace spot ...@@ -582,7 +583,7 @@ namespace spot
if (!a->is_existential()) if (!a->is_existential())
throw std::runtime_error throw std::runtime_error
("tgba_determinize() does not support alternation"); ("tgba_determinize() does not support alternation");
if (a->prop_deterministic()) if (is_universal(a))
return std::const_pointer_cast<twa_graph>(a); return std::const_pointer_cast<twa_graph>(a);
// Degeneralize // Degeneralize
...@@ -701,7 +702,7 @@ namespace spot ...@@ -701,7 +702,7 @@ namespace spot
remove_dead_acc(res, sets); remove_dead_acc(res, sets);
// Acceptance is now min(odd) since we con emit Red on paths 0 with new opti // Acceptance is now min(odd) since we con 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(false, true, sets));
res->prop_deterministic(true); res->prop_universal(true);
res->prop_state_acc(false); res->prop_state_acc(false);
if (pretty_print) if (pretty_print)
......
...@@ -599,7 +599,7 @@ namespace spot ...@@ -599,7 +599,7 @@ namespace spot
a->set_buchi(); a->set_buchi();
if (state_based) if (state_based)
a->prop_state_acc(true); a->prop_state_acc(true);
a->prop_deterministic(true); a->prop_universal(true);
a->new_states(satdict.cand_size); a->new_states(satdict.cand_size);
#if DEBUG #if DEBUG
......
...@@ -879,7 +879,7 @@ namespace spot ...@@ -879,7 +879,7 @@ namespace spot
a->copy_ap_of(aut); a->copy_ap_of(aut);
if (state_based) if (state_based)
a->prop_state_acc(true); a->prop_state_acc(true);
a->prop_deterministic(true); a->prop_universal(true);
a->set_acceptance(satdict.cand_nacc, satdict.cand_acc); a->set_acceptance(satdict.cand_nacc, satdict.cand_acc);
a->new_states(satdict.cand_size); a->new_states(satdict.cand_size);
...@@ -1474,7 +1474,7 @@ namespace spot ...@@ -1474,7 +1474,7 @@ namespace spot
// mode. If the desired output is a Büchi automaton, or not // mode. If the desired output is a Büchi automaton, or not
// desired acceptance was specified, stop here. There is not // desired acceptance was specified, stop here. There is not
// point in minimizing a minimal automaton. // point in minimizing a minimal automaton.
if (a->prop_inherently_weak() && a->prop_deterministic() if (a->prop_weak() && a->prop_universal()
&& (target_is_buchi || !user_supplied_acc)) && (target_is_buchi || !user_supplied_acc))
return a; return a;
}