twa: store property bits as trivals
* spot/twa/twa.hh: Store property bits as trivals. * NEWS: Mention the change. * spot/parseaut/parseaut.yy, spot/twaalgos/are_isomorphic.cc, spot/twaalgos/complete.cc, spot/twaalgos/dot.cc, spot/twaalgos/hoa.cc, spot/twaalgos/isdet.cc, spot/twaalgos/isunamb.cc, spot/twaalgos/lbtt.cc, spot/twaalgos/ltl2tgba_fm.cc, spot/twaalgos/postproc.cc, spot/twaalgos/remfin.cc, spot/twaalgos/strength.cc, spot/twaalgos/stutter.cc, spot/twaalgos/stutter.hh, spot/twaalgos/totgba.cc, tests/core/ikwiad.cc, tests/python/product.ipynb, tests/python/remfin.py: Adjust. * doc/org/hoa.org, doc/org/tut21.org: Update documentation.
This commit is contained in:
parent
1aeb260adf
commit
da391492f3
22 changed files with 337 additions and 258 deletions
|
|
@ -186,15 +186,15 @@ rm -f stvstracc.hoa
|
|||
|
||||
Even if an input HOA file uses only state-based acceptance, Spot
|
||||
internally stores it using transition-based acceptance. However in
|
||||
that case the TωA will have a property bit indicating that it actually
|
||||
that case the TωA will have a property flag indicating that it actually
|
||||
represents an automaton with the "state-based acceptance" property:
|
||||
this implies that transitions leaving one state all belong to the same
|
||||
acceptance sets. A couple of algorithms in Spot checks for this
|
||||
property, and enable specialized treatments of state-based automata.
|
||||
|
||||
Furthermore, even if an automaton does not have the "state-based
|
||||
acceptance" property bit set, the HOA output routine may detect that
|
||||
the automaton satisfies this property. In that case, it output the
|
||||
acceptance" property flag set, the HOA output routine may detect that
|
||||
the automaton satisfies this property. In that case, it outputs the
|
||||
automaton with state-based acceptance.
|
||||
|
||||
For instance in the following automaton, the outgoing transitions of
|
||||
|
|
@ -583,7 +583,7 @@ labels whenever that is possible. The option is named =k= (i.e., use
|
|||
=-Hk= with command-line tools) because it is useful when the HOA file
|
||||
is used to describe a Kripke structure.
|
||||
|
||||
** Property bits
|
||||
** Property flags
|
||||
:PROPERTIES:
|
||||
:CUSTOM_ID: property-bits
|
||||
:END:
|
||||
|
|
@ -593,7 +593,7 @@ These properties can be useful to speedup certain algorithms: for
|
|||
instance it is easier to complement a deterministic automaton that is
|
||||
known to be inherently weak.
|
||||
|
||||
Spot stores this properties that matters to its algorithms as
|
||||
Spot stores the properties that matters to its algorithms as
|
||||
additional bits attached to each automaton. Currently the HOA parser
|
||||
ignores all the properties that are unused by Spot.
|
||||
|
||||
|
|
@ -603,22 +603,22 @@ is parsed; this is for instance the case of =deterministic=,
|
|||
body of the file, and then return and error if what has been declared
|
||||
does not correspond to the reality.
|
||||
|
||||
Some supported properties (like =weak=, =unambiguous=, or
|
||||
=stutter-invariant=) are not double-checked, because that would
|
||||
require too much additional operations. Command-line tools that read
|
||||
HOA files all take a =--trust-hoa=no= option to ignore properties that
|
||||
are not double-checked by the parser.
|
||||
Some supported properties (like =weak=, =inherently-weak=,
|
||||
=unambiguous=, or =stutter-invariant=) are not double-checked, because
|
||||
that would require more operations. Command-line tools that
|
||||
read HOA files all take a =--trust-hoa=no= option to ignore properties
|
||||
that are not double-checked by the parser.
|
||||
|
||||
It should be noted that these bits are only implications. When such a
|
||||
bit is false, it only means that it is unknown whether the property is
|
||||
true. For instance if in some algorithm you want to know whether an
|
||||
automaton is deterministic (the equivalent of calling =autfilt -q
|
||||
It should be noted that each property can take three values: true,
|
||||
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
|
||||
deterministic (the equivalent of calling =autfilt -q
|
||||
--is-deterministic aut.hoa= from the command-line), you should not
|
||||
call the method =aut->prop_deterministic()= because that only checks
|
||||
the property bit, and it might be false even if the =aut= is
|
||||
the property bits, and it might return =maybe= even if =aut= is
|
||||
deterministic. Instead, call the function =is_deterministic(aut)=.
|
||||
This function will first test the property bit, and do the actual
|
||||
check if it has to.
|
||||
This function will first test the property bits, and do the actual
|
||||
check in case it is unknown.
|
||||
|
||||
Algorithms that update a TωA should call the method =prop_keep()= and
|
||||
use the argument to specify which of the properties they preserve.
|
||||
|
|
@ -632,7 +632,7 @@ take a new argument).
|
|||
The =HOA= printer also tries to not bloat the output with many
|
||||
redundant and useless properties. For instance =deterministic=
|
||||
automata are necessarily =unambiguous=, and people interested in
|
||||
unambiguous automata know that, so Spot only output the =unambiguous=
|
||||
unambiguous automata know that, so Spot only outputs the =unambiguous=
|
||||
property if an unambiguous automaton is non-deterministic. Similarly,
|
||||
while Spot only outputs non-alternating automata, it does not output
|
||||
the =no-univ-branch= property because we cannot think of a situation
|
||||
|
|
@ -666,7 +666,7 @@ particular:
|
|||
| =complete= | checked | no | checked | |
|
||||
| =unambiguous= | trusted | yes | as stored if (=-Hv= or not =deterministic=) | can be checked with =--check=unambiguous= |
|
||||
| =stutter-invariant= | trusted | yes | as stored | can be checked with =--check=stuttering= |
|
||||
| =stutter-sensitive= | trusted | yes | as stored | can be checked with =--check=stuttering= |
|
||||
| =stutter-sensitive= | trusted | yes | as stored (opposite of =stutter-invariant=) | can be checked with =--check=stuttering= |
|
||||
| =terminal= | trusted | yes | as stored | can be checked with =--check=strength= |
|
||||
| =weak= | trusted | yes | as stored if (=-Hv= or not =terminal=) | can be checked with =--check=strength= |
|
||||
| =inherently-weak= | trusted | yes | as stored if (=-Hv= or not =weak=) | can be checked with =--check=strength= |
|
||||
|
|
|
|||
|
|
@ -37,8 +37,7 @@ Start: 0
|
|||
AP: 3 "a" "b" "c"
|
||||
acc-name: generalized-Buchi 2
|
||||
Acceptance: 2 Inf(0)&Inf(1)
|
||||
properties: trans-labels explicit-labels trans-acc unambiguous
|
||||
properties: stutter-invariant
|
||||
properties: trans-labels explicit-labels trans-acc stutter-invariant
|
||||
--BODY--
|
||||
State: 0
|
||||
[0] 1
|
||||
|
|
@ -121,29 +120,22 @@ corresponding BDD variable number, and then use for instance
|
|||
if (auto name = aut->get_named_prop<std::string>("automaton-name"))
|
||||
out << "Name: " << *name << '\n';
|
||||
|
||||
// For the following prop_*() methods, true means "it's sure", false
|
||||
// means "I don't know". These properties correspond to bits stored
|
||||
// in the automaton, so they can be queried in constant time. They
|
||||
// are only set whenever they can be determined at a cheap cost: for
|
||||
// instance any algorithm that always produce deterministic automata
|
||||
// would set the deterministic bit on its output. In this example,
|
||||
// the properties that are set come from the "properties:" line of
|
||||
// the input file.
|
||||
out << "Deterministic: "
|
||||
<< (aut->prop_deterministic() ? "yes\n" : "maybe\n");
|
||||
out << "Unambiguous: "
|
||||
<< (aut->prop_unambiguous() ? "yes\n" : "maybe\n");
|
||||
out << "State-Based Acc: "
|
||||
<< (aut->prop_state_acc() ? "yes\n" : "maybe\n");
|
||||
out << "Terminal: "
|
||||
<< (aut->prop_terminal() ? "yes\n" : "maybe\n");
|
||||
out << "Weak: "
|
||||
<< (aut->prop_weak() ? "yes\n" : "maybe\n");
|
||||
out << "Inherently Weak: "
|
||||
<< (aut->prop_inherently_weak() ? "yes\n" : "maybe\n");
|
||||
out << "Stutter Invariant: "
|
||||
<< (aut->prop_stutter_invariant() ? "yes\n" :
|
||||
aut->prop_stutter_sensitive() ? "no\n" : "maybe\n");
|
||||
// For the following prop_*() methods, the return value is an
|
||||
// instance of the spot::trival class that can represent
|
||||
// yes/maybe/no. These properties correspond to bits stored in the
|
||||
// automaton, so they can be queried in constant time. They are
|
||||
// only set whenever they can be determined at a cheap cost: for
|
||||
// instance an algorithm that always produces deterministic automata
|
||||
// would set the deterministic property on its output. In this
|
||||
// example, the properties that are set come from the "properties:"
|
||||
// line of the input file.
|
||||
out << "Deterministic: " << aut->prop_deterministic() << '\n';
|
||||
out << "Unambiguous: " << aut->prop_unambiguous() << '\n';
|
||||
out << "State-Based Acc: " << aut->prop_state_acc() << '\n';
|
||||
out << "Terminal: " << aut->prop_terminal() << '\n';
|
||||
out << "Weak: " << aut->prop_weak() << '\n';
|
||||
out << "Inherently Weak: " << aut->prop_inherently_weak() << '\n';
|
||||
out << "Stutter Invariant: " << aut->prop_stutter_invariant() << '\n';
|
||||
|
||||
// States are numbered from 0 to n-1
|
||||
unsigned n = aut->num_states();
|
||||
|
|
@ -175,8 +167,8 @@ Number of edges: 10
|
|||
Initial state: 0
|
||||
Atomic propositions: a (=0) b (=1) c (=2)
|
||||
Name: Fa | G(Fb & Fc)
|
||||
Deterministic: maybe
|
||||
Unambiguous: yes
|
||||
Deterministic: no
|
||||
Unambiguous: maybe
|
||||
State-Based Acc: maybe
|
||||
Terminal: maybe
|
||||
Weak: maybe
|
||||
|
|
@ -226,12 +218,6 @@ Here is the very same example, but written in Python:
|
|||
import spot
|
||||
|
||||
|
||||
def maybe_yes(pos, neg=False):
|
||||
if neg:
|
||||
return "no"
|
||||
return "yes" if pos else "maybe"
|
||||
|
||||
|
||||
def custom_print(aut):
|
||||
bdict = aut.get_dict()
|
||||
print("Acceptance:", aut.get_acceptance())
|
||||
|
|
@ -249,14 +235,13 @@ Here is the very same example, but written in Python:
|
|||
name = aut.get_name()
|
||||
if name:
|
||||
print("Name: ", name)
|
||||
print("Deterministic:", maybe_yes(aut.prop_deterministic()))
|
||||
print("Unambiguous:", maybe_yes(aut.prop_unambiguous()))
|
||||
print("State-Based Acc:", maybe_yes(aut.prop_state_acc()))
|
||||
print("Terminal:", maybe_yes(aut.prop_terminal()))
|
||||
print("Weak:", maybe_yes(aut.prop_weak()))
|
||||
print("Inherently Weak:", maybe_yes(aut.prop_inherently_weak()))
|
||||
print("Stutter Invariant:", maybe_yes(aut.prop_stutter_invariant(),
|
||||
aut.prop_stutter_sensitive()))
|
||||
print("Deterministic:", aut.prop_deterministic())
|
||||
print("Unambiguous:", aut.prop_unambiguous())
|
||||
print("State-Based Acc:", aut.prop_state_acc())
|
||||
print("Terminal:", aut.prop_terminal())
|
||||
print("Weak:", aut.prop_weak())
|
||||
print("Inherently Weak:", aut.prop_inherently_weak())
|
||||
print("Stutter Invariant:", aut.prop_stutter_invariant())
|
||||
|
||||
for s in range(0, aut.num_states()):
|
||||
print("State {}:".format(s))
|
||||
|
|
@ -280,8 +265,8 @@ Number of states: 4
|
|||
Initial states: 0
|
||||
Atomic propositions: a (=0) b (=1) c (=2)
|
||||
Name: Fa | G(Fb & Fc)
|
||||
Deterministic: maybe
|
||||
Unambiguous: yes
|
||||
Deterministic: no
|
||||
Unambiguous: maybe
|
||||
State-Based Acc: maybe
|
||||
Terminal: maybe
|
||||
Weak: maybe
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue