Vaucanson 2 news

This file describes user visible changes in the course of the development of
Vaucanson 2, in reverse chronological order.  On occasions, significant
changes in the internal API may also be documented.

* 2013-11-13
Release of our second beta, vaucanson-2b.1.

* 2013-11-07
** TAF-Kit: infiltration, product, shuffle: accept multiple arguments
You may pass several (one or more) arguments to vcsn product, infiltration
and shuffle.

** infiltration, product, shuffle: accept non commutative semirings
Beware that the (well defined) behavior of the resulting automata is no
longer what one might expect.

  $ vcsn standard -C 'lal_char(ab)_ratexpset<lal_char(uv)_b>' \
                  -e '<u>a<v>b' -o uv.gv
  $ vcsn standard -C 'lal_char(ab)_ratexpset<lal_char(xy)_b>' \
                  -e '<x>a<y>b' -o xy.gv
  $ vcsn product -f uv.gv xy.gv | vcsn-enumerate -f - 4
  <u.x.v.y>ab
  $ vcsn shuffle -f uv.gv xy.gv | vcsn-enumerate -f - 4
  <u.x.v.y+u.x.y.v+x.u.v.y+x.u.y.v>aabb
  <u.v.x.y+x.y.u.v>abab
  $ vcsn infiltration -f uv.gv xy.gv | vcsn-enumerate -f - 4
  <u.x.v.y>ab
  <u.x.v.y+x.u.v.y>aab
  <u.x.v.y+u.x.y.v>abb
  <u.x.v.y+u.x.y.v+x.u.v.y+x.u.y.v>aabb
  <u.v.x.y+x.y.u.v>abab

** Input/Output fixes
Support for EFSM in input/output is improved to support weights.  Output was
significantly sped up.

Before:
  0.64s: standard -Ee 'a?{500}' -O dot  >a500.gv
  4.47s: standard -Ee 'a?{500}' -O efsm >a500.efsm
  4.04s: standard -Ee 'a?{500}' -O fado >a500.fado
  4.83s: standard -Ee 'a?{500}' -O grail>a500.grail
  1.03s: standard -Ee 'a?{500}' -O tikz >a500.tikz

After:
  0.76s: standard -Ee 'a?{500}' -O dot  >a500.gv
  0.37s: standard -Ee 'a?{500}' -O efsm >a500.efsm
  0.35s: standard -Ee 'a?{500}' -O fado >a500.fado
  0.35s: standard -Ee 'a?{500}' -O grail>a500.grail
  0.68s: standard -Ee 'a?{500}' -O tikz >a500.tikz

* 2013-11-04
** Weight parsing bug fix
The weight parser used to ignore all characters after the first one, so that
for example "1-q" was considered valid and equivalent to "1".

* 2013-10-31
** product and infiltration-product are much faster
On erebus (MacBook Pro i7 2.9GHz 8GB, GCC 4.8 -O3), with "vcsn standard -E
-e 'a?70' -o a70.gv":

Before:
     13.01s: product -q -f a70.gv a70.gv
      0.23s: shuffle -q -f a70.gv a70.gv
     16.64s: infiltration -q -f a70.gv a70.gv
After:
      0.77s: product -q -f a70.gv a70.gv
      0.19s: shuffle -q -f a70.gv a70.gv
      0.87s: infiltration -q -f a70.gv a70.gv

* 2013-10-30
** TAF-Kit: option name changes.
The former options -W and -L (to specify the weightset and labelset) are
removed, definitively replaced by -C, to specify the context.

In addition to -A and -E (input is an automaton/ratexp), option -W now
replaces option -w (input is a weight), and option -P denotes "polynomials".
Note that "polynomials" are actually linear combinations of labels, weighted
by weights, so for instance "LAL" contexts accept only single-letter labels,
used LAW to accept words.

  $ vcsn cat -C 'law_char(ab)_z' -P -e 'a+ab + <-1>a+ab+<10>bb'
  <2>ab + <10>bb

** internal overhaul
Better names were chosen for the various details of the dyn:: value support:

             abstract_automaton -> automaton_base

               abstract_context -> context_base

            abstract_polynomial -> polynomial_base
   concrete_abstract_polynomial -> polynomial_wrapper

                abstract_ratexp -> ratexp_base
       concrete_abstract_ratexp -> ratexp_wrapper

             abstract_ratexpset -> ratexpset_base
    concrete_abstract_ratexpset -> ratexpset_wrapper

                abstract_weight -> weight_base
       concrete_abstract_weight -> weight_wrapper

Note that "_base" is slightly misleading, as it actually applies to the
wrappers, and not to the static objects.  For instance, weightset_wrapper
derives from weightset_base, but b, z, and the other (static) weightsets do
not derive from weightset_base.  It would therefore be more precise to name
"weightset_base" as "weightset_wrapper_base", but that might be uselessly
long.  Names may change again in the future.

Because dyn::polynomial and dyn::weight store the corresponding
polynomialset/weightset, there is no need (so far?) for a
dyn::polynomialset/dyn::weightset.  Therefore, abstract_polynomialset and
abstract_weightset were removed.

For consistency (and many other benefits), automaton_wrapper and
context_wrapper were introduced.  Now, the whole static API is completely
independent of the dyn API, and the dyn API consists only of wrappers of
"static"-level values---instead of inheritance for automata and contexts.

* 2013-10-25
** renamings (static, dynamic, TAF-Kit)
derive        -> derivation
derived-terms -> derived-term
infiltrate    -> infiltration

* 2013-10-24
** taf-kit: option -q for "quiet"
Equivalent to "-O null": do not generate output.

** star-normal-form: new algorithm (static, dynamic, TAF-Kit)
Compute an equivalent rational expression where starred subexpressions have
a non null constant term.  Yields the same standard automaton, but built
faster.

  $ vcsn star-normal-form -e '(a*b*)*'
  (a+b)*

Valid only for Boolean automata.

** ratexp printing: minimize parentheses
Print rational expressions with the minimum required number of parentheses,
making some large expressions considerably easier to read.  For example

Before:
  $ vcsn expand -C 'law_char(abc)_z' -e '(a+b)?{2}*'
  (\e+<2>a+<2>b+(aa)+(ab)+(ba)+(bb))*
  $ vcsn ladybird 2 | vcsn determinize | vcsn aut-to-exp
  \e+(a.((b+(a.a)+(c.((a+c)*).b))*).(a+(c.((a+c)*))))

After:
  $ vcsn expand -C 'law_char(abc)_z' -e '(a+b)?{2}*'
  (\e+<2>a+<2>b+aa+ab+ba+bb)*
  $ vcsn ladybird 2 | vcsn determinize | vcsn aut-to-exp
  \e+a.(b+a.a+c.(a+c)*.b)*.(a+c.(a+c)*)

** expand: new algorithm (static, dynamic, TAF-Kit)
Given a rational expression, distribute product over addition (recursively
under the starred subexpressions) group and sort the equal monomials.

  $ vcsn expand -C 'lal_char(abc)_z' -e '(a+b)?{2}*'
  (\e+<2>a+<2>b+(a.a)+(a.b)+(b.a)+(b.b))*

* 2013-10-22
Release of our first beta, vaucanson-2b.0.

* 2013-10-17
** shuffle, infiltrate: new algorithms (static, dynamic, TAF-Kit)
New algorithms on LAL automata: computes the shuffle-product and
infiltration of two automata.  These (and now product as well) require
weightsets to be commutative semirings.

  $ vcsn standard -C 'lal_char(ab)_z' -E -e 'ab' -o ab.gv
  $ vcsn product    -f ab.gv ab.gv | vcsn enumerate -O text -f - 4
  ab
  $ vcsn shuffle    -f ab.gv ab.gv | vcsn enumerate -O text -f - 4
  <4>aabb + <2>abab
  $ vcsn infiltrate -f ab.gv ab.gv | vcsn enumerate -O text -f - 4
  ab + <2>aab + <2>abb + <4>aabb + <2>abab

* 2013-10-15
** derived-terms: new algorithm (static, dynamic, TAF-Kit)
In addition to thompson and standard, this is a third means to build an
automaton from a (weighted) rational expression.  It corresponds to the
Antimirov definition of derivatives (implemented by "derive").  It requires
LAL rational expressions.

  $ vcsn derived-terms -C 'lal_char(ab)_q' -e '(<1/6>a*+<1/3>b*)*'
  digraph
  {
    vcsn_context = "lal_char(ab)_q"
    rankdir = LR
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F0
      F1
      F2
    }
    {
      node [shape = circle]
      0
      1
      2
    }
    I0 -> 0
    0 -> F0 [label = "<2>"]
    0 -> 1 [label = "<1/3>a"]
    0 -> 2 [label = "<2/3>b"]
    1 -> F1 [label = "<2>"]
    1 -> 1 [label = "<4/3>a"]
    1 -> 2 [label = "<2/3>b"]
    2 -> F2 [label = "<2>"]
    2 -> 1 [label = "<1/3>a"]
    2 -> 2 [label = "<5/3>b"]
  }

** vcsn elimininate-state
This tool allows one to eliminate states one after the other.

  $ vcsn eliminate-state -f lao.gv 2

Its interface is likely to change, or to be completely removed.

** Smaller libraries
Some compiler magic was used to reduce the size of the libraries (about 20%
on Mac OS X using GCC 4.8).  TAF-Kit might start faster.

* 2013-10-14
** determinize: by default no longer forces the result to be complete
The determinization (static, dynamic, TAF-Kit) now admits an optional second
argument (defaulting to '0'), a Boolean stating whether the result must be
complete.

* 2013-10-12
** polynomialset fully replaces entryset
The 'entryset' type is removed, as polynomialset now provides a strict
superset of its features.

