In [1]:
import spot
spot.setup()
In [2]:
a = spot.translate('a U b U c')

The # option of print_dot() can be used to display the internal number of each transition

In [3]:
a.show('.#')
Out[3]:
G 2 2 I->2 2->2 a & !c #6 0 0 2->0 c #4 1 1 2->1 !a & b & !c #5 0->0 1 #1 1->0 c #2 1->1 b & !c #3

Using these numbers you can selectively hightlight some transitions. The second argument is a color number (from a list of predefined colors).

In [4]:
a.highlight_edges([2, 4, 5], 1)
Out[4]:
G 2 2 I->2 2->2 a & !c 0 0 2->0 c 1 1 2->1 !a & b & !c 0->0 1 1->0 c 1->1 b & !c

Note that these highlight_ functions work for edges and states, and come with both singular (changing the color of single state or edge) and plural versions.

They modify the automaton in place.

In [5]:
a.highlight_edge(6, 2).highlight_states((0, 1), 0)
Out[5]:
G 2 2 I->2 2->2 a & !c 0 0 2->0 c 1 1 2->1 !a & b & !c 0->0 1 1->0 c 1->1 b & !c

One use of this highlighting is to highlight a run in an automaton.

The following few command generate an automaton, then an accepting run on this automaton, and highlight that accepting run on the automaton. Note that a run knows the automaton from which it was generated, so calling highlight() will directly decorate that automaton.

In [6]:
b = spot.translate('X (F(Ga <-> b) & GF!b)'); b
Out[6]:
G 0 0 I->0 1 1 0->1 1 1->1 a | b 2 2 1->2 !a & !b 3 3 1->3 a & b 4 4 1->4 a & !b 2->2 b 2->2 !b 3->3 a & b 3->3 a & !b 4->2 !a & b 4->4 a & b
In [7]:
r = spot.couvreur99(b).check().accepting_run(); r
Out[7]:
Prefix:
  0
  |  1
  1
  |  !a & !b
Cycle:
  2
  |  !b	{0}
In [8]:
r.highlight(5) # the parameter is a color number
In [9]:
b
Out[9]:
G 0 0 I->0 1 1 0->1 1 1->1 a | b 2 2 1->2 !a & !b 3 3 1->3 a & b 4 4 1->4 a & !b 2->2 b 2->2 !b 3->3 a & b 3->3 a & !b 4->2 !a & b 4->4 a & b