Libraries

Looking to contribute to the Fortress library effort, but don't know where to start? Look no further! Any library coding you do for Fortress will of course be appreciated, but we're particularly keen to solicit contributions in these areas:

Collection Classes

There are two basic versions of the collections hierarchy: an immutable one, which must be implemented by every single Collections type, and a mutable one, which is not supported by every collection type. Note that every collection operation must appear to be atomic from the perspective of client code. For completely immutable collections this will not be an issue. For collections which make use of mutation, either because they provide the mutable collection interface or because they make use of mutation internally, this requires a certain amount of care. It is simplest to declare all the methods on these objects to be atomic. In practice, of course, there are more efficient (but much trickier) ways of writing collection types to provide the appearance of atomicity.

Some collection data structures we would love to see

  • Red-Black trees (important: must include a merge / union operation)
  • Digital tries
  • Hash tables
  • BDDs, as sets, maps, and relations.
  • B-Trees
  • Sets based on sorted lists
  • Any other good set or map data structure. See trunk/ProjectFortress/test_library/Set.fss and trunk/ProjectFortress/test_library/Map.fss for appropriate pure apis; these use weight-balanced trees.
  • Prefix and suffix trees
  • Queues (pure queues supported by PureList.fss and ArrayList.fss)
  • Deques (pure deques supported by PureList.fss and ArrayList.fss)
  • Finger trees (see PureList.fss)
  • Array-based lists (see ArrayList.fss)
  • Priority queues (see Heap.fss, though better implementations welcome)
  • Catenable deques (again see PureList.fss and ArrayList.fss)
  • Pure Skip Lists (see SkipList.fss courtesy of Michael Spiegel)
  • Simple bindings to give a mutable interface to an immutable collection of a particular type, and vice versa (the latter should be easy).
  • Simple binding to turn a map implementation into a bag implementation by storing counts of occurrences of elements.
  • Simple binding to turn a map into a set using void values.
  • Simple binding to turn a map and a set into a relation.

The collection hierarchy (current proposal)

Collection
    Multiset
        List
            Tree
                SortedTree
            SortedList
                SortedTree
                SortedListWithNoDuplicates
            ListWithNoDuplicates
                SortedListWithNoDuplicates
            Array1D
        Set = MultisetWithNoDuplicates
            SetWithComplements
                SetOverFiniteDomain
        SortedMultiset
            SortedList
        Histogram
        Array
            Array1D
            Array2D
            Array3D
            ...
    RelationCollection
        Relation
            Map
            SortedRelation
                SortedMap
        MapCollection
            Map
                SortedMap
                    Array1D
                Array
            SortedMapCollection
                SortedMap
        SortedRelationCollection
            SortedRelation
            SortedMapCollection
    SortedCollection
        SortedList
        SortedRelationCollection

A collection API

We haven't yet fixed a base class for collections, but here is some of the basic functionality a collection might contain. These are all written in method style; since the interpreter doesn't currently support functional methods, operators will be defined to call through to methods. Note that many of these will have default implementations, and usually want to be specialized for arguments of the same collection type rather than for generic collections.

Immutable:

  • Must extend Generator as appropriate, and provide a generate method.
  • A vararg factory, and another factory which takes a generator as an argument. These should probably be overloadings of the same function (a braketing operator where appropriate).
  • An empty collection of appropriate name and type (and eventually with a coercion from Empty). This could be a 0-argument invocation of the factory.
  • opr =, in terms of opr = on elements (all mentions of !"equal!" here mean !"according to opr =!").
  • toString()
  • add(x) to add a single element x and return a new collection; by default it adds to the front of an ordered collection.
  • addEnd(x) to add a single element x and return a new collection; by default it adds to the end of an ordered collection.
  • adjoin(c) returns a new collection containing the elements of this collection and the elements of c; this collection comes first if they are ordered. This corresponds to opr UNION on sets. For parallelism it is important to make this efficient.
  • adjoinDisjoint(c) works as adjoin but requires that c be nonoverlapping with the present collection.
  • remove(x) returns a new collection in which all occurrences of x (in the sense of opr =) have been removed.
  • removeFirst(x) returns a new collection in which one occence of x (the first, if ordered) has been removed.
  • disjoin(c) returns a new collection containing the elements of this collection, with any elements opr = to those in c removed. This is equivalent to set difference on sets. If order matters, it is preserved in the new collection.
  • intersect(c) returns a new collection containing the elements of this collection which also occur in c. This is equivalent to intersection on sets. Again, if order matters it is preserved in the new collection.
  • contains(x) returns true if the collection contains an element opr = to x. This is equivalent to opr ELEM
  • isEmpty() returns true if the collection is empty.
  • overlaps(c) returns true if the collection has any elements in common with c.
  • size() returns the number of elements in the collection.
  • occurrencesOf(x) returns the number of occurrences of element x in the collection.
  • first() returns the first element of the collection (which can be arbitrary if the collection is unordered).
  • firstRest() returns a pair of the first element and the remainder of the collection with the first element removed.
  • last() returns the last element of the collection (again arbitrary if the collection is unordered).
  • initLast() returns a pair of the collection without the last element, and the last element.
  • opr [i:ZZ32] and indices generator for ordered collections (0-indexed access).
  • opr [k:K] and indices generator for maps.
  • indexOf(x), index of first occurrence of x in an ordered collection.
  • values() collection for a map.
  • inverse() convert a map or relation to a relation

For maps and relations, most of the above methods are in terms of keys. Insertion should take a (key,value) pair.

The mutable interface is much the same, but adds "To" to adders, so we get addTo and addToEnd and adjoinTo, and adds "From" to removers, so we get removeFrom and firstFrom. In both cases the return type is () to avoid confusion with the non-mutable functionality.

Numeric libraries and solvers

  • Useful transcendental functions currently lacking: hyperbolics, Gaussian error functions, Bessel functions, etc.
  • Complex numbers
  • Rational numbers
  • Polynomials
  • Quaternions
  • Infinite-precision real arithmetic
  • Implicit numeric differentiation (in which derivatives are computed alongside point data)
  • Root finding of various sorts (Newton's method, binary decomposition, etc.)
  • FFT
  • Cholesky factorization
  • Anything in BLAS, LAPACK, and LINPACK
  • Realistic conjugate gradient implementations with preconditioners
  • Eigenvalue methods of all kinds
  • Linear programming, dense and sparse
  • Integer linear programming

Sparse grid representations

  • Mesh representations and DeLaunay triangulation
  • Multigrid representations, with refinement methods
  • Space-partitioning representations such as quad- and oct-trees

Bindings to existing Java functionality

  • Binary input and output
  • Efficient numeric arrays
  • Bindings to existing libraries such as ATLAS and FFTW (requires JNI + implementation hacking, but well worth it)

Input and Output

  • A printf or Fortran format equivalent
  • Pretty printing library
  • Combinator-based parser library