import vcsn
vcsn.context('lal<char(abc)>, b')

"""
Explanation: Contexts
The Vcsn platform relies on a central concept: "contexts".  They denote typing information about automata, rational expressions, etc.  This information is alike a function type: an input type (the label), and an output type (the weight).
Contexts are created by the vcsn.context function which takes a string as input.  This string follows the following syntax:
&lt;context&gt; ::= &lt;labelset&gt; , &lt;weightset&gt;

i.e., a context name is composed of a labelset name, then a comma, then a weightset name.
Labelsets
Different LabelSets model multiple variations on labels,
members of a monoid:


letterset&lt; genset &gt;<br>
  Fully defined by an alphabet $A$, its labels being just
  letters.  It is simply denoted by $A$.  It corresponds to the usual
  definition of an NFA.


nullableset&lt; labelset &gt;<br>
  Denoted by $A^?$, also defined by an alphabet $A$, its
  labels being either letters or the empty word.  This corresponds to what
  is often called $\varepsilon$-NFAs.


wordset&lt; genset &gt; <br>
  Denoted by $A^*$, also defined by an alphabet $A$, its labels
  being (possibly empty) words on this alphabet.


oneset<br>
  Denoted by ${1}$, containing a single label: 1, the empty word.


tupleset&lt; labelset1 , labelset2 , ..., labelsetn &gt; <br>
  Cartesian product of LabelSets, $L_1 \times \cdots \times
  L_n$. This type implements the concept of transducers with an arbitrary
  number of "tapes". The concept is developed more in-depth here: Transducers.


Gensets
The gensets define the types of the letters, and sets of the valid letters.  There is currently a single genset type.


char_letters<br>
  Specify that the letters are implemented as char.  Any char will be accepted.  The genset is said to be "open".


char_letters(abc...)<br>
  Specify that the letters are implemented as char, and the genset is closed to {a, b, c}.  Any other char will be rejected.


Abbreviations for Labelsets
There are a few abbreviations that are accepted.

lal_char: letterset&lt;char_letters&gt;
lal_char(abc): letterset&lt;char_letters(abc)&gt;
lan_char: nullableset&lt;letterset&lt;char_letters&gt;&gt;
law_char: wordset&lt;letterset&lt;char_letters&gt;&gt;

Weightsets
The WeightSets define the semiring of the weights.  Builtin weights include:


b <br/>
  The classical Booleans: $\langle \mathbb{B}, \vee, \wedge, \bot, \top \rangle$


z <br/>
  The integers coded as ints: $\langle \mathbb{Z}, +, \times, 0, 1 \rangle$


q<br/>
  The rationals, coded as pairs of ints: $\langle \mathbb{Q}, +, \times, 0, 1 \rangle$


qmp<br/>
  The rationals, with support for multiprecision: $\langle \mathbb{Q}_\text{mp}, +, \times, 0, 1 \rangle$


r <br/>
  The reals, coded as doubles: $\langle \mathbb{R}, +, \times, 0, 1 \rangle$


nmin <br/>
  The tropical semiring, coded as unsigned ints: $\langle \mathbb{N} \cup {\infty}, \min, +, \infty, 0 \rangle$


zmin <br/>
  The tropical semiring, coded as ints: $\langle \mathbb{Z} \cup {\infty}, \min, +, \infty, 0 \rangle$


rmin <br/>
  The tropical semiring, coded as floatss: $\langle \mathbb{R} \cup {\infty}, \min, +, \infty, 0 \rangle$


log <br/>
  The log semiring, coded as doubles: $\langle \mathbb{R} \cup {-\infty, +\infty}, \oplus_\mathrm{log}, +, +\infty, 0 \rangle$ (where $\oplus_\mathrm{log}$ denotes $x, y \rightarrow - \mathrm{log}(\exp(-x) + \exp(-y))$.


f2<br/>
  The field: $\langle \mathbb{F}_2, \oplus, \wedge, 0, 1 \rangle$ (where $\oplus$ denotes the "exclusive or").


tupleset<br/>
  Cartesian product of WeightSets, $W_1 \times \cdots \times W_n$.


Examples
The usual framework for automaton is to use letters as labels, and Booleans as weights:
End of explanation
"""


vcsn.context('lal<char(abc)>, z')

"""
Explanation: If instead of a simple accepter that returns "yes" or "no", you want to compute an integer, work in $\mathbb{Z}$:
End of explanation
"""


vcsn.context('law<char(a-z)>, z')

"""
Explanation: To use words on the usual alphabet as labels:
End of explanation
"""


vcsn.context('lat<lal<char(a-f)>, lal<char(A-F)>>, b')

"""
Explanation: $k$-tape Automata
To create a "classical" two-tape automaton:
End of explanation
"""


vcsn.context('lal<char(ab)>, lat<b, z>')

"""
Explanation: Multiple Weights
To compute a Boolean and an integer:
End of explanation
"""


zmin2 = vcsn.context('lal<char(ab)>, lat<zmin, zmin>')
zmin2

ab = zmin2.expression('(<1,0>a)*(<0,0>b)* & (<0,0>a)*(<0,1>b)*')
ab

a = ab.automaton()
a

print(a.shortest(len = 4).format('list'))

"""
Explanation: The following automaton is almost able to recognize $a^nb^n$: it accepts only words of $a^nb^m$ (aka $a^b^$) and return $(n, m)$.  One still has to check that $n = m$.
End of explanation
"""


vcsn.context('''nullableset< lat< lal<char(ba)>,
                                  lat< lan<char(vu)>, law<char(x-z)> >
                             >
                >
                ,
                lat<expressionset<nullableset<lat<lan<char(fe)>, lan<char(hg)>>>,
                                  lat<r, q>>,
                    lat<b, z>
                >
''')

"""
Explanation: Boss
The interpretation of the following monster is left to the reader as an exercise:
End of explanation
"""


