ADPfusion allows writing dynamic programs for single- and
multi-tape problems. Inputs can be sequences, or sets. New
input types can be defined, without having to rewrite this
library thanks to the open-world assumption of ADPfusion.

The library provides the machinery for Outside and Ensemble
algorithms as well. Ensemble algorithms combine Inside and
Outside calculations.

Starting with version 0.4.1 we support writing multiple
context-free grammars (interleaved syntactic variables). Such
grammars have applications in bioinformatics and linguistics.

The homepage provides a number of tutorial-style examples, with
linear and context-free grammars over sequence and set inputs.

The formal background for generalized algebraic dynamic
progrmaming and ADPfusion is described in a number of papers.
These can be found on the gADP homepage and in the README.

Introduction

From the programmers' viewpoint, ADPfusion behaves very much like the original
ADP implementation http://bibiserv.techfak.uni-bielefeld.de/adp/ developed by
Robert Giegerich and colleagues, though both combinator semantics and
backtracking are different.

The library internals, however, are designed not only to speed up ADP by a
large margin (which this library does), but also to provide further runtime
improvements by allowing the programmer to switch over to other kinds of data
structures with better time and space behaviour. Most importantly, dynamic
programming tables can be strict, removing indirections present in lazy, boxed
tables.

As an example, even rather complex ADP code tends to be completely optimized to
loops that use only unboxed variables (Int# and others, indexIntArray# and
others).

Installation

Implementors Notes (if you want to extend ADPfusion)

The general inlining scheme is: (i) mkStream is {-# INLINE mkStream #-},
inner functions like mk, step, worker functions, and index-modifying
functions get an {-# INLINE [0] funName #-}. Where there is no function to
annotate, use delay_inline.

If you implement a new kind of memoizing table, like the dense Table.Array
ones, you will have to implement mkStream code. When you hand to the left,
the (i,j) indices and modify their extend (by, say, having NonEmpty table
constaints), you have to delay_inline this (until inliner phase 0). Otherwise
you will break fusion for mkStream.

Terminals that capture both, say indexing functions, and data should have no
strictness annotations for the indexing function. This allows the code to be
duplicated, then inlined. This improves performance a lot, because otherwise
a function is created that performs these lookups, which has serious (50%
slower or so) performance implications.