* 2013-10-11
** derive: new algorithm (static, dynamic, TAF-Kit)
New algorithm on LAL automata: computes the derivation of rational
expressions with respect to a word.

  $ vcsn derive -C 'lal_char(a)_z' -e '(<2>a)*' a
  <2>(<2>a)*
  $ vcsn derive -C 'lal_char(a)_z' -e '(<2>a)*' aa
  <4>(<2>a)*
  $ vcsn derive -C 'lal_char(a)_z' -e '(<2>a)*' aaaa
  <16>(<2>a)*
  $ vcsn derive -C 'lal_char(a)_z' -e '(<2>a)*' b
  \z

  $ vcsn derive -C 'lal_char(ab)_q' -e '(<1/6>a*+<1/3>b*)*' a
  <1/3>(a*).(((<1/6>a*)+(<1/3>b*))*)
  $ vcsn derive -C 'lal_char(ab)_q' -e '(<1/6>a*+<1/3>b*)*' aa
  <4/9>(a*).(((<1/6>a*)+(<1/3>b*))*)

* 2013-10-08
** enumerate returns a dyn::polynomial
The 'enumerate' algorithm use to cheat, and returned a std::vector<string>
(each string being a pretty-printing of the monomial, e.g., "<2>a").  It now
returns a dyn::polynomial.

vcsn-enumerate is biased to prefer the 'list' output format:

  $ vcsn enumerate -Ee 'a*' 3
  \e
  a
  aa
  aaa

however the proper syntax for polynomial can be asked for.

  $ vcsn enumerate -O text -Ee 'a*' 3
  \e + a + aa + aaa

** New dyn:: type: polynomial
A new member joins the dyn:: family of types (i.e., automaton, ratexp,
ratexpset, weight, weightset).  Currently there are no means to read such a
value from TAF-Kit, but there is output support with two different output
format:

- 'text' (aka 'default')
  Prints the polynomial this usual way, e.g., "<2>a+<3>b".

- 'list'
  Prints one monomial per line, e.g.
  '<2>a
   <3>b'

* 2013-10-02
** mutable_automaton: speed improvement
"set_transition" used to invoke twice "get_transition", which had a serious
performance impact on some algorithms.  This is fixed.

Before:
  9.08s (0.33s+8.75s): ladybird 21 | determinize -O null
 16.88s (0.85s+16.03s): thompson -C "lan_char(a)_b" -Ee "a?{2000}" | proper -O null
 21.30s (9.76s+11.54s): standard -Ee "(a+b+c+d)?{100}" | aut-to-exp -O null
  7.29s (0.04s+7.25s): standard -C "lal_char(ab)_z" -Ee "(a+b)*b(<2>a+<2>b)*" | power -O null -f- 10
  0.04s (0.04s): standard -E -e "(a?){70}" -o a70.gv
 24.20s (24.20s): product -O null -f a70.gv a70.gv

After:
  8.54s (0.13s+8.41s): ladybird 21 | determinize -O null
 11.87s (0.86s+11.01s): thompson -C "lan_char(a)_b" -Ee "a?{2000}" | proper -O null
 21.03s (9.40s+11.63s): standard -Ee "(a+b+c+d)?{100}" | aut-to-exp -O null
  6.58s (0.06s+6.52s): standard -C "lal_char(ab)_z" -Ee "(a+b)*b(<2>a+<2>b)*" | power -O null -f- 10
  0.07s (0.07s): standard -E -e "(a?){70}" -o a70.gv
 13.16s (13.16s): product -O null -f a70.gv a70.gv

Note in particular that the spontaneous transition elimination algorithm is
faster, going from 16s to 11s on a MacBook Pro i7 2.9GHz 8GB RAM, on the
following sequence.

  $ vcsn thompson -C 'lan_char(a)_b' -Ee 'a?{2000}' | vcsn proper -O null

* 2013-10-01
** random: new algorithm (static, dynamic, TAF-Kit)
Random generation of automata.  Subject to changes.  Accepts four
arguments: number of states, density (of transitions, defaults to .1,
1 generates a clique), number of initial states (defaults to 1), and
number of final states (defaults to 1).

So far LAL and LAN only, no support for random weights.

  $ vcsn random -O fado 3
  @DFA 0
  0 d 1
  1 c 2
  2 d 2
  $ vcsn random -O fado 3
  @DFA 2
  0 c 1
  1 d 2
  2 c 0
  $ vcsn-random -C 'lan_char(ab)_b' -O fado 3
  @NFA 1 * 0
  0 @epsilon 1
  1 b 2
  2 b 1

* 2013-09-24
** Overhaul of the package
Thanks to Automake 1.14 features, there is now a single Makefile, which
significantly speeds up the compilation of the package.  The test-suite now
uses the Test Anything Protocol, which results in more verbose results.

Beware that because of subtle issues (in the generated Makefile snippets
that track dependencies), you are higly recommend to "make clean" after
upgrading from the Git repository, and then "make" as usual.

* 2013-09-20
** proper: faster implementation
The spontaneous transition elimination algorithm is now faster, going from
102s to 15s on a MacBook Pro i7 2.9GHz 8GB RAM, on the following sequence.

  $ vcsn thompson -C 'lan_char(a)_b' -Ee 'a?{2000}' | vcsn proper -O null

* 2013-09-17
** is-ambiguous
New algorithm (static, dynamic, TAF-Kit) on LAL automata: whether some word
is the label of at least two successful computations.

  $ vcsn is-ambiguous <<\EOF
  digraph
  {
    vcsn_context="lal_char(ab)_b"
    I -> 0
    0 -> 1 [label = "a"]
    0 -> 2 [label = "a"]
    1 -> F
  }
  EOF
  false

  $ vcsn is-ambiguous <<\EOF
  digraph
  {
    vcsn_context="lal_char(ab)_b"
    I -> 0
    0 -> 1 [label = "a"]
    0 -> 2 [label = "a"]
    1 -> F
    2 -> F
  }
  EOF
  true

Also reported in the 'info' format for automata.

** product: recover the original states
Similarly to 'determinize', the (static version of) 'product' can now be
queried to get a map from states of the result to pairs of original states.

* 2013-09-08
** Sum of standard automata is fixed
See the previous entry: the computation of the initial transition was wrong,
which resulted in the production of non-standard automata.  This is fixed:

  $ vcsn standard -C 'lal_char(a)_ratexpset<lal_char(x)_b>' -e '<x>a*' > 1.gv
  $ vcsn standard -C 'lal_char(b)_ratexpset<lal_char(y)_b>' -e '<y>b*' > 2.gv
  $ vcsn sum -f 1.gv 2.gv
  digraph
  {
    vcsn_context = "lal_char(ab)_ratexpset<lal_char(xy)_b>"
    rankdir = LR
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F0
      F1
      F2
    }
    {
      node [shape = circle]
      0
      1
      2
    }
    I0 -> 0
    0 -> F0 [label = "<x+y>"]
    0 -> 1 [label = "<x>a"]
    0 -> 2 [label = "<y>b"]
    1 -> F1
    1 -> 1 [label = "a"]
    2 -> F2
    2 -> 2 [label = "b"]
  }

* 2013-09-06
** Operations on automata are generalized
Operations (union, sum, concatenate, chain) were uselessly restricted to
LAL.  Besides, the contexts were improperly computed (both labelset and
weightset).  This is fixed.

  $ vcsn standard -C 'lal_char(a)_ratexpset<lal_char(x)_b>' -e '<x>a*' > 1.gv
  $ vcsn standard -C 'lal_char(b)_ratexpset<lal_char(y)_b>' -e '<y>b*' > 2.gv
  $ vcsn sum -f 1.gv 2.gv
  digraph
  {
    vcsn_context = "lal_char(ab)_ratexpset<lal_char(xy)_b>"
    rankdir = LR
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F0
      F1
      F2
    }
    {
      node [shape = circle]
      0
      1
      2
    }
    I0 -> 0 [label = "<\\e+\\e+\\e>"]
    0 -> F0 [label = "<x+y>"]
    0 -> 1 [label = "<x>a"]
    0 -> 2 [label = "<y>b"]
    1 -> F1
    1 -> 1 [label = "a"]
    2 -> F2
    2 -> 2 [label = "b"]
  }

* 2013-09-04
** double-ring
New algorithm (static, dynamic, TAF-Kit).

  $ vcsn double-ring -C 'lal_char(ab)_b' 6 1 3 4 5
  digraph
  {
    vcsn_context = "lal_char(ab)_b"
    rankdir = LR
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F1
      F3
      F4
      F5
    }
    {
      node [shape = circle]
      0
      1
      2
      3
      4
      5
    }
    I0 -> 0
    0 -> 1 [label = "a"]
    0 -> 5 [label = "b"]
    1 -> F1
    1 -> 0 [label = "b"]
    1 -> 2 [label = "a"]
    2 -> 1 [label = "b"]
    2 -> 3 [label = "a"]
    3 -> F3
    3 -> 2 [label = "b"]
    3 -> 4 [label = "a"]
    4 -> F4
    4 -> 3 [label = "b"]
    4 -> 5 [label = "a"]
    5 -> F5
    5 -> 0 [label = "a"]
    5 -> 4 [label = "b"]
  }

It is advised to pass "layout = circo" to Dot for the rendering.

** concatenation, chain
New algorithm on standard automata (static, dynamic, TAF-Kit).

** right-mult
New algorithm on standard automata (static, dynamic, TAF-Kit).  Same
limitations as left-mult, see below.

* 2013-09-03
** left-mult
New algorithm on standard automata (static, dynamic, TAF-Kit).

