Compute the (accessible part of the) determinization of an automaton.
Preconditions:
Postconditions:
Caveats:
See also:
import vcsn
lady4 = vcsn.context('lal_char(abc), b').ladybird(3)
lady4
lady4d = lady4.determinize()
lady4d
The resulting automaton has states labeled with subsets of the input automaton set of states.
If the input automaton has an empty accessible part (i.e., it has no initial state), then the output is empty (which is genuinely displayed as nothing below).
%%automaton a
context = "lal_char(a), b"
0 -> 1 a
a.determinize()
The algorithm we use requires a division operator. The following example has weights in $\mathbb{Q}$ (and was chosen because the algorithm terminates on it).
%%automaton a
context = "lal_char, q"
$ -> 0 <2>
0 -> 1 <2>a
0 -> 2 <3>a
1 -> 1 <3>b
1 -> 3 <5>c
2 -> 2 <3>b
2 -> 3 <3>d
3 -> $
d = a.determinize()
d
Which is obviously deterministic. Of course they are equivalent:
a.is_equivalent(d)
The next example works in $\mathbb{Z}_{\min}$, which features a division: the usual subtraction.
%%automaton a
context = "lal_char, zmin"
$ -> 0 <0>
0 -> 1 <1>a
0 -> 2 <2>a
1 -> 1 <3>b
1 -> 3 <5>c
2 -> 2 <3>b
2 -> 3 <6>d
3 -> $ <0>
d = a.determinize()
d
Of course, they are equivalent. However we cannot use automaton.is_equivalent here.
a.shortest(10)
d.shortest(10)
Some weighted automata cannot be determinized. See automaton.has_twins_property for a possible means to detect whether the procedure will terminate.
The following automaton, for example, admits no equivalent deterministic automaton.
vcsn.context('lal_char, q').expression('a*+(<2>a)*').automaton()