<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 expression.multiply
This function is overloaded, it supports three different signatures
Step1:  Simple Multiplication
Instead of a.multiply(b), you may write a * b.
Step2:  Of course, trivial identities are applied.
Step3:  In the case of word labels, adjacent words are not fused
Step4:  Repeated Multiplication
Instead of a.multiply(3), you may write a ** 3.  Beware that a * 3 actually denotes a.right_mult(3).
Step5:  Use the exponent -1 to mean infinity.  Alternatively, you may invoke a.star instead of a ** -1.
Step6:  Sums of Repeated Multiplications
Instead of a.multiply((2, 4)), you may write a ** (2, 4).  Again, use exponent -1 to mean infinity.
<ASSISTANT_TASK:>
Python Code:
import vcsn
ctx = vcsn.context('law_char, q')
def exp(e):
    return ctx.expression(e)
Explanation: expression.multiply
This function is overloaded, it supports three different signatures:
expression.multiply(exp)
The product (i.e., the concatenation) of two expressions: a.multiply(b) => ab.
expression.multiply(num)
The repeated multiplication (concatenation) of an expression with itself: a.multiply(3) => aaa.  Exponent -1 denotes the infinity: the Kleene star.
expression.multiply((min,max))
The sum of repeated multiplications of an expression: a.multiply((2,4)) => aa+aaa+aaaa.
Preconditions:
- min &lt;= max
- None
See also:
- automaton.multiply
- polynomial.multiply
Examples
End of explanation
exp('a*b') * exp('ab*')
Explanation: Simple Multiplication
Instead of a.multiply(b), you may write a * b.
End of explanation
exp('<2>a') * exp('<3>\e')
exp('<2>a') * exp('\z')
Explanation: Of course, trivial identities are applied.
End of explanation
exp('a') * exp('b') # Two one-letter words
exp('ab') # One two-letter word
exp('(a)(b)') # Two one-letter words
Explanation: In the case of word labels, adjacent words are not fused: concatenation of two expressions behaves as if the expressions were parenthetized.  Pay attention to the space between $a$ and $b$ below, admittedly too discreet.
End of explanation
exp('ab') ** 3
exp('a*') * 3
Explanation: Repeated Multiplication
Instead of a.multiply(3), you may write a ** 3.  Beware that a * 3 actually denotes a.right_mult(3).
End of explanation
exp('ab') ** -1
exp('ab').star()
Explanation: Use the exponent -1 to mean infinity.  Alternatively, you may invoke a.star instead of a ** -1.
End of explanation
exp('ab') ** (2, 2)
exp('ab') ** (2, 4)
exp('ab') ** (-1, 2)
exp('ab') ** (2, -1)
Explanation: Sums of Repeated Multiplications
Instead of a.multiply((2, 4)), you may write a ** (2, 4).  Again, use exponent -1 to mean infinity.
End of explanation
<END_TASK>