automaton
.is_equivalent
(aut
)¶Whether this automaton is equivalent to aut
, i.e., whether they accept the same words with the same weights.
Preconditions:
See also:
import vcsn
Automata with different languages are not equivalent.
b = vcsn.context('lal_char, b')
a1 = b.ratexp('a').standard()
a2 = b.ratexp('b').standard()
a1.is_equivalent(a2)
Automata that computes different weights are not equivalent.
z = vcsn.context('lal_char, z')
a1 = z.ratexp('<42>a').standard()
a2 = z.ratexp('<51>a').standard()
a1.is_equivalent(a2)
Of course the different means to compute automata from rational expressions result in different, but equivalent, automata.
r = b.ratexp('[abc]*')
r
std = r.standard()
std
dt = r.derived_term()
dt
std.is_equivalent(dt)
One cannot test the Thompson construction directly, as it results in an automaton whose labelset is not free.
th = r.ratexp(vcsn.context('lan_char, b')).thompson()
th
try:
th.is_equivalent(std)
except Exception as e:
print("FAIL: " + str(e).splitlines()[0])
It suffices to call proper
to address this issue. In addition, we show that that useless states "do not count".
th.proper(prune = False)
th.proper(prune = False).is_equivalent(std)
In the case of weighted automata, the algorithms checks whether $(a_1 + -1 \times a_2).\mathtt{reduce}().\mathtt{is\_empty}()$, so the preconditions of automaton.reduce
apply.
a = z.ratexp('<2>ab+<3>ac').derived_term().strip()
a
d = a.determinize()
d
d.is_equivalent(a)
In particular, beware that for numerical inaccuracy (with $\mathbb{R}$) or overflows (with $\mathbb{Z}$ or $\mathbb{Q}$) may result in incorrect results. Using $\mathbb{Q}_\text{mp}$ is safe.