automaton.multiply

This function is overloaded, it supports multiple different signatures:

  • automaton.multiply(aut)

    The product (i.e., the concatenation) of two automata.

    Precondition:

    • In case of standard multiplication, aut has to be standard
  • automaton.multiply(num)

    The repeated multiplication (concatenation) of an automaton with itself. Exponent -1 denotes the infinity: the Kleene star.

    Precondition:

    • In case of standard multiplication, automaton has to be standard
  • automaton.multiply((min,max))

    The sum of repeated multiplications of an automaton.

    Precondition:

    • min <= max
    • In case of standard multiplication, automaton has to be standard

Another parameter can be added to precise on which kind of automaton we want the operation to be applied.

  • automaton.multiply(aut,algorithm)
  • automaton.multiply(num,algorithm)
  • automaton.multiply((min,max),algorithm)

The algorithm has to be one of these:

  • "auto": default parameter, same as "standard" if parameters fit the standard preconditions, "general" otherwise.
  • "general": general multiplication, no additional preconditions.
  • "standard": standard multiplication.

Postconditions:

  • "standard": the result automaton is standard.
  • "general": the context of the result automaton is nullable.

See also:

Examples


In [1]:
import vcsn
ctx = vcsn.context('lal_char, q')
def aut(e):
    return ctx.expression(e).standard()

Simple Multiplication

Instead of a.multiply(b), you may write a * b.


In [2]:
aut('ab') * aut('cd')


Out[2]:
%3 I0 0 0 I0->0 F4 1 1 0->1 a 2 2 1->2 b 3 3 2->3 c 4 4 3->4 d 4->F4

This multiplication is standard because the right hand side automaton is standard.

If you want to force the execution of the general algorithm you can do it this way.


In [3]:
aut('ab').multiply(aut('cd'), "general")


Out[3]:
%3 I0 0 0 I0->0 F5 1 1 0->1 a 2 2 1->2 b 3 3 2->3 ε 4 4 3->4 c 5 5 4->5 d 5->F5

In order to satisfy any kind of input automaton, the general algorithm inserts a transition labelled by one, from each final transition of the left hand side automaton to each initial transition of the right hand side one.


In [4]:
%%automaton -s a
$ -> 0
$ -> 1
1 -> 2 b
0 -> 2 a
2 -> $


%3 I0 0 0 I0->0 I1 1 1 I1->1 F2 2 2 0->2 a 1->2 b 2->F2

In [5]:
b = aut('b+a')
b


Out[5]:
%3 I0 0 0 I0->0 F1 F3 1 1 0->1 a 3 3 0->3 b 1->F1 3->F3

a * b is standard.


In [6]:
a * b


Out[6]:
%3 I0 0 0 I0->0 I1 1 1 I1->1 F3 F4 2 2 0->2 a 1->2 b 3 3 2->3 a 4 4 2->4 b 3->F3 4->F4

b * a is not.


In [7]:
b * a


Out[7]:
%3 I0 0 0 I0->0 F5 1 1 0->1 a 2 2 0->2 b 3 3 1->3 ε 4 4 1->4 ε 2->3 ε 2->4 ε 5 5 3->5 a 4->5 b 5->F5

Repeated Multiplication

Instead of a.multiply(3), you may write a ** 3. Beware that a * 3 actually denotes a.right_mult(3).


In [8]:
aut('ab') ** 3


Out[8]:
%3 I0 0 0 I0->0 F6 1 1 0->1 a 2 2 1->2 b 3 3 2->3 a 4 4 3->4 b 5 5 4->5 a 6 6 5->6 b 6->F6

In [9]:
aut('a*') * 3


Out[9]:
%3 I0 0 0 I0->0 F0 F1 0->F0 ⟨3⟩ 1 1 0->1 a 1->F1 ⟨3⟩ 1->1 a

Use the exponent -1 to mean infinity. Alternatively, you may invoke a.star instead of a ** -1.


In [10]:
aut('ab') ** -1


Out[10]:
%3 I0 0 0 I0->0 F0 F2 0->F0 1 1 0->1 a 2 2 1->2 b 2->F2 2->1 a

In [11]:
aut('ab').star()


Out[11]:
%3 I0 0 0 I0->0 F0 F2 0->F0 1 1 0->1 a 2 2 1->2 b 2->F2 2->1 a

Sums of Repeated Multiplications

Instead of a.multiply((2, 4)), you may write a ** (2, 4). Again, use exponent -1 to mean infinity.


In [12]:
aut('ab') ** (2, 2)


Out[12]:
%3 I0 0 0 I0->0 F4 1 1 0->1 a 2 2 1->2 b 3 3 2->3 a 4 4 3->4 b 4->F4

In [13]:
aut('ab') ** (2, 4)


Out[13]:
%3 I0 0 0 I0->0 F4 F6 F10 1 1 0->1 a 2 2 1->2 b 3 3 2->3 a 4 4 3->4 b 4->F4 5 5 4->5 a 7 7 4->7 a 6 6 5->6 b 6->F6 8 8 7->8 b 9 9 8->9 a 10 10 9->10 b 10->F10

In [14]:
aut('ab') ** (2, -1)


Out[14]:
%3 I0 0 0 I0->0 F4 F6 1 1 0->1 a 2 2 1->2 b 3 3 2->3 a 4 4 3->4 b 4->F4 5 5 4->5 a 6 6 5->6 b 6->F6 6->5 a

In [15]:
aut('ab') ** (-1, 3)


Out[15]:
%3 I0 0 0 I0->0 F0 F2 F6 F12 0->F0 1 1 0->1 a 3 3 0->3 a 7 7 0->7 a 2 2 1->2 b 2->F2 4 4 3->4 b 5 5 4->5 a 6 6 5->6 b 6->F6 8 8 7->8 b 9 9 8->9 a 10 10 9->10 b 11 11 10->11 a 12 12 11->12 b 12->F12

In some cases applying proper to the result automaton of the general algorithm will give you the result of the standard algorithm.


In [16]:
aut('ab').multiply((-1, 3), "general")


Out[16]:
%3 I0 0 0 I0->0 F1 F4 F10 F19 1 1 0->1 ε 2 2 0->2 ε 5 5 0->5 ε 11 11 0->11 ε 1->F1 3 3 2->3 a 4 4 3->4 b 4->F4 6 6 5->6 a 7 7 6->7 b 8 8 7->8 ε 9 9 8->9 a 10 10 9->10 b 10->F10 12 12 11->12 a 13 13 12->13 b 14 14 13->14 ε 15 15 14->15 a 16 16 15->16 b 17 17 16->17 ε 18 18 17->18 a 19 19 18->19 b 19->F19

In [17]:
aut('ab').multiply((-1, 3), "general").proper()


Out[17]:
%3 I0 0 0 I0->0 F0 F2 F6 F12 0->F0 1 1 0->1 a 3 3 0->3 a 7 7 0->7 a 2 2 1->2 b 2->F2 4 4 3->4 b 5 5 4->5 a 6 6 5->6 b 6->F6 8 8 7->8 b 9 9 8->9 a 10 10 9->10 b 11 11 10->11 a 12 12 11->12 b 12->F12