The TAF-Kit version is (currently) troublesome, as it does not infer the
context to parse the weight from the automaton: be sure to specify -C:

  $ vcsn standard -C 'lal_char(a)_z' -e a | vcsn left-mult 12
  vcsn-left-mult: left_mult: no implementation available for mutable_automaton<lal_char_z> x b
  $ vcsn standard -C 'lal_char(a)_z' -e a | vcsn left-mult -C 'lal_char(a)_z' 12
  digraph
  {
    vcsn_context = "lal_char(a)_z"
    rankdir = LR
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F1
    }
    {
      node [shape = circle]
      0
      1
    }
    I0 -> 0
    0 -> 1 [label = "<12>a"]
    1 -> F1
  }

** taf-kit: option -w for weights as input
Currently only vcsn-cat supports it.

  $ vcsn cat -w -e 2
  vcsn-cat: invalid Boolean: 2
  $ vcsn cat -w -e 1
  1
  $ vcsn cat -C 'lal_char(a)_z' -w -e 2
  2

** concatenate, star, sum
New algorithms on standard automata (static, dynamic, TAF-Kit).

* 2013-09-02
** union
New algorithm on automata (static as "union_a", dynamic as "union_a",
TAF-Kit as "union").  Plain graph union.

** is-valid
New algorithm on rational expressions (static, dynamic, TAF-Kit).

  $ vcsn is-valid -C 'lal_char(a)_r' -E -e '(<.5>\e)*'
  true
  $ vcsn is-valid -C 'lal_char(a)_r' -E -e '\e*'
  false

For consistency, is-valid is now also available for automata in dyn:: and
TAF-Kit (it used to be static only, visible from "info" output).

  $ vcsn thompson -C 'lan_char(a)_r' -e '(<.5>\e)*' | vcsn is-valid
  true
  $ vcsn thompson -C 'lan_char(a)_r' -e '\e*' | vcsn is-valid
  false

* 2013-08-13
** More RatExp quantifiers
In addition to "*", there is "?"/"{?}" and "{+}".  Support for "{*}" is
added for symmetry.

  $ vcsn cat -Ee 'a?'
  \e+a
  $ vcsn cat -Ee 'a?{3}'
  (\e+a).(\e+a).(\e+a)
  $ vcsn cat -Ee '(a+b){+}'
  (a+b).((a+b)*)

* 2013-08-02
** I/O EFSM format support
We are now able to produce and read EFSM format (designed as an interface to
OpenFST).  This is not (yet) thoroughly tested for weighted automata.

  $ vcsn ladybird -O efsm 4 |
     efstcompile | fstdeterminize | efstdecompile |
     vcsn cat -I efsm -O info
  type: mutable_automaton<lal_char(abc)_b>
  number of states: 15
  number of initial states: 1
  number of final states: 8
  number of accessible states: 15
  number of coaccessible states: 15
  number of useful states: 15
  number of transitions: 43
  number of deterministic states: 15
  number of eps transitions: 0
  is complete: 0
  is deterministic: 1
  is empty: 0
  is eps-acyclic: 1
  is normalized: 0
  is proper: 1
  is standard: 0
  is trim: 1
  is useless: 0
  is valid: 1

** Output in EFSM format is improved
State numbers now start appropriately at 0 (instead of 2), and when there is
a single initial state, no "pre-initial state" is output; this avoids the
introduction of spontaneous transitions in deterministic automata.

Before (see news of 2013-07-01):

  $ vcsn-ladybird -O efsm 2
  #! /bin/sh

  cat >transitions.fsm <<\EOFSM
  0       2       \e
  2
  2       3       a
  3       3       b
  3       3       c
  3       2       c
  3       2       a
  EOFSM

  cat >isymbols.txt <<\EOFSM
  \e      0
  a       1
  b       2
  c       3
  EOFSM

  fstcompile --acceptor --keep_isymbols --isymbols=isymbols.txt transitions.fsm

Now:

  $ vcsn ladybird -O efsm 2
  #! /bin/sh

  cat >isymbols.txt <<\EOFSM
  \e      0
  a       1
  b       2
  c       3
  EOFSM

  cat >transitions.fsm <<\EOFSM
  0       1       a
  1       0       a
  1       1       b
  1       0       c
  1       1       c
  0
  EOFSM

  fstcompile --acceptor --keep_isymbols --isymbols=isymbols.txt transitions.fsm

** I/O FAdo format support
We are now able to produce and read FAdo format.

  $ vcsn ladybird -O fado 4 | \
    python -c "from FAdo import fa
  nfa = fa.readFromFile('/dev/stdin')[0]
  dfa = nfa.toDFA()
  fa.saveToFile('dl4.fado', dfa)"

  $ vcsn cat -I fado -O info -f dl4.fado
  type: mutable_automaton<lal_char(abc)_b>
  number of states: 15
  number of initial states: 1
  number of final states: 8
  number of accessible states: 15
  number of coaccessible states: 15
  number of useful states: 15
  number of transitions: 43
  number of deterministic states: 15
  number of eps transitions: 0
  is complete: 0
  is deterministic: 1
  is empty: 0
  is eps-acyclic: 1
  is normalized: 0
  is proper: 1
  is standard: 0
  is trim: 1
  is useless: 0
  is valid: 1

** constant-term
New algorithm on rational expressions (static, dynamic, TAF-Kit).

  $ vcsn constant-term -e '(?@lal_char(a)_b)(\e)*'
  1
  $ vcsn constant-term -e '(?@lal_char(a)_z)(\e)*'
  vcsn-constant-term: z: star: invalid value: 1
  $ vcsn constant-term -C 'law_char(ab)_ratexpset<law_char(wxyz)_b>' \
                       -e '<w>(<x>a*+<y>b*)*<z>'
  w.((x+y)*).z

* 2013-07-26
** Automaton library
The set of library automata for existing contexts is now complete with
respect to what Vaucanson 1 provided.  Automata families are not, and will
not, be part of this library ; for instance, instead of looking for
ladybird-6.gv, use 'vcsn ladybird 6'.

  lal_char_b: a1.gv b1.gv evena.gv oddb.gv
  lal_char_z: b1.gv binary.gv c1.gv d1.gv
  lal_char_zmin: minab.gv minblocka.gv slowgrow.gv

Currently one must specify their path:

  $ vcsn evaluate -f share/vcsn/lal_char_zmin/minab.gv aabbba
  3

* 2013-07-25
** TAF-Kit: works on standard input by default
The very frequent "-f -" sequence is no longer required: by default the
input is stdin.

  $ vcsn ladybird 2 | vcsn determinize | vcsn aut-to-exp
  \e+(a.((b+(a.a)+(c.((a+c)*).b))*).(a+(c.((a+c)*))))

* 2013-07-18
** standard
New algorithm on automata (static, dynamic, TAF-Kit).  Corresponds to
"standardize" in Vaucanson 1.

** is-standard
New algorithm on automata (static, dynamic, TAF-Kit).  Also reported in
"info" format.

** u
New automata factory (static, dynamic, TAF-Kit): Brzozowski's universal
witness.

* 2013-07-17
** New formats: grail and fado

  $ vcsn standard -O fado -e 'a+b'
  @DFA 1 2
  0	a	1
  0	b	2
  $ vcsn standard -O fado -e 'a+ab'
  @NFA 1 3 * 0
  0	a	1
  2	b	3
  0	a	2
  $ vcsn standard -O grail -e 'a+ab'
  (START)	|-	0
  0	a	1
  2	b	3
  0	a	2
  1	-|	(FINAL)
  3	-|	(FINAL)

* 2013-07-14
** power
New algorithm on automata (static, dynamic, TAF-Kit).

  $ vcsn standard -e '(?@lal_char(01)_z)(0+1)*1(<2>0+<2>1)*' >binary.gv
  $ vcsn power -f binary.gv 0 | vcsn enumerate -f- 2
  \e
  0
  1
  00
  01
  10
  11
  $ vcsn power -f binary.gv 1 | vcsn enumerate -f- 2
  1
  <2>10
  <3>11
  $ vcsn power -f binary.gv 2 | vcsn enumerate -f- 2
  1
  <4>10
  <9>11
  $ vcsn power -f binary.gv 4 | vcsn enumerate -f- 2
  1
  <16>10
  <81>11
  $ vcsn power -f binary.gv 8 | vcsn enumerate -f- 2
  1
  <256>10
  <6561>11

* 2013-07-13
** divkbaseb
New algorithm (static, dynamic, TAF-Kit).

  $ vcsn divkbaseb -C 'lal_char(01)_b' 3 2
  digraph
  {
    vcsn_context = "lal_char(01)_b"
    rankdir = LR
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F0
    }
    {
      node [shape = circle]
      0
      1
      2
    }
    I0 -> 0
    0 -> F0
    0 -> 0 [label = "0"]
    0 -> 1 [label = "1"]
    1 -> 0 [label = "1"]
    1 -> 2 [label = "0"]
    2 -> 1 [label = "0"]
    2 -> 2 [label = "1"]
  }

* 2013-07-12
** enumerate produces a list of weighted words
enumerate now also provides the weight of the words.  It is also fixed: it
no longer reports words with nul weight (e.g., 'a' in 'a+<-1>a').

  $ vcsn standard -e '(?@lal_char(01)_z)(0+1)*1(<2>0+<2>1)*' \
      | vcsn enumerate -f - 3
  1
  01
  <2>10
  <3>11
  001
  <2>010
  <3>011
  <4>100
  <5>101
  <6>110
  <7>111

shortest is fixed and modified similarly.

  $ vcsn standard -e '(?@lal_char(ab)_z)(a+<5>bb+<-1>a)' \
        | vcsn shortest -f -
  <5>bb

