The Vcsn team is happy to announce the long overdue release of Vcsn 2.6.
Most of our work was devoted to providing a better, smoother, user
experience. This includes improvements in the build system, better
performances, extended consistency, and more legible error messages.
Multitape expressions also received a lot of attention.
For more information see the detailed news below.
We warmly thank our users who made valuable feedback (read "bug reports")
including Victor Miller, Dominique Soudière and Harald Schilly. Dominique
and Harald helped integrating Vcsn into CoCalc (formerly SageMathCloud).
People who contributed to this release:
- Akim Demaille
- Clément Démoulins
- Clément Gillard
- Sarasvati Moutoucomarapoulé
Our next stop should be Vcsn 3.0, which will include extensive changes from
Sarasvati.
Release page:
https://vcsn.lrde.epita.fr/Vcsn2.6
Tarball:
https://www.lrde.epita.fr/dload/vcsn/2.6/vcsn-2.6.tar.bz2
Home page:
https://vcsn.lrde.epita.fr
The various packages (Docker, Debian, MacPorts, etc.) will appear
soon.
## New features
### Promotion from single to multitape
It is now possible to mix single-tape expressions with multitape
expressions. This is especially handy when using labels classes (`[abc]`).
For instance:
In [2]: zmin2 = vcsn.context('lat<lan, lan>, zmin')
In [3]: zmin2.expression(r'([ab] + ⟨1⟩(\e|[ab] + [ab]|\e))*')
Out[3]: (a|a+b|b+<1>(\e|(a+b)+(a+b)|\e))*
is a easy means to specify an expression generating an automaton that
computes the edit-distance (between words or languages). Or, with a wide
alphabet:
In [4]: zmin = vcsn.context('lan(a-z), zmin')
In [5]: zmin2 = zmin | zmin
In [6]: zmin2
Out[6]: {abcdefghijklmnopqrstuvwxyz}? x {abcdefghijklmnopqrstuvwxyz}? -> Zmin
In [7]: zmin2.expression(r'([^] + ⟨1⟩(\e|[^] + [^]|\e))*')
In the future the display of expressions will also exploit this approach.
### vcsn compile now links with precompiled contexts
If you write a program using dyn::, then it will benefit from all the
precompiled algorithms.
### vcsn compile now supports --debug
Use this to avoid the removal of intermediate object files. On some
platforms, such as macOS, the object file contains the debug symbols, so
their removal makes the use of a debug harder.
### vcsn compile now uses -rpath
Programs/libraries generated by `vcsn compile` needed to be told where the
Vcsn libraries were installed. In practice, it meant that `vcsn run` was
needed to execute this program, and in some situations it was not even
sufficient.
Now, `vcsn compile my-prog.cc` generates `my-prog` which can be run directly.
### random_expression supports the tuple operator
It is now possible to generate multitape expressions such as `(a|x*)*`.
Before, random_expression was limited to expressions on multitape labels
such as `(a|x)*`.
In [1]: import vcsn
In [2]: c = vcsn.context('lan(abc), q')
In [3]: c2 = c | c
In [4]: for i in range(10):
...: e = c2.random_expression('|, +, ., *=.2, w.=.2, w="min=-2,
max=2"', length=10)
...: print('{:u}'.format(e))
...:
a|a+(ε|b)*+⟨1/2⟩ε|ε
(ε+c)a|(⟨2⟩ε+c)
(ε|b+(c|a)*)*
ε|a+a|b
c|b+⟨2⟩ε|(ε+b)
ε|a+((a|ε)(ε|b)(ε|c))*(b|ε)
(a|b+c|ε)(a|b)
ε*|ε
ε+a|a+⟨2⟩(b|ε)
(ε+ε*)|ε
Generating expressions with compose operators is also supported.
In [5]: for i in range(10):
...: e = c2.random_expression('|=.5, +, ., @=2', length=10,
identities='none')
...: print('{:u}'.format(e))
...:
((b|ε)ε)(ε(ε|a))
ε(ε|c)+((ε|a)(a|b)+ε|c)
((ε|a)(ε|b))((b|a)(c|c)@b|b)
(b|b@ε+a|b)@(c|ε@b|ε)
(ε+ε|a)@(ε|c@ε|a+b|ε)
(ε|a+ε|c)((ε|b)(c|ε))
(a|ε)((ε+c)|(a+ε))
c|ε@(a|ε)(ε|b@b|ε)
(ε+ε|b)@ε|b+ε|a
b(ε²)|((ε+ε)+a)
### New algorithms
A few algorithms were added:
- context.compose
Composing `{abc} x {xyz}` with `{xyz} x {ABC}` gives, of course,
`{abc} x {ABC}`.
- expansion.normalize, expansion.determinize
These are rather low-level features. The latter is used internally when
derived-term is asked for a deterministic automaton.
- expansion.expression
The "projection" of an expansion as an expression.
- label.compose
For instance `a|b|x @ x|c` -> `a|b|c`.
- polynomial.compose
Additive extension of monomial composition. For instance composing
`a|e|x + a|e|y + a|e|\e` with `x|E|A + y|E|A + \e|E|A` gives
`<3>a|e|E|A`.
- polynomial.shuffle and polynomial.infiltrate
The missing siblings of polynomial.conjunction.
### Doxygen is no longer needed
By default, `make install` generated and installed the C++ API documentation
using Doxygen. It is now disabled by default, pass `--enable-doxygen` to
`configure` to restore it.
## Bug Fixes
### Severe performance regression when reading daut
Version 2.5 introduced a large penalty when reading daut files, especially
large ones.
### Tupling of automata could be wrong on weights
As a consequence, `expression.inductive` was also producing incorrect
automata from multitape expressions.
### Polynomials featuring the zero-label
Under some circumstances it was possible to have polynomials featuring
monomials whose label is the zero of the labelset (e.g., `\z` with
expressions as labels). This is fixed.
### Portability issues
Newest compilers are now properly supported.
## Changes
### Divisions
The division of expressions and automata now compute the product of the
weights, not their quotient.
### Handling of the compose operator
The support of the compose operators in expansions was completely rewritten.
As a result, the derived-term automata are often much smaller, since many
useless states (non coaccessible) are no longer generated.
For instance the derived-term automaton of `(\e|a)* @ (aa|\e)*` has exactly
two states. It used to have three additional useless states.
### Better diagnostics
Many error messages have been improved.
The Daut automaton format now treats `->` as a keyword, so `0->1 a` is now
properly read instead of producing a weird error message because Vcsn
thought your state was named `0->1`.