This example is the left part of Fig.2 in our ATVA'16 paper titled "Spot 2.0 — a framework for LTL and ω-automata manipulation", slightly updated to the current version of Spot.

In [1]:
import spot
spot.setup(show_default='.b')
In [2]:
f = spot.formula('GFa <-> GFb'); f
Out[2]:
$\mathsf{G} \mathsf{F} a \leftrightarrow \mathsf{G} \mathsf{F} b$
In [3]:
f.translate()
Out[3]:
b'\n\n\nInf(\n\xe2\x93\xbf\n)&Inf(\n\xe2\x9d\xb6\n)\n[gen. B\xc3\xbcchi 2]\n\n\n\n0\n\n0\n\n\n\nI->0\n\n\n\n\n\n0->0\n\n\n1\n\n\n\n1\n\n1\n\n\n\n0->1\n\n\na | b\n\n\n\n2\n\n2\n\n\n\n0->2\n\n\n!a & !b\n\n\n\n1->1\n\n\n!a & !b\n\n\n\n1->1\n\n\na & !b\n\xe2\x93\xbf\n\n\n\n1->1\n\n\n!a & b\n\xe2\x9d\xb6\n\n\n\n1->1\n\n\na & b\n\xe2\x93\xbf\n\xe2\x9d\xb6\n\n\n\n2->2\n\n\n!a & !b\n\xe2\x93\xbf\n\xe2\x9d\xb6\n\n\n\n'
In [4]:
def implies(f, g):
    f = spot.formula(f)
    g = spot.formula.Not(g)
    return spot.product(f.translate(), g.translate()).is_empty()
def equiv(f, g):
    return implies(f, g) and implies(g, f)
In [5]:
equiv('a U (b U a)', 'b U a')
Out[5]:
True
In [6]:
equiv('!(a U b)', '!a U !b')
Out[6]:
False