In [1]:
import spot
from spot.jupyter import display_inline
from spot.seminator import seminator, ViaTGBA
spot.setup()
The orange states below form deterministic bottom SCCs. After processing by Seminator, they are both in the 1st (violet) and 2nd (green) component. Simplifications cannot merge these duplicates as one is accepting and one is not. In fact, we do not need the copy in the first component as there is no non-determinism and so there is nothing to wait for. We have to make every edge entering such SCC as a cut-edge.
In [2]:
def example(**opts):
in_a = spot.translate("(FGp2 R !p2) | GFp1")
in_a.highlight_states([3,4], 2).set_name("input")
# Note: the pure=True option disables all optimizations that are usually on by default.
out_a = seminator(in_a, pure=True, postprocess=False, highlight=True, **opts)
out_a.set_name("output")
simp_a = seminator(in_a, pure=True, postprocess=True, highlight=True, **opts)
simp_a.set_name("simplified output")
display_inline(in_a, out_a, simp_a, per_row=3, show=".vn")
example()
Enabling the bottom-SCC optimization simplifies the output automata as follows:
In [3]:
example(bscc_avoid=True)
In [4]:
example(cut_det=True)
In [5]:
example(cut_det=True, bscc_avoid=True)
We can avoid more than bottom SCC. In fact, we can avoid all SCCs that are already good for semi-deterministic automata (semi-deterministic SCC). SCC $C$ is semi-deterministic if $C$ and all successors of $C$ are deterministic. This is ilustrated on the following example and states 1 and 5.
In [6]:
def example2(**opts):
in_a = spot.translate('G((((a & b) | (!a & !b)) & (GF!b U !c)) | (((!a & b) | (a & !b)) & (FGb R c)))')
spot.highlight_nondet_states(in_a, 1)
in_a.set_name("input")
options = { "cut_det": True, "highlight": True, "jobs": ViaTGBA, "skip_levels": True, "pure": True, **opts}
out_a = seminator(in_a, **options, postprocess=False)
out_a.set_name("output")
simp_a = seminator(in_a, **options, postprocess=True)
simp_a.set_name("simplified output")
display_inline(in_a, out_a, simp_a, show=".nhs")
example2()
In [7]:
example2(bscc_avoid=True)
In the previous example we have saved several states by not including the semi-deterministic components in the 1st part of the result. However, we still got 6 (and 5 after postprocessing) states out of the 3 deterministic states $1, 5$, and $6$. This can be tackled by reusing the semi-deterministic components as they are. This immediately leads to a TGBA on the output and we have to adress this in the parts which still rely on breakpoint construction. The edges that are accepting will now carry all the marks that are needed (as they do in the original automaton anyway).
In [8]:
example2(powerset_on_cut=True, reuse_deterministic=True)
In [ ]: