from IPython.display import display
import spot
from spot.jupyter import display_inline
spot.setup()
To build an automaton from an LTL formula, simply call translate()
with a formula, and a list of options to characterize the automaton you want (those options have the same name as the long options name of the ltl2tgba
tool, and they can be abbreviated).
a = spot.translate('(a U b) & GFc & GFd', 'Buchi', 'state-based', 'complete'); a
The call the spot.setup()
in the first cells has installed a default style for the graphviz output. If you want to change this style temporarily, you can call the show(style)
method explicitly. For instance here is a vertical layout with the default font of GraphViz.
a.show("v")
If you want to add some style options to the existing one, pass a dot to the show()
function in addition to your own style options:
a.show(".st")
The translate()
function can also be called with a formula object. Either as a function, or as a method.
f = spot.formula('a U b'); f
spot.translate(f)
f.translate()
When used as a method, all the arguments are translation options. Here is a monitor:
f.translate('mon')
The following three cells show a formulas for which it makes a difference to select 'small'
or 'deterministic'
.
f = spot.formula('Ga | Gb | Gc'); f
f.translate('buchi', 'state-based', 'small').show('.v')
f.translate('buchi', 'state-based', 'det').show('v.')
Here is how to build an unambiguous automaton:
spot.translate('GFa -> GFb', 'unambig')
Compare with the standard translation:
spot.translate('GFa -> GFb')
And here is the automaton above with state-based acceptance:
a = spot.translate('GFa -> GFb', 'sbacc')
a
Some example of running the self-loopization algorithm on an automaton:
a.is_empty()
Reading from file (see automaton-io.ipynb
for more examples).
%%file example1.aut
HOA: v1
States: 3
Start: 0
AP: 2 "a" "b"
acc-name: Buchi
Acceptance: 5 Inf(0)&Fin(1)&Fin(4) | Inf(2)&Inf(3) | Inf(1)
--BODY--
State: 0 {3}
[t] 0
[0] 1 {1}
[!0] 2 {0 4}
State: 1 {3}
[1] 0
[0&1] 1 {0}
[!0&1] 2 {2 4}
State: 2
[!1] 0
[0&!1] 1 {0}
[!0&!1] 2 {0 4}
--END--
a = spot.automaton('example1.aut')
display(a)
display(spot.remove_fin(a))
display(a.postprocess('GeneralizedBuchi', 'complete'))
display(a.postprocess('Buchi', "SBAcc"))
!rm example1.aut
spot.complete(a)
spot.complete(spot.translate('Ga'))
spot.formula('(a W c) & FGa').is_syntactic_persistence()
# Using +1 in the display options is a convenient way to shift the
# set numbers in the output, as an aid in reading the product.
a1 = spot.translate('GF(a <-> Xa)')
a2 = spot.translate('a U b & GFc')
display_inline(a1.show('.t'), a2.show('.t+1'))
# the product should display pairs of states, unless asked not to (using '1').
p = spot.product(a1, a2)
display_inline(p.show('.t'), p.show('.t1'), per_row=2)
Explicit determinization after translation:
a = spot.translate('FGa')
display(a)
display(a.is_deterministic())
spot.tgba_determinize(a)
Determinization by translate()
. The generic
option allows any acceptance condition to be used instead of the default generalized Büchi.
spot.translate('FGa', 'generic', 'deterministic')
Translation to state-based co-Büchi automaton
spot.translate('FGa', 'coBuchi', 'deterministic', 'sbacc').show('.b')
Translation to parity automaton. Specifying just parity max odd
requires a parity acceptance. Adding colored
ensures that each transition (or state if sbacc
is also given) has a color, as people usually expect in parity automata.
spot.translate('FGa', 'parity max odd', 'colored')
Adding an atomic proposition to all edges
import buddy
display(a)
b = buddy.bdd_ithvar(a.register_ap('b'))
for e in a.edges():
e.cond &= b
display(a)
Adding an atomic proposition to the edge between 0 and 1:
c = buddy.bdd_ithvar(a.register_ap('c'))
for e in a.out(0):
if e.dst == 1:
e.cond &= c
a