Writing programs with Vcsn is quite simple once you're familiar with the library.
When using the static version of the library, use algorithms from the vcsn::
namespace. These algorithms are highly templated and hence require the user to know the context and parameters of these algorithms at compile time.
This part of the library provides less flexibility but ensures that all of the required code will be compiled before runtime.
The dyn version of the library consists of algorithms from the vcsn::dyn::
namespace. These algorithms provide an abstraction from the static library that hides from users the actual fully templated versions of algorithms. This allows more flexibility as the user does not have to know the context of automata at compile time and new types of automata can be created at runtime. However, algorithms may need to be compiled at runtime, lowering the program's performances (once compiled algorithms are cached and can be used without further compilation though).
Compiling your program will then require to use the Vcsn program with the compiler option and can be done as such:
$ vcsn compile source.cc
It is also possible to modify the programs compilation options and compiler in the command line option:
$ vcsn compile CXX='g++' CXXFLAGS+='-g3' source.cc
Run vcsn compile --help
for additional options. This page provides examples of use of vcsn compile
, see below.
When actually running the program you just compiled you might have to use the Vcsn program as well through the run option:
$ vcsn run my-prog args...
The command can be followed directly by the arguments of your program.
Possibly just running my-prog
would work too, but it depends on your setup. In case of doubt, use vcsn run
.
More samples of code are present in the tests/demo
directory of the project from which you can inspire yourself.
import vcsn
This a simple example which shows how to build dyn
labels, weights, etc. and how to manipulate them with operators such as +
.
For a start, labels are the simplest objects: you can hardly do more that concatenating them, thanks to *
. You may also run multiply(a, b)
instead of a * b
. The following examples shows how to compare labels too.
# Don't worry about this "magic" line: it selects some lines from
# the `operators.cc` file, and pretty-prints them.
!perl -ne '(/labels:/ ... /labels:/) && !/labels:/ && print' ../../tests/demo/operators.cc | pygmentize -l c++
Weights are more capables than labels: in addition to multiplication, they support conjunction and addition.
!perl -ne '(/weights:/ ... /weights:/) && !/weights:/ && print' ../../tests/demo/operators.cc | pygmentize -l c++
Of course, expressions are more interesting: they support a wide range of operators, and many functions.
!perl -ne '(/expressions:/ ... /expressions:/) && !/expressions:/ && print' ../../tests/demo/operators.cc | pygmentize -l c++
Automata also offer a rich feature set.
!perl -ne '(/automata:/ ... /automata:/) && !/automata:/ && print' ../../tests/demo/operators.cc | pygmentize -l c++
prod-eval
¶The following example shows how to use basic operations on automata to implement a simple processing: load two automata, compute their conjunction, and evaluate a word on it. It is implemented twice: once in dyn::
and then in the static library, vcsn::
.
The dyn
version is straightforward, users do not have to have to track exact types of the automata, labels and weights.
!perl -ne '(/dyn: begin/ ... /dyn: end/) && !/dyn:/ && print' ../../tests/demo/prod-eval.cc | pygmentize -l c++
The static implementation is templated by a context, i.e., a specific type of labelset and weightset.
!perl -ne '(/static: begin/ ... /static: end/) && !/static:/ && print' ../../tests/demo/prod-eval.cc | pygmentize -l c++
Compile the prod-eval program using vcsn compile
. To know exactly what is going on, pass the option -v
/--verbose
.
!vcsn compile -q ../../tests/demo/prod-eval.cc
Now we generate two input automata for the prod-eval program. Here, we generate them via the command line tool vcsn
(see Executables), with the command standard
, which corresponds to expression.standard
.
!vcsn standard -C 'lal_char(01), z' -Ee '(0+1)*1(<2>0+<2>1)*' -o bin.gv
!vcsn standard -C 'lal_char(01), z' -Ee '(0+1)*0' -o even.gv
The following automaton, bin
, decodes binary into decimal values.
bin = vcsn.automaton(filename='bin.gv')
bin
This automaton, even
, only accepts even numbers.
even = vcsn.automaton(filename='even.gv')
even
Now we run prod-eval
to evaluate words on the synchronized product of bin
and even
.
The result is the value denoted by this binary number if it is even else 0.
The result is displayed twice, once for the dyn implementation and once for static one.
!for i in 0 1 10 1110 101010 101011; \
do \
printf "%6s: " $i; \
vcsn run ../../tests/demo/prod-eval bin.gv even.gv $i; \
done
For the record, this could have been done this way in Python:
for i in [0, 1, 10, 1110, 101010, 101011]:
print('{:6d}: {}'.format(i, (bin & even).evaluate(i)))
compose
¶This example shows how to build a multitape automaton (adding states and transitions), and how to use it.
!pygmentize -l c++ ../../tests/demo/compose.cc