automaton.proper(prune=True, backward=False)

Create an equivalent automaton without any spontaneous transitions (i.e., transitions labeled by \e).

Arguments:

  • prune whether to remove the states that become inaccessible (or non coaccsessible in the case of forward closure).
  • backward whether to perform backward closure, or forward closure.

Preconditions:

  • None

Postconditions:

  • Result is proper

See also:

References:

Examples

In [1]:
import vcsn

The typical use of proper is to remove spontaneous transitions from a Thompson automaton.

In [2]:
a = vcsn.context('lan_char, b').ratexp('(ab)*').thompson(); a
Out[2]:
%3 I4 4 4 I4->4 F5 0 0 1 1 0->1 a 2 2 1->2 ε 3 3 2->3 b 3->0 ε 5 5 3->5 ε 4->0 ε 4->5 ε 5->F5
In [3]:
p = a.proper(); p
Out[3]:
%3 I2 2 2 I2->2 F1 F2 0 0 1 1 0->1 b 1->F1 1->0 a 2->F2 2->0 a
In [4]:
p.context()
Out[4]:
$\{a, b\}\rightarrow\mathbb{B}$

The closure can be run "forwardly" instead of "backwardly", which the default (sort of a "coproper"):

In [5]:
a.proper(backward = False)
Out[5]:
%3 I0 0 0 I0->0 I2 2 2 I2->2 F2 1 1 0->1 a 1->0 b 1->2 b 2->F2
In [6]:
a.proper().is_equivalent(a.proper(backward = False))
Out[6]:
True

Pruning

States that become inaccessible are removed. To remove this pruning, pass prune = False to proper:

In [7]:
%%automaton a
  vcsn_context = "lan_char(abc), b"
  I -> 0
  0 -> 1 a
  1 -> F
  i -> 0 a
  1 -> f \\e
%3 I0 0 0 I0->0 F1 1 1 0->1 a 1->F1 3 3 1->3 ε 2 2 2->0 a
In [8]:
a.proper()
Out[8]:
%3 I0 0 0 I0->0 F1 1 1 0->1 a 1->F1 2 2 2->0 a
In [9]:
a.proper(prune = False)
Out[9]:
%3 I0 0 0 I0->0 F1 1 1 0->1 a 1->F1 2 2 2->0 a 3 3