Unifpack consists of several libraries and executables, it is expected
that next releases will have only one library, thus simplifying
Makefile's and usage. The libraries are libmisc , libpack , libudrv
and liblang .
libmisc contains some generic data types, basic I/O and error
handling; libudrv contains the device drivers; libpack contains the
group and polygon classes; finally liblang contains most of the uniflang
code.
When linking a Unifpack application you should specify this libraries
as -llang -ludrv -lpack -lmisc
, please remember that the
order is important on most systems.
The algorithms and data structures in Unifpack use many
common data-types (such as lists and binary trees)
to reduce the size
of the code and to make programming easier some ``generic'' data-types
were implemented
using the the ANSI-C void* type.
None of the Unifpack generic data types makes memory allocation though
this means that users of these classes must make sure that they allocate
and free memory when needed.
When some ordering relation is needed the user is required to provide a function taking as parameters two pointers and returning a number less that zero, zero or greater than zero when the first parameter should be condidered less than, equal to or greater than the second parameter; much in the same way that qsort(3) requires a compare function.
Several classes are provided to calculate groups from presentations, namely Generator, Symbol, SymbolTable, Word, Element and Group; when a presentation is read (from a file or typed by the user) the generators are asigned a number, the name-to-number translation is done by the SymbolTable class, the Generator class should be used to store a generator, as it is currently impleted it is just an integer; the Symbol class represents a generator or its inverse, it is used to label the Cayley graph edges and to build Word's.
A Group is an array of Element's, each element keeps the
list of its neighbours in the Cayley graph, so a Group can be
thought as a Cayley graph too. The way the group is calculated can
be controled supplying some functions.
A FillFunction takes an
Element and (at least) acomplishes step (2.1) on the
figure , experiments sujest that adding just the
neighbours is not very efficient, adding the relations that start
from the element works much better; in any case the function should
not left any double edges or edges with the same color but different
destinations.
A FindPeerFunctions takes an element and searches on the graph for
an element that should be collapsed to it, it performs step (2.2) in
the group algorithm.
A SearchLabelsFunction relabels all the elements of a group,
but respecting user preferences.
Since all the groups in Unifpack have a known presentation each element can be represented by a word on the generators, this word is sometimes called a ``label'' for the element, this label can be set by some algorithm or by the user, the user can set a special flag on the element meaning that the current word is its favourite word for the element, programs should respect user preferences.
Elements can be multiplied, inverted and relabeled, users of the class should not try to create them (they are created by their containing group), write them to or read them from a file (the group does this to). Many of the algorithms require to leave ``marks'' on the elements (such as the ones used by BFS or DFS), Element's provide a mechanism to do this.
To read presentations a simple parser is provided (in contrast to the more general but complex parser of uniflang), the function RestartYYLex let you control the source of the presentation (a FILE* or a string), later the function ReadGroupTree can be used to read a binary tree that contains the presentation, functions are provided to fill a SymbolTable from a tree and to found the list of relations.
Calculating fundamental polygons is the main object of the package, the class Polygon is used to that purpose, usually a fundamental polygons has many parameters reflecting that several Riemann surfaces can have the given group, the class provides methods to change those parameters and to calculate initial values to those parameters; sometimes it may prove useful to use a different set of parameters than the canonical ones, for instance using angles instead of side lengths, the class provides a simple method to do this, each polygon has an associated ``polygon type'' (this is in a form of inheritance), this polygon type provides the methods that do all the computations, the polygon only provides a uniform interface; the class tries to determine the ``best'' class for a given polygon.
uniflang is implemented as a stack machine, much like hoc(1), the parser generates a program (an array of pointer to functions), this program operates a stack of UlValue's to produce the results.
An UlValue is a tagged union that can contain integers, reals, words, generators, group, polygons, strings, etc. Each UlValue also keeps a reference count, the garbage collector deletes UlValue with reference count equal to zero.
More documentation on the language is necessary, but the code is very unstable as to document it now.