import spot
spot.setup()
Let's build a small automaton to use as example.
aut = spot.translate('G(Fa <-> Xb)'); aut
The call to couvreur99()
just instanciate the emptiness check, but does not run the check. Calling check()
will return None
if no accepting run was found. Otherwise the presence of the accepting run is established, but an accepting run hasn't necessarily been calculated: calling accepting_run()
on the result will cause this computation to happen.
In the example below, we do not check the result of check()
because we know that the input formula is satisfiable, so the automaton has an accepting run.
run = spot.couvreur99(aut).check().accepting_run(); run
Accessing the contents of the run can be done via the prefix
and cycle
lists.
print(spot.bdd_format_formula(aut.get_dict(), run.prefix[0].label))
print(run.cycle[0].acc)
To convert the run into a word, using spot.twa_word()
. Note that our runs are labeled by Boolean formulas that are not necessarily a conjunction of all involved litterals. The word is just the projection of the run on its labels.
word = spot.twa_word(run); word
Accessing the different formulas (stored as BDDs) can be done again via the prefix
and cycle
lists.
print(spot.bdd_format_formula(aut.get_dict(), word.prefix[0]))
print(spot.bdd_format_formula(aut.get_dict(), word.cycle[0]))
print(spot.bdd_format_formula(aut.get_dict(), word.cycle[1]))
Calling simplifify()
will produce a shorter word that is compatible with the original word. For instance in the above word, the initial !a
is compatible with both a & b
and !a & b
. The word obtained by restricting !a
to !a & b
is therefore still accepted, but it allows removing the prefix by rotating the cycle:
word.simplify()
word
Words can be created using the parse_word
function:
print(spot.parse_word('a; b; cycle{a&b}'))
print(spot.parse_word('cycle{a&bb|bac&(aaa|bbb)}'))
print(spot.parse_word('a; b;b; qiwuei;"a;b&c;a" ;cycle{a}'))
# make sure that we can parse a word back after it has been printed
spot.parse_word(str(spot.parse_word('a;b&a;cycle{!a&!b}')))
Words can be easily converted as automata
w1 = spot.parse_word('a; !a; cycle{a; !a; a}')
w1.as_automaton()
Test some syntax errors
print(spot.parse_word('a; b&!a; b'))
print(spot.parse_word('a; b; c}'))
print(spot.parse_word('a; cycle{}'))
print(spot.parse_word('a; cycle{!a}; a'))
# Creating an empty word is OK...
w = spot.twa_word(spot._bdd_dict)
# ... as long as this word is not printed.
print(w)