* 2013-07-04
** WeightSet: added support for rational weights
We can now use automata with rational numbers as their weights.

  $ vcsn-standard -e "(?@lal_char(ab)_q)(<1/2>a+<2>b)*" \
    | ./bin/vcsn-evaluate -f - aaabbbb
  2

  $ vcsn-standard -e "(?@lal_char(ab)_q)(<1/2>a+<2>b)*"\
    | ./bin/vcsn-evaluate -f - aaab
  1/4

* 2013-07-01
** new format: efsm (and new tool: efstcompile)
The former output format ("fsm") is dropped, replaced by an adhoc "extended
FSM" format: "efsm".  The FSM format focuses only on the transitions, and
lacks information about the labels (which are expected to be mapped to
numbers), weights, whether it's an acceptor or transducer, etc.

The efsm format is designed to be simple to use with OpenFST: just run
"efstcompile" instead of "fstcompile".  As a matter fact, the new
"efstcompile" tool is rather dumb, as it simply executes the "efsm" file.

  $ vcsn-ladybird -O efsm 2
  #! /bin/sh

  cat >transitions.fsm <<\EOFSM
  0       2       \e
  2
  2       3       a
  3       3       b
  3       3       c
  3       2       c
  3       2       a
  EOFSM

  cat >isymbols.txt <<\EOFSM
  \e      0
  a       1
  b       2
  c       3
  EOFSM

  fstcompile --acceptor --keep_isymbols --isymbols=isymbols.txt transitions.fsm

  $ vcsn-ladybird -O efsm 8 | efstcompile | fstdeterminize | fstinfo \
      | grep '# of states'
  # of states                                       256

* 2013-06-28
** new binary: vcsn
To give a flavor of what TAF-Kit should be (a single tool instead of one per
command), the new "vcsn" script bounces to the vcsn-* tools.  It does not
support \| as TAK-Kit 1 did.

  $ vcsn are-equivalent -Ee '(a*b*)*' '(a+b)*'
  true

* 2013-06-26
** proper
Now removes states to which no transition arrive after spontaneous
transitions removal.

** Thompson
Only the concatenation yielded an automaton whose projection on Boolean
weights was different from the Thompson of the projection of the rational
expression on Boolean.  This is now fixed.

** is-normalized
New algorithm (static, dynamic, TAF-Kit).

* 2013-06-25
** identity, unit => one
Labels new define one() and is_one() instead of identity() and
is_identity().

We now use LAO, "labels are one", instead of LAU, "labels are unit".

WeightSets now define one() and is_one() instead of unit() and is_unit().

* 2013-06-21
** shortest, enumerate
New algorithms (static, dynamic, TAF-Kit).

* 2013-06-20
** universal
Now accepts (LAL Boolean) rational expressions.

** are-equivalent
Now accepts (LAL Boolean) rational expressions.  It cannot compare a
rational expression with an automaton (or vice-versa).  This is a temporary
defect which shell be addressed once TAF-Kit is properly developed.

  $ vcsn-are-equivalent -Ee '(a*b*)*' '(a+b)*'
  true
  $ vcsn-are-equivalent -Ee '(a*b)*' '(a+b)*'
  false

** dyn: overhaul
Consistency is enforced in dyn.  In particular the very first dynamic/static
bridge (which was not identified as such), vcsn::rat::abstract_ratexpset, is
now part of dyn::.

dyn::weight now aggregates its WeightSet instead of a Context.  More similar
conversions were performed, and other are to come.

* 2013-06-19
** dot
The output now shows useless states (and their transitions) in gray.

* 2013-06-18
** are-equivalent
New algorithm (static, dynamic, TAF-Kit).  Currently works only for LAL
Boolean automata.

  $ vcsn-standard -e 'a(ba)*' -o a1.gv
  $ vcsn-standard -e '(ab)*a' -o a2.gv
  $ vcsn-are-equivalent -f a1.gv a2.gv
  true

* 2013-06-17
** is_trim, is_useless, is_empty
New algorithms (static, dynamic, TAF-Kit).

** accessible_states, coaccessible_states, useful_states
New algorithms, static only.

** num_accessible_states, num_coaccessible_states, num_useful_states
New algorithms, static only.  Available in the "info" display.

** copy accepts a predicate
It is now possible to filter the states to keep.  Either as a predicate, or
a set of states.  For instance:

  template <typename Aut>
  Aut trim(const Aut& a)
  {
    return vcsn::copy(a, useful_states(a));
  }

** universal
New algorithm (static, dynamic, and TAF-Kit).  Requires a LAL Boolean
automaton.

  $ vcsn-universal -f a1.gv
  digraph
  {
    vcsn_context = "lal_char(ab)_b"
    rankdir = LR
    node [shape = circle]
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I0
      F2
    }
    { 0 1 2 }
    I0 -> 0
    0 -> 0 [label = "a, b"]
    0 -> 1 [label = "a"]
    1 -> 0 [label = "a, b"]
    1 -> 1 [label = "a, b"]
    1 -> 2 [label = "b"]
    2 -> F2
    2 -> 0 [label = "a, b"]
    2 -> 1 [label = "a, b"]
    2 -> 2 [label = "a, b"]
  }

** complement
New algorithm (static, dynamic, and TAF-Kit).  Requires a complete
deterministic LAL Boolean automaton.

  $ vcsn-standard -e '(?@lal_char(ab)_b)a' \
      | vcsn-determinize -f- \
      | vcsn-complement -f-  \
      | vcsn-aut-to-exp -f-
  \e+((b+(a.(a+b))).((a+b)*))

* 2013-06-13
** is-deterministic
It is conforming with the specifications: _all_ the states must be
deterministic, not just the reachable ones.

** info output adjustments
It now displays whether the automaton "is complete" and the number of
deterministic states if LAL, otherwise "N/A".  It also reports "is
deterministic: N/A" for non-LAL.

** Invalid labels are rejected
Under some circumstances, some invalid transitions could be accepted by the
Dot parser (e.g., "aa" or "\e" in LAL).  This is fixed.

* 2013-06-05
** Support for entries is removed.
Member types, functions, and variables, about entries, have been removed.
The services provided by entries in Vaucanson 1 are provided by LAU
automata, so entries are not as useful in Vaucanson 2.  And anyway, if
needed, it should rather be a set of free standing functions.

* 2013-05-27
** Refactoring: eps-removal => proper
Eps-removal is renamed to Proper.

* 2013-05-24
** Syntax for rational-expressions has changed!
Angular brackets are now used for weights.  Instead of

  $ vcsn-standard -e '(?@lal_char(01)_z)(0+1)*1({2}1+{2}0)*' -o binary.dot

run

  $ vcsn-standard -e '(?@lal_char(01)_z)(0+1)*1(<2>1+<2>0)*' -o binary.dot

Braces are now used instead of (*...) for generalized quantifiers.

  a{0} => \e
  a{1} => a
  a{2} => a.a
  a{5} => a.a.a.a.a

  a{0,1} => \e+a
  a{0,2} => \e+a+a.a
  a{0,3} => \e+a+a.a+a.a.a

  a{1,2} => a.(\e+a
  a{1,3} => a.(\e+a+a.a)

  a{2,5} => a.a.(\e+a+a.a+a.a.a)

  a{0,} => a*
  a{1,} => a.(a*)
  a{4,} => a.a.a.a.(a*)

* 2013-05-23
** info output
Now displays the number of spontaneous transitions (0 for LAL).

* 2013-04-29
** Digits as letters
Recently broken by accident, support for digits as letters is restored.

  $ vcsn-standard -e '(?@lal_char(01)_z)(0+1)*1({2}1+{2}0)*' -o binary.dot
  $ vcsn-evaluate -f binary.dot '11111111'
  255
  $ vcsn-evaluate -f binary.dot '101010'
  42

* 2013-04-26
** Dot parser
This parser is now stricter than it used to be: be sure to escape
backslashes in input Dot files, i.e.,

    0 -> 2 [label = "\e"]

is now invalid, write

    0 -> 2 [label = "\\e"]

This change was made because Graphviz treats "\e" (and renders it) exactly
like "e".

* 2013-04-25
** New algorithm: Thompson
Conversion from rational expression to automata.  Requires lan or law.
The handling of weights might be changed in the near future.

  $ vcsn-thompson -Ee '(?@lan_char(abc)_z){2}(a+{3}b+c)*{5}'
  digraph
  {
    vcsn_context = "lan_char(abc)_z"
    rankdir = LR
    node [shape = circle]
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I8
      F9
    }
    { 0 1 2 3 4 5 6 7 8 9 }
    I8 -> 8
    0 -> 2 [label = "\\e"]
    0 -> 4 [label = "\\e"]
    0 -> 6 [label = "\\e"]
    1 -> 0 [label = "\\e"]
    1 -> 9 [label = "{5}\\e"]
    2 -> 3 [label = "a"]
    3 -> 1 [label = "\\e"]
    4 -> 5 [label = "{3}b"]
    5 -> 1 [label = "\\e"]
    6 -> 7 [label = "c"]
    7 -> 1 [label = "\\e"]
    8 -> 0 [label = "{2}\\e"]
    8 -> 9 [label = "{10}\\e"]
    9 -> F9
  }

* 2013-04-22
** standard is the new name for standard-of
The "of" is useless, inconsistent with the other algorithms, and with the
TAF-Kit v1 name.

* 2013-04-18
** Evaluation is fixed
Several initializations were incorrect, expecting the zero to be 0 (which is
not the case for zmin for instance).  There might also be some speed up.

* 2013-04-16
** New output format: tikz
Layout is dumb, yet this is useful to prepare LaTeX documents.

