Compute the (accessible part of the) determinization of an automaton. When lazy
, determinize on-demand (e.g., only states traversed by an evaluation).
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. This decoration, like all the others, can be stripped (see automaton.strip):
lady4d.strip()
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 -s 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 -s 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 -s 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
They are equivalent, but we cannot use automaton.is_equivalent here.
a.shortest(10)
d.shortest(10)
Some weighted automata cannot be determinized (into a finite automaton). 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.
a = vcsn.context('lal_char, q').expression('a*+(<2>a)*').automaton()
a
You may however use the lazy determinization in this case.
d = a.determinize(lazy=True)
d
print(d('')); d
print(d('aa')); d
print(d('aaaa')); d
To force the full evaluation of a lazy determinization, use automaton.accessible.
d = lady4.determinize(lazy=True)
d
print(d('')); d
d.accessible()