* 2013-04-12
** New output format: info
This pseudo format displays facts about the automaton (number of states and
so on) or rational expressions (number of nodes).

** is-eps-acyclic
Can now be called on LAL automata, for consistency with is-proper and
is-valid.

* 2013-04-11
** Dot
The states are now numbered from 0.

** Clang Compatibility
Clang++ (3.2 and 3.3) can now compile Vaucanson.

* 2013-03-18
** New LabelSet: nullableset
Initial support for "Labels are nullable".

  $ cat lan.dot
  digraph lan
  {
    vcsn_context = "lan_char(a)_b"
    I1 -> 1
    2 -> F2
    1 -> 2 [label = "a"]
    1 -> 2 [label = "\e"]
  }
  $ vcsn-cat -Af lan.dot
  digraph
  {
    vcsn_context = "lan_char(a)_b"
    rankdir = LR
    node [shape = circle]
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I1
      F2
    }
    { 1 2 }
    I1 -> 1
    1 -> 2 [label = "\\e, a"]
    2 -> F2
  }
  $ vcsn-eps-removal -Af lan.dot
  digraph
  {
    vcsn_context = "lan_char(a)_b"
    rankdir = LR
    node [shape = circle]
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I1
      F2
      F1
    }
    { 1 2 }
    I1 -> 1
    1 -> F1
    1 -> 2 [label = "a"]
    2 -> F2
  }

** is-proper
New dyn algorithm and tool (vcsn-is-proper).

* 2013-03-08
** determinize speed-up
Determinization algorithm is five times faster.

Before:
  $ time bin/vcsn-de-bruijn 18 | bin/vcsn-determinize -Af - -Onull
  real    0m13.049s
  user    0m12.773s
  sys     0m0.276s
  $ time bin/vcsn-de-bruijn 20 | bin/vcsn-determinize -Af - -Onull
  real    0m56.780s
  user    0m55.775s
  sys     0m0.988s

Now:
  $ time bin/vcsn-de-bruijn 18 | bin/vcsn-determinize -Af - -Onull
  real     0m2.181s
  user     0m2.048s
  sys      0m0.132s
  $ time bin/vcsn-de-bruijn 20 | bin/vcsn-determinize -Af - -Onull
  real     0m8.653s
  user     0m8.177s
  sys      0m0.476s

* 2013-02-26
** hierarchy and API clean up
dyn:: was cleaned.  Some headers were renamed:

  vcsn/ctx/abstract_context.hh -> vcsn/dyn/context.hh
  vcsn/algos/dyn.hh            -> vcsn/dyn/algos.hh
  vcsn/core/automaton.hh       -> vcsn/dyn/automaton.hh

dyn::make_automaton was introduced to hide implementation details.

* 2013-02-21
** LabelSet renamings
The name LetterSet, UnitSet, and WordSet were not compliant.  They have been
renamed as letterset, unitset, and wordset.

* 2013-02-20
** Generalized quantifier as syntactic sugar for rational expressions
The new "(* min, max)" quantifier (postfix, like "*") allows to specify
"powers" of an expression.  For instance:

  ({a}b)(*0) => \e
  ({a}b)(*1) => {a}b
  ({a}b)(*2) => {a}b.{a}b
  ({a}b)(*5) => {a}b.{a}b.{a}b.{a}b.{a}b

  ({a}b)(*0,1) => \e+{a}b
  ({a}b)(*0,2) => \e+{a}b+({a}b.{a}b)
  ({a}b)(*0,3) => \e+{a}b+({a}b.{a}b)+({a}b.{a}b.{a}b)

  ({a}b)(*1,2) => {a}b.(\e+{a}b)
  ({a}b)(*1,3) => {a}b.(\e+{a}b+({a}b.{a}b))

  ({a}b)(*2,5) => {a}b.{a}b.(\e+{a}b+({a}b.{a}b)+({a}b.{a}b.{a}b))

  ({a}b)(*0,) => ({a}b)*
  ({a}b)(*1,) => {a}b.(({a}b)*)
  ({a}b)(*4,) => {a}b.{a}b.{a}b.{a}b.(({a}b)*)

* 2013-02-18
** Comment in rational expressions
The (?#...) construct allows to embed comments in rational expressions.
They are discarded.  There is no means to include a closing parenthesis in
this construct.

** Context in rational expressions
The (?@...) allows a rational expression to "carry" its context.  Contrast
for instance the two following runs.

  $ vcsn-cat -C 'lal_char(xyz)_z'  -Ee '{42}x+{51}z'
  {42}x+{51}z
  $ vcsn-cat -Ee '(?@lal_char(xyz)_z){42}x+{51}z'
  {42}x+{51}z

This will be used, eventually, so that TAF-Kit-like tools propagate the
context in runs such as:

  $ vcsn-cat -Ee '(?@lal_char(xyz)_z){42}x+{51}z' | vcsn-transpose -Ef -
  1.1-5: invalid Boolean: 42

Currently it fails, as the "default" context is "lal_char(abc)_b".

** New output format: fsm
An initial, and rough, support for Open FSM's format is provided.  Currently
there is no support _at all_ for the weights.

  $ vcsn-de-bruijn -O fsm 12 | fstcompile | fstdeterminize | wc -l
  1216

** New output format: null
The output is discarded.  This is useful for benching.

* 2013-02-14
** New algorithms: is-deterministic and complete
is-deterministic takes an automaton as argument and exits with code status 0
if the given automaton is deterministic, 2 otherwise.

complete also takes an automaton as argument and make it complete. If the
given automaton is already complete, then it is unchanged.

* 2013-02-12
** Overhaul of the LAU, LAL, LAW implementation
So far a context was a triple: <Kind, LabelSet, WeightSet>, where (for
instance), Kind is labels_are_letters, LabelSet is
set_alphabet<char_letters>, and WeightSet is zmin).  This is troublesome on
several regards, the clearest being that the LabelSet makes no sense for
LAU.

Now contexts are pairs: <LabelSet, WeightSet>, where this time the LabelSet
(same name as before, different concept) can be a instance of UnitSet for
LAU, WordSet for LAW, or LetterSet for LAL.  These structures, in turn, are
parameterized by the effective set of generators to use: for instance,
LetterSet<set_alphabet<char_letters>>.  Of course UnitSet is not
parameterized.

As a first visible consequence, the name of the LAU contexts has changed:

  lau_char_br => lau_br
  lau_char(xyz)_ratexpset<lal_char(abc)_b> => lau_ratexpset<lal_char(abc)_b>

* 2013-01-24
** options renamed
The options to select the input and output format are renamed -I and -O
(instead of -i and -o).

** new option: -o for output file
The vcsn-* tools now support '-o FILE' to save the output in FILE.

* 2013-01-22
** product: strengthened preconditions
The product of automata requires LAL automata.  The output alphabet is the
intersection of the ones of the operands.  This works as expected when the
automata have disjoint alphabets.

* 2013-01-18
** dyn::product and vcsn-product
They compute the product of automata.

* 2013-01-14
** vcsn-determinize and vcsn-evaluate use the common command line options
These tools support -C, -g, etc. like the other tools.  See "vcsn-<tool> -h".

** context names are now complete
Context names used to describe the "static" structure only (e.g.,
lal_char_ratexpset<law_char_b>).  It now includes the "dynamic" part,
currently only the list of generators (e.g.,
lal_char(abc)_ratexpset<law_char(xyz)_b>).

This context strings are both printed and read by the various tools.  For
instance:

  $ vcsn-standard-of -C 'law_char(xyz)_ratexpset<law_char(abc)_z>' \
        -e '{abc}xyz' | vcsn-aut-to-exp -f -
  {abc}xyz

Note that the second tool, vcsn-aut-to-exp, found the context in its input,
the standard automaton in Dot format.

* 2013-01-13
** dyn::ratexpset, dyn::context
These are now handled by shared pointer, consistently with dyn::automaton
and dyn::ratexp.

Nasty memory management issues have been fixed.

** vcsn-de-bruijn
It now supports the same arguments as the other vcsn-* tools.  It also no
longer requires 'a' and 'b' to be accepted letters, and it uses the whole
alphabet.  For instance "vcsn-de-bruijn -g 'xyz' 3" generates an automaton
for "(x+y+z)x(x+y+z)^3".

** dyn::ladybird, vcsn-ladybird
New dynamic algorithm, and new tool (which also supports the common command
line options).

* 2013-01-12
** contexts are renamed
Contexts have both a name and an identifier.  The name is used to display in
a readable form the nature of the context, for instance in Dot output.  The
identifier is used for instance headers, or predefined contexts, and
libraries.

So far names and identifiers are equal, but this will change.

As a first step, identifiers/names are now <Kind>_<LabelSet>_<WeightSet>
instead of <LabelSet>_<WeightSet>_<Kind>.  For instance:

  char_b_lal  => lal_char_b
  char_br_lal => lal_char_br
  char_zr_lal => lal_char_zr
  char_br_lau => lau_char_br
  char_br_law => law_char_br
  char_zr_law => law_char_zr

* 2013-01-11
** pprat is removed
It was designed for the test suite.  The vcsn-* tools are now sufficient for
the test suite, and are exposed to the user.

** vcsn-*: option overhaul
The different tools had already too many different calling conventions.
They are now (quite) consistent.

** vcsn-aut-to-exp
Calls the default implementation of aut-to-exp.

  $ vcsn-standard-of -Wz     -e '{2}(ab){3}' | vcsn-aut-to-exp -Af -
  ({2}a.b){3}
  $ vcsn-standard-of -Wz -Lw -e '{2}(ab){3}' | vcsn-aut-to-exp -Af -
  {6}ab

** vcsn-lift
It now also supports lifting rational expressions.

  $ vcsn-lift -C char_b_lal -Ee 'abc'
  {a.b.c}\e

* 2013-01-10
** dotty -> dot
The name "dotty" was incorrect (as it denotes a program instead of the
format).  Therefore, every occurrence of "dotty" is now mapped to "dot".

** dot
The Dot output (input and output) now uses ", " as a label separator,
instead of " + ".

* 2012-12-26
** dyn: input/output
Routines: dyn::read_(automaton|ratexp)_(file|string) and dyn::print take the
input format.  Available input/output are:
- "dotty".
- "text".
- "xml".

* 2012-12-19
** genset is replaced by labelset
Through out the code.

* 2012-12-18
** dyn: input
New routines: dyn::read_(automaton|ratexp)_(file|string).

** dyn: output
New routines: dyn::print, for both automata and RatExps.

** bin: new tools
vcsn-cat, vcsn-transpose (both on RatExps only currently).
vcsn-standard-of.
vcsn-lift.

* 2012-12-13
** krat -> rat
kratexp, kratexpset etc. are renamed as ratexp, ratexpset, etc.

** labels are unit
labels-are-empty/lae were mapped to labels-are-unit/lau.

* 2012-10-31
** dyn::context
For consistency with dyn::automaton, vcsn::ctx::abstract_context is renamed
vcsn::dyn::context.  Eventually, we might turn it into a shared pointer too.

** dyn::de_bruijn, bin/vcsn-de-bruijn
New tools, useful for tests for instance.

  $ vcsn-de-bruijn char_b_lal 2
  digraph
  {
    vcsn_context = "char_b_lal"
    vcsn_genset = "ab"
    rankdir = LR
    node [shape = circle]
    {
      node [style = invis, shape = none, label = "", width = 0, height = 0]
      I1
      F4
    }
    I1 -> 1
    1 -> 1 [label = "a + b"]
    1 -> 2 [label = "a"]
    2 -> 3 [label = "a + b"]
    3 -> 4 [label = "a + b"]
    4 -> F4
  }

* 2012-10-22
** dyn::parse_file and parse_string
They construct dyn::automaton's.

** dyn::eval
For bad reasons, currently works only for char_b_lal

** vcsn-determinize and vcsn-evaluate
Two new shell commands to write tests.

* 2012-10-12
** pprat works with abstract algorithms
pprat now uses *only* abstract (aka, dynamic) algorithms!  On OS X, it is
now a 77KB program; it was 11MB before.

This schedules its death: either it will be replaced by a set of smaller
grain commands (vcsn-determinize, vcsn-standard-of, etc.) from which test
cases will be easier to write, or it will be replaced by some early
implementation of a TAF-Kit-like *unified* program (instead of one per
context).

* 2012-10-09
** automata provide a vname
To dispatch algorithms such as dotty, we not only need to know the context
type name, but also the automaton type name, as mutable_automaton and
transpose_automaton are two different types for instance.

* 2012-10-08
** dot-parser
Because it uses only algorithms made abstract (make_context,
make_automaton_editor, and dotty), the dot parser now works for any of the
precompiled contexts!

* 2012-09-26
** add_entry
In addition to the add_entry method of mutable_automaton, there is now an
add_entry _algorithm_, which is templated by the automaton type.  This
algorithm provides an abstract interface to an unknown type of automaton.

* 2012-09-24
** renamings
For consistency, polynomials is renamed polynomialset.

** mutable_automaton::add_entry and del_entry
The first of these new functions allows to add directly a list of transition
between two states by passing the corresponding entry_t (this is most useful
when reading an automaton with entries, such as with the Dot parser).  The
second one removes every existing transition between two states.

* 2012-08-01
** labels are empty
Initial work on labels-are-empty automata.  See the unit/char_z_lae test.
The labels are not displayed, but the "{...}" to denote the weights, are
kept:

  digraph
  {
    vcsn_context=char_z_lae
    vcsn_genset=""
    rankdir=LR
    node [shape=circle]
    {
      node [style=invis,shape=none,label="",width=0,height=0]
      I1
      F2
    }
    I1 -> 1
    2 -> F2 [label="{10}"]
    1 -> 2 [label="{51}"]
    2 -> 3 [label="{3}"]
    2 -> 1
    1 -> 1 [label="{42}"]
    1 -> 3
  }

In that case, the transitions do not store labels.

** lift now returns a labels-are-empty automaton/ratexp
Accordingly, pprat -l (lift) now displays:

  $ pprat -Lw -l 'ab+cd'
  digraph
  {
    vcsn_context=char_kratexpset<char_b_law>_lae
    vcsn_genset="abcd"
    rankdir=LR
    node [shape=circle]
    {
      node [style=invis,shape=none,label="",width=0,height=0]
      I1
      F2
      F3
    }
    1 -> 2 [label="{ab}"]
    2 -> F2
    I1 -> 1
    3 -> F3
    1 -> 3 [label="{cd}"]
  }

* 2012-07-31
** dot-parser
It is now possible to load an automaton from its dotty output.  Actually, it
is possible to write simpler automata.  This is no yet fully generic: it
works properly only for char_b_lal.

The test program unit/parse-dot gives access to it.  When fed with the
following input file:

  digraph
  {
    vcsn_context=char_b_lal vcsn_genset="a"
    {1} -> {2 3} -> {4 5 6} [label=a]
    I -> 1
    {4 5 6} -> F
  }

it produces an automaton, and dumps it using the dotty algorithm:

  digraph
  {
    vcsn_context=char_b_lal
    vcsn_genset="a"
    rankdir=LR
    node [shape=circle]
    {
      node [style=invis,shape=none,label="",width=0,height=0]
      I1
      F4
      F5
      F6
    }
    1 -> 2 [label="a"]
    1 -> 3 [label="a"]
    2 -> 4 [label="a"]
    2 -> 5 [label="a"]
    2 -> 6 [label="a"]
    3 -> 4 [label="a"]
    3 -> 5 [label="a"]
    3 -> 6 [label="a"]
    I1 -> 1
    4 -> F4
    5 -> F5
    6 -> F6
  }

* 2012-07-25
** pprat uses -L for labels instead of -A
For consistency, since we now also use the name "labels" to denote the
leaves of rational expressions (others that \z and \e), -A is renamed -L.

** Metadata are embedded in the Dot file
The pseudo name "A" which was used in every dotty output is no longer
defined, as it is both optional and useless.  The context name and the
alphabet are also provided.  For instance:

  $ ./tests/unit/ladybird-b 2 | sed 4q
  digraph
  {
    vcsn_context=char_b_lal
    vcsn_genset="abc"
  $ pprat -s -L z 'abc' | sed 4q
  digraph
  {
    vcsn_context=char_z_lal
    vcsn_genset="abcd"
  $ pprat -s -L zr -A w 'abc' | sed 4q
  digraph
  {
    vcsn_context=char_kratexpset<char_z_law>_law
    vcsn_genset="abcd"

This is an experimentation, and the current choice is somewhat
unsatisfactory.  Instead of

    vcsn_context=char_b_lal
    vcsn_genset="abc"

it is probably more sensible to use

    vcsn_context="char_b_lal{abc}"

or maybe

    vcsn_context="char{abc}_b_lal"

so that when weightsets depend for instance upon an alphabet, it can be
specified too.  Instead of

    vcsn_context=char_kratexpset<char_z_law>_law
    vcsn_genset="abcd"

(which does not define the alphabet used for the weightset), one would
expect:

    vcsn_context=char_kratexpset<char_z_law{xyz}>_law{abcd}

or maybe

    vcsn_context=char{abcd}_kratexpset<char{xyz}_z_law>_law

Also, the name "kratexpset" is of course open to discussion:

    vcsn_context=char_rat<char_z_laz{xyw}>_law{abcd}

** polynomials::conv
It is now possible to read back polynomials such as "a+b+{2}a".

** static_assert
It is used more extensively to forbid meaningless calls, such as
determinizing a law automaton.

* 2012-07-13
** Precompiled contexts
Several predefined contexts come with their own header (e.g.,
"ctx/char_b_lal"), and their own library (e.g., "libchar_b_lal").  This is
provide for char_{b,z,zmin}_{lal,law}.

** z_min renamed zmin
Consistently with Vaucanson 1.4.

* 2012-07-10
** transposition
Transposition on automaton is a read/write view: operations such as
del_state, add_transition, etc. on a transposed automaton actually modify
the wrapped automaton: set_final calls set_initial and so forth.

As an extreme example, the following snippet:

  using context_t = vcsn::ctx::char_b;
  using automaton_t = vcsn::mutable_automaton<context_t>;
  using tr_automaton_t = vcsn::details::transpose_automaton<automaton_t>;
  context_t ctx{{'a', 'b'}};
  auto ks = ctx.make_kratexpset();
  auto aut = vcsn::standard_of<tr_automaton_t>(ctx, ks.conv("a+a+a+a"));

applies the standard-of algorithm to a transposed mutable_automaton.  In
other words,

  aut.original_automaton();

is the transposition of a standard automaton, except that it is a
mutable_automaton, not a transpose_automaton<mutable_automaton>.

* 2012-07-09
** transposition
The "transpose" operation is implemented on words, weights, kratexps, and
automata.  pprat provides support to transpose on kratexps (option -t):

  pprat -W zrr -t {{{2}ab}cd}abcd   =>   {{{2}ba}dc}dcba
  pprat -W zrr -t {ab}(abcd)*{cd}   =>   ({dc}(dcba)*{ba})

and on (standard) automata (option -T):

  $ pprat -A w -W br    -s '{ab}(\e+a+b({abc}c{bcd})*){cd}' > forward.dot
  $ pprat -A w -W br -T -s '{ab}(\e+a+b({abc}c{bcd})*){cd}' > transpose.dot
  $ diff -W80 -t  -y forward.dot transpose.dot
  digraph A {                            digraph A {
    rankdir=LR                             rankdir=LR
    node [shape=circle]                    node [shape=circle]
    {                                      {
      node [style=invis,shape=none,la        node [style=invis,shape=none,la
      I1                                     I1
                                      >      I2
                                      >      I4
      F1                                     F1
      F2                              <
      F4                              <
    }                                      }
    1 -> F1 [label="{(ab).(cd)}"]     |    I1 -> 1 [label="{(dc).(ba)}"]
    I1 -> 1                           |    1 -> F1
    2 -> F2 [label="{cd}"]            |    I2 -> 2 [label="{dc}"]
    1 -> 2 [label="{ab}a"]            |    2 -> 1 [label="{ba}a"]
    4 -> F4 [label="{cd}"]            |    I4 -> 4 [label="{dc}"]
    4 -> 4 [label="{(abc).(bcd)}c"]   |    4 -> 4 [label="{(dcb).(cba)}c"]
    1 -> 3 [label="{ab}b"]            |    3 -> 1 [label="{ba}b"]
    3 -> 4 [label="{(abc).(bcd)}c"]   |    4 -> 3 [label="{(dcb).(cba)}c"]
  }                                      }

* 2012-06-19
** aut_to_exp
An initial version of aut_to_exp is available.  The new pprat option -a
provides an access to this algorithm: apply aut_to_exp to the standard_of an
expression.

  pprat      -a 'a*'     => \e+(a.(a*))
  pprat      -a '(a+b)c' => (a.c)+(b.c)
  pprat -W z -a '{2}({3}a+{5}b){7}c{11}' => (({6}a.{7}c)+({10}b.{7}c)){11}

Currently, the only "heuristic" implemented eliminates the states in order.
There are probably possible improvements.

  pprat -a '(a+b)*' | wc -c => 265

** pprat: -a and -w are renamed -A and -W

** new factory: de Bruijn
Builds automata for (a+b)a(a+b)^n.

* 2012-06-18
** standard_of is part of vcsn::
It used to be in vcsn::rat::.

* 2012-06-14
** kratexpset/abstract_kratexpset
kratexpset, i.e. the object that provides operation on kratexps (with
specified Gen and Weight), used to derive from abstract_kratexp (which is
"opaque": it does not know the precise type that is used underneath).

Now, from abstract_kratexp we derive a concrete_abstract_kratexpset
which *aggregates* a kratexpset.  This means that kratexpset no longer
derives from a weakly-typed ancestor, and can provide simple and
strongly-typed routines.

** kratexpset/kratexp
For consistency with weightset/weight, genset/gen, kratexps (note the s) is
renamed as kratexpset and std::shared_ptr<const rat::node> as kratexp.

** lift
A new algorithm which creates, from an automaton, another one with the same
states and transitions, but the new automaton features only spontaneous
transitions, whose weights correspond to the labels (and weights) of the
initial one.

For instance:

  $ pprat -aw -wz  -sl '({2}\e+{3}a){4}'
  digraph A {
    rankdir=LR
    node [shape=circle]
    {
      node [style=invis,shape=none,label="",width=0,height=0]
      I1
      F1
      F2
    }
    1 -> F1 [label="{8}"]
    I1 -> 1
    2 -> F2 [label="{4}"]
    1 -> 2 [label="{3}a"]
  }

  digraph A {
    rankdir=LR
    node [shape=circle]
    {
      node [style=invis,shape=none,label="",width=0,height=0]
      I1
      F1
      F2
    }
    1 -> F1 [label="{{8}\\e}"]
    I1 -> 1
    2 -> F2 [label="{{4}\\e}"]
    1 -> 2 [label="{{3}a}\\e"]
  }

** RatExps: fix is_unit
is_unit simply checked that the expression was \e, but did not check that
weight itself was the unit.

** VCSN_DEBUG
This variable allows to force the display of weights.

* 2012-06-11
** Contexts aggregate shared pointers
Now contexts are mutable, and hold (shared) pointers to (immutable) gensets
and weightsets.  This way, we can alter contexts (e.g., the ladybird factory
can add the letters it needs in a new genset), yet there is good sharing,
and identity can still be used to distinguish, for instance, two gensets
defined equally.

It is also simpler to really expose them as pointers, so every
"weightset().mul", etc. must be rewritten as "weightset()->mul".

* 2012-06-08
** Contexts
The Kind parameter is now part of the context.  The same type of Kind is now
use for both RatExps and automata.  This results in many significant
simplifications.

For instance, again, the test case for product:

Before:

   using context_t = vcsn::ctx::char_z;
   context_t ctx { {'a', 'b', 'c'} };
   using automaton_t =
     vcsn::mutable_automaton<context_t, vcsn::labels_are_letters>;
   automaton_t aut1(ctx);

After:

  using context_t = vcsn::ctx::char_z;
  context_t ctx { {'a', 'b', 'c'} };
  using automaton_t = vcsn::mutable_automaton<context_t>;

Or the source of pprat:

Before:

  using atom_kind_t
    = typename Factory::kind_t;
  using label_kind_t
    = typename vcsn::label_kind<atom_kind_t>::type;
  using context_t =
    vcsn::ctx::context<typename Factory::genset_t,
                       typename Factory::weightset_t,
                       label_kind_t>;
  context_t ctx{factory.genset(), factory.weightset()};
  using automaton_t = vcsn::mutable_automaton<context_t>;
  auto aut = vcsn::rat::standard_of<automaton_t>(ctx, e);

After:

  using context_t = typename Factory::context_t;
  using automaton_t = vcsn::mutable_automaton<context_t>;
  auto aut = vcsn::rat::standard_of<automaton_t>(factory.context(), e);


* 2012-06-05
** Contexts
"Contexts" were introduced to factor two aspects that are required through
out the library: the GenSet type (i.e., the nature of the generators), and
the WeightSet type (i.e., the nature of the weights).  Not only do contexts
define these types, they must also be instantiated so that "run-time"
details be known: for instance the set of generators is dynamic (what are
the allowed letters), and on occasion the weightset also needs run-time
information (e.g., when RatExp are parameterized by RatExp, what is the
alphabet of the latter ones?).

As an example of the changes on the user side, consider the product
test-case.

Before:

   typedef vcsn::set_alphabet<vcsn::char_letters> alpha_t;
   typedef vcsn::mutable_automaton<alpha_t, vcsn::z,
                                  vcsn::labels_are_letters> automaton_t;
   vcsn::z z;
   alpha_t alpha{'a', 'b', 'c'};
   automaton_t aut1(alpha, z);

After:

   using context_t = vcsn::ctx::char_z;
   context_t ctx { {'a', 'b', 'c'} };
   using automaton_t =
     vcsn::mutable_automaton<context_t, vcsn::labels_are_letters>;
   automaton_t aut1(ctx);

* 2012-05-30
** RatExp: atoms are words
Expressions such as "(ab)(ab)" used to be equivalent to "(abab)" (a
single four-letter atom).  Now:

  pprat -aw '(ab)(ab)'   => (ab).(ab)
  pprat -aw 'abab'       => abab
  pprat -aw 'ab.ab'      => (ab).(ab)
  pprat -aw 'ab(ab)abc*' => (ab).(ab).(ab).(c*)

* 2012-05-28
** New algorithm: eval, evaluates a word over an (weighted) automaton
Defined in vcsn/algos/eval.hh as vcsn::eval.

** New algorithm: determinize, Boolean automaton determinization
Defined in vcsn/algos/determinize.hh as vcsn::determinize.

* 2012-05-25
** RatExp: changes in the display
Fixed the output of "atoms are words" expressions.  For instance
"(ab)*" used to be displayed as "ab*" (which is wrong as it is parsed
as "a(b*)").  It is now properly displayed as "(ab)*".

** RatExp: slight changes in the grammar
A star is now valid after a weight:

  $ pprat -w z '{2}ab{3}*'
  ({2}(a.b){3})*

* 2012-05-11
** dotty: define initial/final states first
In order to improve readability, instead of

  digraph A {
    rankdir=LR
    node [shape=circle];
    F1 [style=invis,shape=none,label="",width=0,height=0]
    1 -> F1 [label="{a.a.((d.d)*)}"]
    3 -> 2 [label="{(d.d)*}b"]
    I1 [style=invis,shape=none,label="",width=0,height=0]
    I1 -> 1
    1 -> 2 [label="{a.a.((d.d)*)}b"]
    F3 [style=invis,shape=none,label="",width=0,height=0]
    3 -> F3 [label="{(d.d)*}"]
    2 -> 3 [label="b"]
  }

we now produce

  digraph A {
    rankdir=LR
    node [shape=circle]
    {
      node [style=invis,shape=none,label="",width=0,height=0]
      I1
      F1
      F3
    }
    1 -> F1 [label="{a.a.((d.d)*)}"]
    3 -> 2 [label="{(d.d)*}b"]
    I1 -> 1
    1 -> 2 [label="{a.a.((d.d)*)}b"]
    3 -> F3 [label="{(d.d)*}"]
    2 -> 3 [label="b"]
  }

* 2012-05-10
** RatExp: support for the kind of atoms
As a major overhaul, the rational expressions (vcsn::rat::node) are
now parameterized by Atom, which denotes the atom value.  The kratexps
structure is now parameterized by the Kind, from which it is deduced,
from the GenSet parameter, whether we should use word_t or letter_t
atoms.

** pprat: an option -a
To provide user-access to these feature, pprat now supports an option
-a, which accepts "letters" or "words" as argument, with obvious
meaning.  For instance:

  pprat -a letters 'abc' => a.b.c
  pprat -a letters 'abc.abc' => a.b.c.a.b.c
  pprat -w br -al '{aa}bb{c}dd{a}' => ({a.a}(b.b).{c}(d.d)){a}

  pprat -a words 'abc' => abc
  pprat -a words 'abc.abc' => abc.abc
  pprat -w br -aw '{aa}bb{c}dd{a}' => ({aa}bb.{c}dd){a}

Of course, this also works with the "standard-of" option:

  $ pprat -w br -al '{aa}({dd}\e+bb)*'
  {a.a}(({d.d}\e+(b.b))*)
  $ pprat -s -w br -al '{aa}({dd}\e+bb)*'
  digraph A {
    rankdir=LR
    node [shape=circle];
    F1 [style=invis,shape=none,label="",width=0,height=0]
    1 -> F1 [label="{a.a.((d.d)*)}"]
    3 -> 2 [label="{(d.d)*}b"]
    I1 [style=invis,shape=none,label="",width=0,height=0]
    I1 -> 1
    1 -> 2 [label="{a.a.((d.d)*)}b"]
    F3 [style=invis,shape=none,label="",width=0,height=0]
    3 -> F3 [label="{(d.d)*}"]
    2 -> 3 [label="b"]
  }

versus:

  $ pprat  -w br -aw '{aa}({dd}\e+bb)*'
  {aa}(({dd}\e+bb)*)
  $ pprat -s -w br -aw '{aa}({dd}\e+bb)*'
  digraph A {
    rankdir=LR
    node [shape=circle];
    F1 [style=invis,shape=none,label="",width=0,height=0]
    1 -> F1 [label="{aa.(dd*)}"]
    2 -> 2 [label="{dd*}bb"]
    F2 [style=invis,shape=none,label="",width=0,height=0]
    2 -> F2 [label="{dd*}"]
    1 -> 2 [label="{aa.(dd*)}bb"]
    I1 [style=invis,shape=none,label="",width=0,height=0]
    I1 -> 1
  }


* 2012-05-07
** RatExp: in some case the weights could be lost
"Associativity" was applied too eagerly, which would result in loss of
some weights.  E.g. {a}bb{c}dd resulted in b.b.d.d, not it evaluates
to {a}(b.b).{c}(d.d).

* 2012-05-03
** RatExp: improved pretty-printing
The outermost pair of parentheses is removed if useless.  For
instance:

   (a.b) => a.b
   (a+b+c) => a+b+c
   (a*) => a*

But in the following examples they are kept.

   {3}(a.b){4}
   {3}(a*)
   (a+b){4}

** standard-of: star is fixed
Standard-of seems to be correct.

* 2012-04-25
** Expressions overhaul
They are immutable: we no longer make side effects on expressions.
They are shared_ptr, no longer plain pointers.  They *can* be used
like the other values, by value.

* 2012-04-19
** standard-of is fully implemented
Support for star was implemented, and checked for B and Z.  For
implementation reasons, one cannot yet use rational expressions as
weights.

* 2012-04-18
** mutable_automata::mul_weight

** RatExp::head and tail

** dotty
In order to improve the readability of its output, it no longer
"defines" the reachable states.  See the following diff:

   digraph A {
     rankdir=LR
     node [shape=circle];
  -  1
  -  2
  -  3
  -  4
     I1 [style=invis,shape=none,label="",width=0,height=0]
     I1 -> 1 [label="{6}"]
     F1 [style=invis,shape=none,label="",width=0,height=0]
     1 -> F1
     1 -> 2 [label="a"]
     1 -> 3 [label="a"]
     2 -> 4 [label="{3}b"]
     F4 [style=invis,shape=none,label="",width=0,height=0]
     4 -> F4
     4 -> 3 [label="a"]
   }


** standard-of: many fixes in the handling of the weights
An expression such as "{12}\e" used to leave the weight in the initial
transition; it is now on the final transition.  More generally the
initial transition always has unit as weight.

The product and sum of expressions now handle the left and right
weights.

Accepting initial states in expressions such as "\e+a" are no longer
lost.

* 2012-04-11
** Many renamings
  alphabet_t/alphabet() -> genset_t/genset(), etc.
  factory -> abstract_kratexp.
  factory_ -> kratexp.
  initials() -> initial_transitions(), etc.
  invalid_state -> null_state, etc.
  nb_state() -> num_states(), etc.
  polynomial -> polynomials, etc.

* 2012-04-09
** product

  An implementation of the product of two automata is available.

* 2012-04-07
** z_min

  An example of tropical semiring, to test show_unit().

* 2012-04-05
** char_letters::special()

  This method return a special, reserved character, that is used to
  label initial and final transitions.  This character is not part of
  the alphabet and is never output.

* 2012-04-04
** standard-of
Initial work on "+".

** mutable_automata are implemented using a pre() and post() states

  What is missing is the correct '$' letter on the initial and final
  transitions.  The current value is the default value for label_t.

  The previous interface has been preserved (but maybe we should
  clean it) except for one change:

    initial() and final() have been changed to return a pseudo
    container of transitions.  These transitions give us both
    the weight and the initial/final state.

  The following methods are new:

    pre(), post()         returns the pre-initial and post-final state.
    all_states()          returns all states, including pre() and post()
    all_transitions()     returns all transitions, including initial and
                            final transitions
    all_entries()         likewise for entries
    all_out(s), all_in(s) likewise for outgoing and ingoing transitions


  The methods get_initial_weight(s) and get_final_weight(s) are slower
  now, because they need to locate the corresponding initial/final
  transition.  For the same reason, is_initial(), is_final() are also
  slower.

* 2012-04-03
** standard-of
Initial version of standard-of is implemented.  Can be tested with
pprat's new option -s:

  $ pprat -wz -s '{123}a'
  digraph A {
    rankdir=LR
    node [shape=circle];
    1
    I1 [style=invis,shape=none,label="",width=0,height=0]
    I1 -> 1
    2
    F2 [style=invis,shape=none,label="",width=0,height=0]
    2 -> F2
    1 -> 2 [label="{123}a"]
  }

** mutable_automaton uses unsigned for state_t and transition_t.

This allows to store states in a std::vector<stored_state_t>.
Likewise for transitions.  Erased elements are marked (so they are
skipped over during iteration), and added to a free store to be reused
later.

** mutable_automaton does not store any weight when WeightSet == b.

** mutable_automaton has a read-only entry interface

  entries() is a pseudo container that filters transitions()
    to see each (src,dst) pair at most once.

  entry_at(src, dst) and entry_at(t) return a polynomial describing
    the entry between (src, dst) or (src_of(t), dst_of(t)).

  entryset() returns the WeightSet that can be used to manipulate
    these polynomials.

** make check-rat, make check-unit

There is a check target for each subdirectory of tests/.

* 2012-04-02
** Alphabets are checked
pprat is hard-coded to use a, b, c, d for all the alphabets
(including for inner rational expressions):

  $ pprat -w b -e 'y'
  1.1: invalid word: y: invalid letter: y

** Weights are checked
As follows:

  $ pprat -w b -e '{12}a'
  1.1-5: invalid Boolean: 12

Unfortunately the locations are bad currently for complex weights:

  $ pprat -w zr -e '{x}a'
  1.1-4: 1.1: invalid word: x: invalid letter: x

To be fixed.

* 2012-03-30
** G++ 4.7 is required
We use constructs that are not supported by 4.6 (e.g., constructor
delegation).

** zrr
As a demonstration that rational expressions can be weights of
rational expressions, pprat supports '-w zrr' (Rat<Rat<Z>>):

   $ pprat -w zr -e '{{{2}{3}a}u}x{{{4}{5}\e}\e}'
   {{{120}a}u}x

--
Local Variables:
mode: outline
coding: utf-8
ispell-dictionary: "american"
fill-column: 76
End:

LocalWords:  TAF LAL automata vcsn EOF lal determinize ratexpset gv xy mult
LocalWords:  rankdir invis labelset weightset circo taf dyn thompson lan Ee
LocalWords:  RatExp EFSM OpenFST efsm efstcompile fstdeterminize abc eps dl
LocalWords:  efstdecompile coaccessible acyclic pre fsm EOFSM isymbols txt
LocalWords:  fstcompile acceptor FAdo fado nfa readFromFile dfa toDFA wxyz
LocalWords:  Vaucanson evena oddb zmin minab minblocka slowgrow aabbba aut
LocalWords:  stdin Brzozowski's divkbaseb nul bb WeightSet aaabbbb aaab TAK
LocalWords:  adhoc fstinfo LAU WeightSets ba num typename const aa Graphviz
LocalWords:  Refactoring initializations tikz LaTeX LabelSet nullableset Af
LocalWords:  nullable Determinization de bruijn Onull sys API renamings xyz
LocalWords:  LetterSet UnitSet WordSet letterset unitset wordset postfix Ef
LocalWords:  FSM's wc parameterized lao br zr lau pprat Wz Lw ratexp xml cd
LocalWords:  genset RatExps krat kratexp kratexpset lae vname precompiled
LocalWords:  templated polynomialset del abcd Metadata sed weightsets laz
LocalWords:  xyw determinizing ctx libchar conv kratexps zrr dcba bcd dcb
LocalWords:  cba wz sl gensets mul GenSet typedef abab eval determinization
LocalWords:  al Associativity ptr nb semiring ingoing pprat's src dst utf
LocalWords:  entryset subdirectory ispell american
