diff --git a/Chromosome/ANN.hs b/Chromosome/ANN.hs
new file mode 100644
--- /dev/null
+++ b/Chromosome/ANN.hs
@@ -0,0 +1,142 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Artificial Neural Networks
+module Chromosome.ANN (ANN, Layer, Node,
+                       eval,
+                       config,
+                       uniformCross,
+                       averageCross,
+                       mutateRandomize,
+                       mutateShift,
+                       fitnessMSE,
+                       averageMSE,
+                       correctExamples,
+                       randomANN)
+where
+
+import GA
+import Control.Monad.State
+import List
+import Random
+
+-- |An Artificial Neural Network
+type ANN = [Layer]
+-- |A layer of nodes in an ANN
+type Layer = [Node]
+-- |A node in an ANN. The head of the list is the bias weight. The tail is the weights for the previous layer
+type Node = [Double]
+
+-- User must specify fitness, mutate, and crossover functions
+config = ChromosomeConfig {
+           fitness = undefined,
+           mutate = undefined,
+           cross = undefined
+           }
+
+-- |Returns the number of examples correct within the tolerance. The examples are a list of tuples of (input, output)
+correctExamples :: [([Double],[Double])] -> Double -> ANN -> Double
+correctExamples examples tolerance ann =
+    fromIntegral $ sum $ map (correctExample ann tolerance) examples
+
+correctExample :: ANN -> Double -> ([Double],[Double]) -> Int
+correctExample ann tolerance example =
+    numMatching ((<tolerance) . abs) $
+                rawError ann example
+
+-- |Computes the fitness based on the mean square error for a list of examples
+-- The examples are a list of tuples of (input, output)
+fitnessMSE :: [([Double],[Double])] -> ANN -> Double
+fitnessMSE examples ann = 1.0 / averageMSE ann examples
+
+-- |Computes the mean square error for a list of examples
+-- The examples are a list of tuples of (input, output)
+averageMSE :: ANN -> [([Double],[Double])] -> Double
+averageMSE ann examples =
+    average $ map (mse ann) examples
+
+mse :: ANN -> ([Double],[Double]) -> Double
+mse ann examples =
+    average $ map (^2) $ rawError ann examples
+
+rawError :: ANN -> ([Double], [Double]) -> [Double]
+rawError ann (ins, outs) =
+    zipWith (-) outs $ eval ins ann
+
+-- |Mutates an ANN by randomly settings weights to +/- range
+mutateRandomize :: Double -> Double -> ANN -> (GAState ANN p) ANN
+mutateRandomize rate range ann =
+    mapM (mapM (mapM rnd)) ann
+    where rnd = randWeight False rate range
+
+-- |Mutates an ANN by randomly shifting weights by +/- range
+mutateShift :: Double -> Double -> ANN -> (GAState ANN p) ANN
+mutateShift rate range ann =
+    mapM (mapM (mapM rnd)) ann
+    where rnd = randWeight True rate range
+
+randWeight :: Bool -> Double -> Double -> Double -> (GAState c p) Double
+randWeight shiftp rate range weight = do
+  test <- gaRand (0.0, 1.0)
+  if test > rate
+     then return weight
+     else do
+       delta <- gaRand (-range, range)
+       return $ delta + (if shiftp then weight else 0.0)
+
+-- |Crossover between two ANN's by exchanging weights
+uniformCross :: ANN -> ANN -> (GAState c p) (ANN,ANN)
+uniformCross xsss ysss =
+    zipWithM (zipWithM (zipWithM pickRandom)) xsss ysss >>=
+    return . unzip . map unzip . map (map unzip)
+
+-- |Crossover between two ANN's by averaging weights
+averageCross :: ANN -> ANN -> (GAState c p) (ANN,ANN)
+averageCross n1 n2 =
+    let retval = zipWith (zipWith (zipWith avg)) n1 n2
+    in return (retval, retval)
+
+pickRandom :: a -> a -> (GAState c p) (a,a)
+pickRandom x y = do
+  test <- gaRand (False, True)
+  if test then return (x,y) else return (y,x)
+
+-- |Evaluates an ANN with a given input
+eval :: [Double] -> ANN -> [Double]
+eval input [] = input
+eval input (x:xs) =
+    eval (evalLayer input x) xs
+
+evalLayer :: [Double] -> Layer -> [Double]
+evalLayer inputs =
+    map (evalNode inputs)
+
+evalNode :: [Double] -> Node -> Double
+evalNode inputs (bias : weights) =
+    sigmoid $ bias + dotProduct inputs weights
+
+-- |Generates a random ANN with a given number of input nodes, a list of number of hidden nodes per layer, and the weight range
+randomANN :: Int -> [Int] -> Double -> (GAState c p) ANN
+randomANN _ [] _ = return []
+randomANN i (l:ls) r = do
+  x <- randomLayer i l r
+  xs <- randomANN l ls r
+  return $ x : xs
+
+randomLayer :: Int -> Int -> Double -> (GAState c p) Layer
+randomLayer i o range = replicateM o $ randomNode i range
+
+randomNode :: Int -> Double -> (GAState c p) Node
+randomNode i range = replicateM (i+1) $ gaRand (-range,range)
+
+-- Low level utilities
+sigmoid :: Double -> Double
+sigmoid x = 1.0 / (1.0 + exp (-x))
+
+dotProduct :: [Double] -> [Double] -> Double
+dotProduct u v = sum $ zipWith (*) u v
+
+avg x y = (x + y) / 2.0
+average xs = sum xs / genericLength xs
+
+numMatching p =
+    foldl (\acc x -> if p x then acc + 1 else acc) 0
diff --git a/Chromosome/Bits.hs b/Chromosome/Bits.hs
new file mode 100644
--- /dev/null
+++ b/Chromosome/Bits.hs
@@ -0,0 +1,53 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Chromosomes represented as a bit field
+module Chromosome.Bits (mutateBits,
+                        bits2int,
+                        randomBits,
+                        pointCross,
+                        config)
+where
+
+import List
+import Random
+import Control.Monad.State
+import GA
+
+-- |The config for a chromosome of a list of bits. User must defined fitness and mutate.
+config :: ChromosomeConfig [a] p
+config = ChromosomeConfig {
+           fitness = undefined,
+           mutate = undefined,
+           cross = pointCross
+}
+
+-- |Single point cross at a random location
+pointCross :: [a] -> [a] -> (GAState c p) ([a],[a])
+pointCross xs ys = do
+  let len = length xs
+  point <- gaRand (0, len)
+  let (left1, right1) = splitAt point xs
+      (left2, right2) = splitAt point ys
+      in return $ (left1 ++ right2, left2 ++ right1)
+
+-- |Generates i random bits
+randomBits :: Int -> (GAState c p) [Bool]
+randomBits i = replicateM i (gaRand (True, False))
+
+-- |Randomly flips fits with a specified probability
+mutateBits :: Double -> [Bool] -> (GAState c p) [Bool]
+mutateBits mutationRate xs =
+    mapM (mutateBit mutationRate) xs
+
+
+mutateBit r b = do
+  test <- gaRand (0.0, 1.0)
+  if test < r
+     then return $ not b
+     else return b
+
+-- |Converts a list of Bool's to it's integer representation
+bits2int :: [Bool] -> Int
+bits2int bs =
+    sum [ x | (x, b) <- zip _2pwrs bs, b ]
+    where _2pwrs = 1 : map (*2) _2pwrs
diff --git a/Chromosome/GP.hs b/Chromosome/GP.hs
new file mode 100644
--- /dev/null
+++ b/Chromosome/GP.hs
@@ -0,0 +1,88 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Genetic Programming as strictly-evaluated s-expressions
+module Chromosome.GP (Op (..),
+                      Node (..),
+                      mseFitness,
+                      mutate,
+                      eval,
+                      random,
+                      config)
+where
+
+import Array
+import qualified GA
+import Control.Monad.State
+import List
+
+-- The config for the GP chromosome model. mutate, cross, and fitness must be defined.
+config = GA.ChromosomeConfig {
+           GA.mutate = undefined,
+           GA.cross = undefined,
+           GA.fitness = undefined
+           }
+
+-- |An operator in the syntax tree of the GP
+data Op a s = Op {
+      -- |The function for evaluating this node
+      callback :: ([a] -> State s a),
+      -- |The number of children of this node
+      arity :: Int,
+      -- |The name of the node when shown
+      name :: String
+      }
+
+instance Show (Op a s) where
+    show = name
+
+-- |A node in the syntax tree of the GP
+data Node a s = Node (Op a s) [Node a s]
+
+instance Show (Node a s) where
+    show (Node o children) =
+        if arity o == 0
+           then show o
+           else "(" ++ (unwords $ show o : map show children) ++ ")"
+
+-- |Calculates fitness based on the mean square error across a list of examples
+-- The examples are a list of tuples of (inputs state, correct output)
+mseFitness :: (Fractional a) => [(s, a)] -> Node a s -> a
+mseFitness examples node =
+    1.0 / (mse node examples + 1.0)
+
+mse :: (Fractional a) => Node a s -> [(s, a)] -> a
+mse node examples =
+    average $ map (^2) $ map (\(i,o) -> delta node i o) examples
+
+delta node state output =
+    output - (evalState (eval node) state)
+
+-- |Statefully evaluates a given GP
+eval :: Node a s -> State s a
+eval (Node (Op f _ _) ns) =
+    mapM eval ns >>= f
+
+-- |Mutates a GP by replacing nodes with random GP's
+mutate 0 ops rate tree = error "Attempt to mutate with depth of 0"
+mutate d ops rate tree@(Node op children) = do
+  test <- GA.gaRand (0.0, 1.0)
+  if test >= rate  -- No mutation
+     then do newChildren <- mapM (mutate (d-1) ops rate) children
+             return $ Node op newChildren
+     else random d ops
+
+-- |Generates a random GP with a given depth limit
+random 0 ops = error "Attempt to create depth 0 tree"
+random 1 ops = do
+  op <- randomOp $ filter ((==0) . arity) ops
+  return $ Node op []
+random d ops = do
+  op <- randomOp ops
+  children <- replicateM (arity op) $ random (d-1) ops
+  return $ Node op children
+
+randomOp ops =
+    GA.gaRand (0,length ops - 1) >>=
+    return . (ops !!)
+
+average xs = sum xs / genericLength xs
diff --git a/GA.hs b/GA.hs
new file mode 100644
--- /dev/null
+++ b/GA.hs
@@ -0,0 +1,142 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Genetic Algorithms
+module GA (Config (..),
+           PopulationConfig (..),
+           ChromosomeConfig (..),
+           defaultConfig,
+           GAState,
+           bestChromosome,
+           gaRand,
+           run,
+           rouletteM,
+           mutateM,
+           crossM,
+           tournamentM,
+           isDone)
+where
+
+import Maybe
+import Random
+import Control.Monad.State
+
+type GAState c p = State (Config c p)
+
+data Config c p = Config {
+      -- |The config for the chromosome model
+      cConfig :: ChromosomeConfig c p,
+      -- |The config for the population model
+      pConfig :: PopulationConfig c p,
+      -- |The function that transforms a population into the next generation
+      newPopulation :: p -> (GAState c p) p,
+      -- |The fitness at which to stop the GA
+      maxFitness :: Maybe Double,
+      -- |The generation at which to stop the GA
+      maxGeneration :: Maybe Int,
+      -- |The number of generations elapsed. defaultConfig sets this to 0
+      currentGeneration :: Int,
+      -- |The random number generator
+      gen :: StdGen
+      }
+
+data ChromosomeConfig c p = ChromosomeConfig {
+      -- |The fitness function for the chromosome model
+      fitness :: c -> Double,
+      -- |The mutation operator for the chromosome model
+      mutate :: c -> (GAState c p) c,
+      -- |The crossover operator for the chromosome model
+      cross :: c -> c -> (GAState c p) (c,c)
+      }
+
+data PopulationConfig c p = PopulationConfig {
+      bestChromosomePop :: p -> (GAState c p) c,
+      roulettePop :: p -> (GAState c p) p,
+      tournamentPop :: p -> (GAState c p) p,
+      applyCrossoverPop :: p -> (GAState c p) p,
+      applyMutationPop :: p -> (GAState c p) p
+      }
+-- |defaultConfig acts as a blank slate for genetic algorithms.
+-- cConfig, pConfig, gen, and maxFitness or maxGeneration must be defined
+defaultConfig :: Config c p
+defaultConfig = Config {
+                  cConfig = undefined,
+                  pConfig = undefined,
+                  newPopulation = undefined,
+                  maxFitness = Nothing,
+                  maxGeneration = Nothing,
+                  currentGeneration = 0,
+                  gen = undefined
+                  }
+
+-- |Wrapper function which returns the best chromosome of a population
+bestChromosome :: p -> (GAState c p) c
+bestChromosome pop = do
+  config <- get
+  bestChromosomePop (pConfig config) pop
+
+-- |Wrapper function which returns the highest-fitness member of a population
+highestFitness :: p -> (GAState c p) Double
+highestFitness pop = do
+  fitFunc <- (fitness . cConfig) `liftM` get
+  best <- bestChromosome pop
+  return $ fitFunc best
+
+-- |A wrapper function for use in newPopulation for roulette selection
+rouletteM :: p -> (GAState c p) p
+rouletteM pop =
+  (roulettePop . pConfig) `liftM` get >>= ($pop)
+
+-- |A wrapper function for use in newPopulation for tournament selection
+tournamentM :: p -> (GAState c p) p
+tournamentM pop =
+    (tournamentPop . pConfig) `liftM` get >>= ($pop)
+
+-- |A wrapper function for use in newPopulation for mutating the population
+mutateM :: p -> (GAState c p) p
+mutateM pop = do
+  (applyMutationPop . pConfig) `liftM` get >>= ($pop)
+
+-- |A wrapper function for use in newPopulation for applying crossover to the population
+crossM :: p -> (GAState c p) p
+crossM pop =
+    (applyCrossoverPop . pConfig) `liftM` get >>= ($pop)
+
+newPopulationM :: p -> (GAState c p) p
+newPopulationM pop =
+    incGA >> newPopulation `liftM` get >>= ($pop)
+
+incGA :: (GAState c p) ()
+incGA = modify (\c@Config { currentGeneration = g} ->
+                    c { currentGeneration = g + 1})
+
+untilM :: (Monad m) => (a -> m Bool) -> (a -> m a) -> a -> m a
+untilM p f x = do
+  test <- p x
+  if test 
+     then return x
+     else f x >>= untilM p f
+
+-- |Runs the specified GA config until the termination condition is reached
+run :: p -> (GAState c p) p
+run = untilM isDone newPopulationM
+
+-- |Returns true if the given population satisfies the termination condition for the GA config
+isDone :: p -> (GAState c p) Bool
+isDone population = do
+  c <- get
+  f <- highestFitness population
+  let generationsDone =
+          maybe False (<(currentGeneration c)) $ maxGeneration c
+  let fitnessDone =
+          maybe False (>f) $ maxFitness c
+  return $ generationsDone || fitnessDone
+
+-- |Generates a random number which updating the random number generator for the config
+gaRand :: (Random a) =>
+          (a,a) -> (GAState c p) a
+gaRand range = do
+  config <- get
+  let g = gen config
+  let (x, g') = randomR range g
+  put $ config { gen = g' }
+  return x
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,1 @@
+Copyleft 2008. All rights reversed.
diff --git a/Population/Array.hs b/Population/Array.hs
new file mode 100644
--- /dev/null
+++ b/Population/Array.hs
@@ -0,0 +1,101 @@
+
+-- | Populations represented as a diff array of chromosomes
+module Population.Array (config, fromList)
+where
+
+import GA
+
+import Data.Array.Diff
+import Control.Monad
+import Control.Monad.State
+import List
+
+-- |The type used to represent population arrays; is a diff array.
+type PArray c = DiffArray Int c
+
+-- |Population config for arrays
+config :: PopulationConfig c (PArray c)
+config = PopulationConfig {
+           bestChromosomePop = bestChromosomeArray,
+           roulettePop = rouletteArray,
+           tournamentPop = tournamentArray,
+           applyCrossoverPop = crossoverArray,
+           applyMutationPop = mutateArray
+}
+
+--yipee
+tournamentArray :: PArray c -> (GAState c p) (PArray c)
+tournamentArray arr = do
+  f <- (fitness . cConfig) `liftM` get
+  let augument c = (c, f c)
+  let augArr = amap augument arr
+  aforM arr $ \_ -> do
+    index1 <- gaRand $ bounds arr
+    index2 <- gaRand $ bounds arr
+    let chrom1 = augArr ! index1
+    let chrom2 = augArr ! index2
+    if snd chrom1 > snd chrom2
+       then return $ fst chrom1
+       else return $ fst chrom2
+
+mutateArray :: PArray c -> (GAState c (PArray c)) (PArray c)
+mutateArray arr =
+    (mutate . cConfig) `liftM` get >>= flip amapM arr
+
+crossoverArray arr = do
+  c <- (cross . cConfig) `liftM` get
+  crossoverArray' c arr $ fst $ bounds arr
+
+crossoverArray' cross arr index =
+    let lastIndex = snd $ bounds arr in
+    if index > lastIndex
+       then return arr
+       else
+           let p1 = arr ! index
+               p2 = arr ! (index + 1)
+           in do (c1, c2) <- cross p1 p2
+                 let newArr = arr // [(index, c1), (index + 1, c2)]
+                 crossoverArray' cross newArr (index + 2)
+
+bestChromosomeArray :: PArray c -> (GAState c p) c
+bestChromosomeArray arr = do
+    f <- (fitness . cConfig) `liftM` get
+    let cmp x y | f x > f y = x
+                | otherwise = y
+    return $ afoldl1 cmp arr
+
+
+rouletteArray :: PArray c -> (GAState c p) (PArray c)
+rouletteArray arr = do
+  f <- (fitness . cConfig) `liftM` get
+  let totalFitness = (afoldl (\fit c -> fit + f c) 0.0 arr) :: Double
+  let augument chrom = (chrom, (f chrom) / totalFitness)
+  let augArr = amap augument arr
+  aforM arr $ \_ ->
+      selectDistribution augArr 0.0 $ fst $ bounds arr
+
+selectDistribution :: PArray (c, Double) -> Double -> Int -> (GAState c p) c
+selectDistribution arr acc index =
+    let lastIndex = snd $ bounds arr in
+    if index == lastIndex
+       then return $ fst $ arr ! lastIndex
+       else do
+         let (chrom, fit) = arr ! index
+         test <- gaRand (0.0, 1.0)
+         if test < fit / (1 - acc)
+            then return chrom
+            else selectDistribution arr (fit + acc) (index + 1)
+
+-- |Converts a list to an array
+fromList xs = listArray (0, length xs - 1) xs
+
+amapM p arr =
+    listArray (bounds arr) `liftM` mapM p (elems arr)
+
+aforM arr p = amapM p arr
+ 
+afoldl p seed arr =
+    foldl p seed $ elems arr
+
+afoldl1 p arr =
+    foldl1 p $ elems arr
diff --git a/Population/List.hs b/Population/List.hs
new file mode 100644
--- /dev/null
+++ b/Population/List.hs
@@ -0,0 +1,81 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Populations represented as a list of chromosomes
+-- Arrays are recommended instead for performance reasons.
+module Population.List (config)
+where
+
+import GA
+
+import Control.Monad
+import Control.Monad.State
+import Random
+import List
+
+-- |Config for use of lists as the population model. Lists are deprecated in favor of arrays.
+config :: PopulationConfig c [c]
+config = PopulationConfig {
+           bestChromosomePop = bestChromosomeList,
+           roulettePop = rouletteList,
+           tournamentPop = tournamentList,
+           applyCrossoverPop = crossoverList,
+           applyMutationPop = mutateList
+           }
+
+-- Warning: shit performance for tournamentList :/ O(n^2) afaict
+-- Moral o Story: Lists suck, but arrays are fugly ;_;
+tournamentList :: [c] -> (GAState c [c]) [c]
+tournamentList xs = do
+  f <- (fitness . cConfig) `liftM` get
+  let len = length xs
+  let augChroms = map (\c -> (c, f c)) xs
+  forM xs $ \_ -> do
+    index1 <- gaRand (0, len - 1)
+    index2 <- gaRand (0, len - 1)
+    let test1 = augChroms !! index1
+    let test2 = augChroms !! index2
+    if snd test1 > snd test2
+       then return $ fst test1
+       else return $ fst test2
+
+crossoverList :: [c] -> (GAState c [c]) [c]
+crossoverList [] = return []
+crossoverList [x] = return [x]
+crossoverList (x:y:xs) = do
+  c <- (cross . cConfig) `liftM` get
+  (offspring1,offspring2) <- c x y
+  rest <- crossoverList xs
+  return $ offspring1 : offspring2 : rest
+
+mutateList :: [c] -> (GAState c [c]) [c]
+mutateList cs =
+    (mutate . cConfig) `liftM` get >>= forM cs
+
+rouletteList :: [c] -> (GAState c [c]) [c]
+rouletteList cs = do
+  f <- (fitness . cConfig) `liftM` get
+  let fs = map f cs
+  let total = sum fs
+  let probs = map (/total) fs
+  let augumentedChromosomes = zip cs probs
+  forM cs $
+           \_ -> selectDistribution augumentedChromosomes
+
+
+bestChromosomeList :: [c] -> (GAState c [c]) c
+bestChromosomeList cs = do
+  f <- (fitness . cConfig) `liftM` get
+  let compareChromosomes x y =
+          compare (f x) (f y)
+  return $ maximumBy compareChromosomes cs
+
+
+selectDistribution :: [(a, Double)] -> (GAState c p) a
+selectDistribution xs =
+    select 0.0 xs
+    where select _ ((a,p):[]) = return a
+          select acc ((a,p):xs) = do
+            test <- gaRand (0,1.0)
+            if test < p / (1 - acc)
+               then return a
+               else select (p + acc) xs
diff --git a/README b/README
new file mode 100644
--- /dev/null
+++ b/README
@@ -0,0 +1,13 @@
+See examples/. It should get you started.
+The source code is haddock-ready. Run:
+
+runhaskell Setup.hs configure
+runhaskell Setup.hs haddock
+
+Note you need haddock version 2.
+
+Please send comments, patches, etc to:
+
+ellisk@catlin.edu
+
+Thank you so much for using hgalib.
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/_darcs/format b/_darcs/format
new file mode 100644
--- /dev/null
+++ b/_darcs/format
@@ -0,0 +1,1 @@
+darcs-1.0
diff --git a/_darcs/inventory b/_darcs/inventory
new file mode 100644
--- /dev/null
+++ b/_darcs/inventory
@@ -0,0 +1,11 @@
+
+[Genesis
+ellisk@catlin.edu**20080819224536] 
+[examples
+ellisk@catlin.edu**20080820194518] 
+[0.1 final
+ellisk@catlin.edu**20080826060739
+ Got everything ready for the 0.1 release
+] 
+[Improved GP example
+ellisk@catlin.edu**20080826153840] 
diff --git a/_darcs/patches/20080819224536-2e7c7-16fca1334987407b252c303d6d18be29e7f74594.gz b/_darcs/patches/20080819224536-2e7c7-16fca1334987407b252c303d6d18be29e7f74594.gz
new file mode 100644
Binary files /dev/null and b/_darcs/patches/20080819224536-2e7c7-16fca1334987407b252c303d6d18be29e7f74594.gz differ
diff --git a/_darcs/patches/20080820194518-2e7c7-2c2b981ba8bd66edf4f1853dcaf929c22d7de013.gz b/_darcs/patches/20080820194518-2e7c7-2c2b981ba8bd66edf4f1853dcaf929c22d7de013.gz
new file mode 100644
Binary files /dev/null and b/_darcs/patches/20080820194518-2e7c7-2c2b981ba8bd66edf4f1853dcaf929c22d7de013.gz differ
diff --git a/_darcs/patches/20080826060739-2e7c7-cea315b48cddfa35ef09426cc5ecc4b4d1ac8619.gz b/_darcs/patches/20080826060739-2e7c7-cea315b48cddfa35ef09426cc5ecc4b4d1ac8619.gz
new file mode 100644
Binary files /dev/null and b/_darcs/patches/20080826060739-2e7c7-cea315b48cddfa35ef09426cc5ecc4b4d1ac8619.gz differ
diff --git a/_darcs/patches/20080826153840-2e7c7-bfffecbf6d5c3ee694f167da4c0eae6274482c55.gz b/_darcs/patches/20080826153840-2e7c7-bfffecbf6d5c3ee694f167da4c0eae6274482c55.gz
new file mode 100644
Binary files /dev/null and b/_darcs/patches/20080826153840-2e7c7-bfffecbf6d5c3ee694f167da4c0eae6274482c55.gz differ
diff --git a/_darcs/patches/pending b/_darcs/patches/pending
new file mode 100644
--- /dev/null
+++ b/_darcs/patches/pending
@@ -0,0 +1,2 @@
+{
+}
diff --git a/_darcs/patches/pending.tentative b/_darcs/patches/pending.tentative
new file mode 100644
--- /dev/null
+++ b/_darcs/patches/pending.tentative
@@ -0,0 +1,2 @@
+{
+}
diff --git a/_darcs/prefs/author b/_darcs/prefs/author
new file mode 100644
--- /dev/null
+++ b/_darcs/prefs/author
@@ -0,0 +1,1 @@
+ellisk@catlin.edu
diff --git a/_darcs/prefs/binaries b/_darcs/prefs/binaries
new file mode 100644
--- /dev/null
+++ b/_darcs/prefs/binaries
@@ -0,0 +1,59 @@
+# Binary file regexps:
+\.png$
+\.PNG$
+\.gz$
+\.GZ$
+\.pdf$
+\.PDF$
+\.jpg$
+\.JPG$
+\.jpeg$
+\.JPEG$
+\.gif$
+\.GIF$
+\.tif$
+\.TIF$
+\.tiff$
+\.TIFF$
+\.pnm$
+\.PNM$
+\.pbm$
+\.PBM$
+\.pgm$
+\.PGM$
+\.ppm$
+\.PPM$
+\.bmp$
+\.BMP$
+\.mng$
+\.MNG$
+\.tar$
+\.TAR$
+\.bz2$
+\.BZ2$
+\.z$
+\.Z$
+\.zip$
+\.ZIP$
+\.jar$
+\.JAR$
+\.so$
+\.SO$
+\.a$
+\.A$
+\.tgz$
+\.TGZ$
+\.mpg$
+\.MPG$
+\.mpeg$
+\.MPEG$
+\.iso$
+\.ISO$
+\.exe$
+\.EXE$
+\.doc$
+\.DOC$
+\.elc$
+\.ELC$
+\.pyc$
+\.PYC$
diff --git a/_darcs/prefs/boring b/_darcs/prefs/boring
new file mode 100644
--- /dev/null
+++ b/_darcs/prefs/boring
@@ -0,0 +1,56 @@
+# Boring file regexps:
+\.hi$
+\.hi-boot$
+\.o-boot$
+\.o$
+\.o\.cmd$
+# *.ko files aren't boring by default because they might
+# be Korean translations rather than kernel modules.
+# \.ko$
+\.ko\.cmd$
+\.mod\.c$
+(^|/)\.tmp_versions($|/)
+(^|/)CVS($|/)
+\.cvsignore$
+^\.#
+(^|/)RCS($|/)
+,v$
+(^|/)\.svn($|/)
+(^|/)\.hg($|/)
+\.bzr$
+(^|/)SCCS($|/)
+~$
+(^|/)_darcs($|/)
+\.bak$
+\.BAK$
+\.orig$
+\.rej$
+(^|/)vssver\.scc$
+\.swp$
+(^|/)MT($|/)
+(^|/)\{arch\}($|/)
+(^|/).arch-ids($|/)
+(^|/),
+\.prof$
+(^|/)\.DS_Store$
+(^|/)BitKeeper($|/)
+(^|/)ChangeSet($|/)
+\.py[co]$
+\.elc$
+\.class$
+\#
+(^|/)Thumbs\.db$
+(^|/)autom4te\.cache($|/)
+(^|/)config\.(log|status)$
+^\.depend$
+(^|/)(tags|TAGS)$
+#(^|/)\.[^/]
+(^|/|\.)core$
+\.(obj|a|exe|so|lo|la)$
+^\.darcs-temp-mail$
+-darcs-backup[[:digit:]]+$
+\.(fas|fasl|sparcf|x86f)$
+\.part$
+(^|/)\.waf-[[:digit:].]+-[[:digit:]]+($|/)
+(^|/)\.lock-wscript$
+^\.darcs-temp-mail$
diff --git a/_darcs/prefs/motd b/_darcs/prefs/motd
new file mode 100644
--- /dev/null
+++ b/_darcs/prefs/motd
diff --git a/_darcs/pristine/Chromosome/ANN.hs b/_darcs/pristine/Chromosome/ANN.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/Chromosome/ANN.hs
@@ -0,0 +1,142 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Artificial Neural Networks
+module Chromosome.ANN (ANN, Layer, Node,
+                       eval,
+                       config,
+                       uniformCross,
+                       averageCross,
+                       mutateRandomize,
+                       mutateShift,
+                       fitnessMSE,
+                       averageMSE,
+                       correctExamples,
+                       randomANN)
+where
+
+import GA
+import Control.Monad.State
+import List
+import Random
+
+-- |An Artificial Neural Network
+type ANN = [Layer]
+-- |A layer of nodes in an ANN
+type Layer = [Node]
+-- |A node in an ANN. The head of the list is the bias weight. The tail is the weights for the previous layer
+type Node = [Double]
+
+-- User must specify fitness, mutate, and crossover functions
+config = ChromosomeConfig {
+           fitness = undefined,
+           mutate = undefined,
+           cross = undefined
+           }
+
+-- |Returns the number of examples correct within the tolerance. The examples are a list of tuples of (input, output)
+correctExamples :: [([Double],[Double])] -> Double -> ANN -> Double
+correctExamples examples tolerance ann =
+    fromIntegral $ sum $ map (correctExample ann tolerance) examples
+
+correctExample :: ANN -> Double -> ([Double],[Double]) -> Int
+correctExample ann tolerance example =
+    numMatching ((<tolerance) . abs) $
+                rawError ann example
+
+-- |Computes the fitness based on the mean square error for a list of examples
+-- The examples are a list of tuples of (input, output)
+fitnessMSE :: [([Double],[Double])] -> ANN -> Double
+fitnessMSE examples ann = 1.0 / averageMSE ann examples
+
+-- |Computes the mean square error for a list of examples
+-- The examples are a list of tuples of (input, output)
+averageMSE :: ANN -> [([Double],[Double])] -> Double
+averageMSE ann examples =
+    average $ map (mse ann) examples
+
+mse :: ANN -> ([Double],[Double]) -> Double
+mse ann examples =
+    average $ map (^2) $ rawError ann examples
+
+rawError :: ANN -> ([Double], [Double]) -> [Double]
+rawError ann (ins, outs) =
+    zipWith (-) outs $ eval ins ann
+
+-- |Mutates an ANN by randomly settings weights to +/- range
+mutateRandomize :: Double -> Double -> ANN -> (GAState ANN p) ANN
+mutateRandomize rate range ann =
+    mapM (mapM (mapM rnd)) ann
+    where rnd = randWeight False rate range
+
+-- |Mutates an ANN by randomly shifting weights by +/- range
+mutateShift :: Double -> Double -> ANN -> (GAState ANN p) ANN
+mutateShift rate range ann =
+    mapM (mapM (mapM rnd)) ann
+    where rnd = randWeight True rate range
+
+randWeight :: Bool -> Double -> Double -> Double -> (GAState c p) Double
+randWeight shiftp rate range weight = do
+  test <- gaRand (0.0, 1.0)
+  if test > rate
+     then return weight
+     else do
+       delta <- gaRand (-range, range)
+       return $ delta + (if shiftp then weight else 0.0)
+
+-- |Crossover between two ANN's by exchanging weights
+uniformCross :: ANN -> ANN -> (GAState c p) (ANN,ANN)
+uniformCross xsss ysss =
+    zipWithM (zipWithM (zipWithM pickRandom)) xsss ysss >>=
+    return . unzip . map unzip . map (map unzip)
+
+-- |Crossover between two ANN's by averaging weights
+averageCross :: ANN -> ANN -> (GAState c p) (ANN,ANN)
+averageCross n1 n2 =
+    let retval = zipWith (zipWith (zipWith avg)) n1 n2
+    in return (retval, retval)
+
+pickRandom :: a -> a -> (GAState c p) (a,a)
+pickRandom x y = do
+  test <- gaRand (False, True)
+  if test then return (x,y) else return (y,x)
+
+-- |Evaluates an ANN with a given input
+eval :: [Double] -> ANN -> [Double]
+eval input [] = input
+eval input (x:xs) =
+    eval (evalLayer input x) xs
+
+evalLayer :: [Double] -> Layer -> [Double]
+evalLayer inputs =
+    map (evalNode inputs)
+
+evalNode :: [Double] -> Node -> Double
+evalNode inputs (bias : weights) =
+    sigmoid $ bias + dotProduct inputs weights
+
+-- |Generates a random ANN with a given number of input nodes, a list of number of hidden nodes per layer, and the weight range
+randomANN :: Int -> [Int] -> Double -> (GAState c p) ANN
+randomANN _ [] _ = return []
+randomANN i (l:ls) r = do
+  x <- randomLayer i l r
+  xs <- randomANN l ls r
+  return $ x : xs
+
+randomLayer :: Int -> Int -> Double -> (GAState c p) Layer
+randomLayer i o range = replicateM o $ randomNode i range
+
+randomNode :: Int -> Double -> (GAState c p) Node
+randomNode i range = replicateM (i+1) $ gaRand (-range,range)
+
+-- Low level utilities
+sigmoid :: Double -> Double
+sigmoid x = 1.0 / (1.0 + exp (-x))
+
+dotProduct :: [Double] -> [Double] -> Double
+dotProduct u v = sum $ zipWith (*) u v
+
+avg x y = (x + y) / 2.0
+average xs = sum xs / genericLength xs
+
+numMatching p =
+    foldl (\acc x -> if p x then acc + 1 else acc) 0
diff --git a/_darcs/pristine/Chromosome/Bits.hs b/_darcs/pristine/Chromosome/Bits.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/Chromosome/Bits.hs
@@ -0,0 +1,53 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Chromosomes represented as a bit field
+module Chromosome.Bits (mutateBits,
+                        bits2int,
+                        randomBits,
+                        pointCross,
+                        config)
+where
+
+import List
+import Random
+import Control.Monad.State
+import GA
+
+-- |The config for a chromosome of a list of bits. User must defined fitness and mutate.
+config :: ChromosomeConfig [a] p
+config = ChromosomeConfig {
+           fitness = undefined,
+           mutate = undefined,
+           cross = pointCross
+}
+
+-- |Single point cross at a random location
+pointCross :: [a] -> [a] -> (GAState c p) ([a],[a])
+pointCross xs ys = do
+  let len = length xs
+  point <- gaRand (0, len)
+  let (left1, right1) = splitAt point xs
+      (left2, right2) = splitAt point ys
+      in return $ (left1 ++ right2, left2 ++ right1)
+
+-- |Generates i random bits
+randomBits :: Int -> (GAState c p) [Bool]
+randomBits i = replicateM i (gaRand (True, False))
+
+-- |Randomly flips fits with a specified probability
+mutateBits :: Double -> [Bool] -> (GAState c p) [Bool]
+mutateBits mutationRate xs =
+    mapM (mutateBit mutationRate) xs
+
+
+mutateBit r b = do
+  test <- gaRand (0.0, 1.0)
+  if test < r
+     then return $ not b
+     else return b
+
+-- |Converts a list of Bool's to it's integer representation
+bits2int :: [Bool] -> Int
+bits2int bs =
+    sum [ x | (x, b) <- zip _2pwrs bs, b ]
+    where _2pwrs = 1 : map (*2) _2pwrs
diff --git a/_darcs/pristine/Chromosome/GP.hs b/_darcs/pristine/Chromosome/GP.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/Chromosome/GP.hs
@@ -0,0 +1,88 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Genetic Programming as strictly-evaluated s-expressions
+module Chromosome.GP (Op (..),
+                      Node (..),
+                      mseFitness,
+                      mutate,
+                      eval,
+                      random,
+                      config)
+where
+
+import Array
+import qualified GA
+import Control.Monad.State
+import List
+
+-- The config for the GP chromosome model. mutate, cross, and fitness must be defined.
+config = GA.ChromosomeConfig {
+           GA.mutate = undefined,
+           GA.cross = undefined,
+           GA.fitness = undefined
+           }
+
+-- |An operator in the syntax tree of the GP
+data Op a s = Op {
+      -- |The function for evaluating this node
+      callback :: ([a] -> State s a),
+      -- |The number of children of this node
+      arity :: Int,
+      -- |The name of the node when shown
+      name :: String
+      }
+
+instance Show (Op a s) where
+    show = name
+
+-- |A node in the syntax tree of the GP
+data Node a s = Node (Op a s) [Node a s]
+
+instance Show (Node a s) where
+    show (Node o children) =
+        if arity o == 0
+           then show o
+           else "(" ++ (unwords $ show o : map show children) ++ ")"
+
+-- |Calculates fitness based on the mean square error across a list of examples
+-- The examples are a list of tuples of (inputs state, correct output)
+mseFitness :: (Fractional a) => [(s, a)] -> Node a s -> a
+mseFitness examples node =
+    1.0 / (mse node examples + 1.0)
+
+mse :: (Fractional a) => Node a s -> [(s, a)] -> a
+mse node examples =
+    average $ map (^2) $ map (\(i,o) -> delta node i o) examples
+
+delta node state output =
+    output - (evalState (eval node) state)
+
+-- |Statefully evaluates a given GP
+eval :: Node a s -> State s a
+eval (Node (Op f _ _) ns) =
+    mapM eval ns >>= f
+
+-- |Mutates a GP by replacing nodes with random GP's
+mutate 0 ops rate tree = error "Attempt to mutate with depth of 0"
+mutate d ops rate tree@(Node op children) = do
+  test <- GA.gaRand (0.0, 1.0)
+  if test >= rate  -- No mutation
+     then do newChildren <- mapM (mutate (d-1) ops rate) children
+             return $ Node op newChildren
+     else random d ops
+
+-- |Generates a random GP with a given depth limit
+random 0 ops = error "Attempt to create depth 0 tree"
+random 1 ops = do
+  op <- randomOp $ filter ((==0) . arity) ops
+  return $ Node op []
+random d ops = do
+  op <- randomOp ops
+  children <- replicateM (arity op) $ random (d-1) ops
+  return $ Node op children
+
+randomOp ops =
+    GA.gaRand (0,length ops - 1) >>=
+    return . (ops !!)
+
+average xs = sum xs / genericLength xs
diff --git a/_darcs/pristine/GA.hs b/_darcs/pristine/GA.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/GA.hs
@@ -0,0 +1,142 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Genetic Algorithms
+module GA (Config (..),
+           PopulationConfig (..),
+           ChromosomeConfig (..),
+           defaultConfig,
+           GAState,
+           bestChromosome,
+           gaRand,
+           run,
+           rouletteM,
+           mutateM,
+           crossM,
+           tournamentM,
+           isDone)
+where
+
+import Maybe
+import Random
+import Control.Monad.State
+
+type GAState c p = State (Config c p)
+
+data Config c p = Config {
+      -- |The config for the chromosome model
+      cConfig :: ChromosomeConfig c p,
+      -- |The config for the population model
+      pConfig :: PopulationConfig c p,
+      -- |The function that transforms a population into the next generation
+      newPopulation :: p -> (GAState c p) p,
+      -- |The fitness at which to stop the GA
+      maxFitness :: Maybe Double,
+      -- |The generation at which to stop the GA
+      maxGeneration :: Maybe Int,
+      -- |The number of generations elapsed. defaultConfig sets this to 0
+      currentGeneration :: Int,
+      -- |The random number generator
+      gen :: StdGen
+      }
+
+data ChromosomeConfig c p = ChromosomeConfig {
+      -- |The fitness function for the chromosome model
+      fitness :: c -> Double,
+      -- |The mutation operator for the chromosome model
+      mutate :: c -> (GAState c p) c,
+      -- |The crossover operator for the chromosome model
+      cross :: c -> c -> (GAState c p) (c,c)
+      }
+
+data PopulationConfig c p = PopulationConfig {
+      bestChromosomePop :: p -> (GAState c p) c,
+      roulettePop :: p -> (GAState c p) p,
+      tournamentPop :: p -> (GAState c p) p,
+      applyCrossoverPop :: p -> (GAState c p) p,
+      applyMutationPop :: p -> (GAState c p) p
+      }
+-- |defaultConfig acts as a blank slate for genetic algorithms.
+-- cConfig, pConfig, gen, and maxFitness or maxGeneration must be defined
+defaultConfig :: Config c p
+defaultConfig = Config {
+                  cConfig = undefined,
+                  pConfig = undefined,
+                  newPopulation = undefined,
+                  maxFitness = Nothing,
+                  maxGeneration = Nothing,
+                  currentGeneration = 0,
+                  gen = undefined
+                  }
+
+-- |Wrapper function which returns the best chromosome of a population
+bestChromosome :: p -> (GAState c p) c
+bestChromosome pop = do
+  config <- get
+  bestChromosomePop (pConfig config) pop
+
+-- |Wrapper function which returns the highest-fitness member of a population
+highestFitness :: p -> (GAState c p) Double
+highestFitness pop = do
+  fitFunc <- (fitness . cConfig) `liftM` get
+  best <- bestChromosome pop
+  return $ fitFunc best
+
+-- |A wrapper function for use in newPopulation for roulette selection
+rouletteM :: p -> (GAState c p) p
+rouletteM pop =
+  (roulettePop . pConfig) `liftM` get >>= ($pop)
+
+-- |A wrapper function for use in newPopulation for tournament selection
+tournamentM :: p -> (GAState c p) p
+tournamentM pop =
+    (tournamentPop . pConfig) `liftM` get >>= ($pop)
+
+-- |A wrapper function for use in newPopulation for mutating the population
+mutateM :: p -> (GAState c p) p
+mutateM pop = do
+  (applyMutationPop . pConfig) `liftM` get >>= ($pop)
+
+-- |A wrapper function for use in newPopulation for applying crossover to the population
+crossM :: p -> (GAState c p) p
+crossM pop =
+    (applyCrossoverPop . pConfig) `liftM` get >>= ($pop)
+
+newPopulationM :: p -> (GAState c p) p
+newPopulationM pop =
+    incGA >> newPopulation `liftM` get >>= ($pop)
+
+incGA :: (GAState c p) ()
+incGA = modify (\c@Config { currentGeneration = g} ->
+                    c { currentGeneration = g + 1})
+
+untilM :: (Monad m) => (a -> m Bool) -> (a -> m a) -> a -> m a
+untilM p f x = do
+  test <- p x
+  if test 
+     then return x
+     else f x >>= untilM p f
+
+-- |Runs the specified GA config until the termination condition is reached
+run :: p -> (GAState c p) p
+run = untilM isDone newPopulationM
+
+-- |Returns true if the given population satisfies the termination condition for the GA config
+isDone :: p -> (GAState c p) Bool
+isDone population = do
+  c <- get
+  f <- highestFitness population
+  let generationsDone =
+          maybe False (<(currentGeneration c)) $ maxGeneration c
+  let fitnessDone =
+          maybe False (>f) $ maxFitness c
+  return $ generationsDone || fitnessDone
+
+-- |Generates a random number which updating the random number generator for the config
+gaRand :: (Random a) =>
+          (a,a) -> (GAState c p) a
+gaRand range = do
+  config <- get
+  let g = gen config
+  let (x, g') = randomR range g
+  put $ config { gen = g' }
+  return x
diff --git a/_darcs/pristine/Population/Array.hs b/_darcs/pristine/Population/Array.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/Population/Array.hs
@@ -0,0 +1,101 @@
+
+-- | Populations represented as a diff array of chromosomes
+module Population.Array (config, fromList)
+where
+
+import GA
+
+import Data.Array.Diff
+import Control.Monad
+import Control.Monad.State
+import List
+
+-- |The type used to represent population arrays; is a diff array.
+type PArray c = DiffArray Int c
+
+-- |Population config for arrays
+config :: PopulationConfig c (PArray c)
+config = PopulationConfig {
+           bestChromosomePop = bestChromosomeArray,
+           roulettePop = rouletteArray,
+           tournamentPop = tournamentArray,
+           applyCrossoverPop = crossoverArray,
+           applyMutationPop = mutateArray
+}
+
+--yipee
+tournamentArray :: PArray c -> (GAState c p) (PArray c)
+tournamentArray arr = do
+  f <- (fitness . cConfig) `liftM` get
+  let augument c = (c, f c)
+  let augArr = amap augument arr
+  aforM arr $ \_ -> do
+    index1 <- gaRand $ bounds arr
+    index2 <- gaRand $ bounds arr
+    let chrom1 = augArr ! index1
+    let chrom2 = augArr ! index2
+    if snd chrom1 > snd chrom2
+       then return $ fst chrom1
+       else return $ fst chrom2
+
+mutateArray :: PArray c -> (GAState c (PArray c)) (PArray c)
+mutateArray arr =
+    (mutate . cConfig) `liftM` get >>= flip amapM arr
+
+crossoverArray arr = do
+  c <- (cross . cConfig) `liftM` get
+  crossoverArray' c arr $ fst $ bounds arr
+
+crossoverArray' cross arr index =
+    let lastIndex = snd $ bounds arr in
+    if index > lastIndex
+       then return arr
+       else
+           let p1 = arr ! index
+               p2 = arr ! (index + 1)
+           in do (c1, c2) <- cross p1 p2
+                 let newArr = arr // [(index, c1), (index + 1, c2)]
+                 crossoverArray' cross newArr (index + 2)
+
+bestChromosomeArray :: PArray c -> (GAState c p) c
+bestChromosomeArray arr = do
+    f <- (fitness . cConfig) `liftM` get
+    let cmp x y | f x > f y = x
+                | otherwise = y
+    return $ afoldl1 cmp arr
+
+
+rouletteArray :: PArray c -> (GAState c p) (PArray c)
+rouletteArray arr = do
+  f <- (fitness . cConfig) `liftM` get
+  let totalFitness = (afoldl (\fit c -> fit + f c) 0.0 arr) :: Double
+  let augument chrom = (chrom, (f chrom) / totalFitness)
+  let augArr = amap augument arr
+  aforM arr $ \_ ->
+      selectDistribution augArr 0.0 $ fst $ bounds arr
+
+selectDistribution :: PArray (c, Double) -> Double -> Int -> (GAState c p) c
+selectDistribution arr acc index =
+    let lastIndex = snd $ bounds arr in
+    if index == lastIndex
+       then return $ fst $ arr ! lastIndex
+       else do
+         let (chrom, fit) = arr ! index
+         test <- gaRand (0.0, 1.0)
+         if test < fit / (1 - acc)
+            then return chrom
+            else selectDistribution arr (fit + acc) (index + 1)
+
+-- |Converts a list to an array
+fromList xs = listArray (0, length xs - 1) xs
+
+amapM p arr =
+    listArray (bounds arr) `liftM` mapM p (elems arr)
+
+aforM arr p = amapM p arr
+ 
+afoldl p seed arr =
+    foldl p seed $ elems arr
+
+afoldl1 p arr =
+    foldl1 p $ elems arr
diff --git a/_darcs/pristine/Population/List.hs b/_darcs/pristine/Population/List.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/Population/List.hs
@@ -0,0 +1,81 @@
+{-# OPTIONS_GHC -fglasgow-exts #-}
+
+-- | Populations represented as a list of chromosomes
+-- Arrays are recommended instead for performance reasons.
+module Population.List (config)
+where
+
+import GA
+
+import Control.Monad
+import Control.Monad.State
+import Random
+import List
+
+-- |Config for use of lists as the population model. Lists are deprecated in favor of arrays.
+config :: PopulationConfig c [c]
+config = PopulationConfig {
+           bestChromosomePop = bestChromosomeList,
+           roulettePop = rouletteList,
+           tournamentPop = tournamentList,
+           applyCrossoverPop = crossoverList,
+           applyMutationPop = mutateList
+           }
+
+-- Warning: shit performance for tournamentList :/ O(n^2) afaict
+-- Moral o Story: Lists suck, but arrays are fugly ;_;
+tournamentList :: [c] -> (GAState c [c]) [c]
+tournamentList xs = do
+  f <- (fitness . cConfig) `liftM` get
+  let len = length xs
+  let augChroms = map (\c -> (c, f c)) xs
+  forM xs $ \_ -> do
+    index1 <- gaRand (0, len - 1)
+    index2 <- gaRand (0, len - 1)
+    let test1 = augChroms !! index1
+    let test2 = augChroms !! index2
+    if snd test1 > snd test2
+       then return $ fst test1
+       else return $ fst test2
+
+crossoverList :: [c] -> (GAState c [c]) [c]
+crossoverList [] = return []
+crossoverList [x] = return [x]
+crossoverList (x:y:xs) = do
+  c <- (cross . cConfig) `liftM` get
+  (offspring1,offspring2) <- c x y
+  rest <- crossoverList xs
+  return $ offspring1 : offspring2 : rest
+
+mutateList :: [c] -> (GAState c [c]) [c]
+mutateList cs =
+    (mutate . cConfig) `liftM` get >>= forM cs
+
+rouletteList :: [c] -> (GAState c [c]) [c]
+rouletteList cs = do
+  f <- (fitness . cConfig) `liftM` get
+  let fs = map f cs
+  let total = sum fs
+  let probs = map (/total) fs
+  let augumentedChromosomes = zip cs probs
+  forM cs $
+           \_ -> selectDistribution augumentedChromosomes
+
+
+bestChromosomeList :: [c] -> (GAState c [c]) c
+bestChromosomeList cs = do
+  f <- (fitness . cConfig) `liftM` get
+  let compareChromosomes x y =
+          compare (f x) (f y)
+  return $ maximumBy compareChromosomes cs
+
+
+selectDistribution :: [(a, Double)] -> (GAState c p) a
+selectDistribution xs =
+    select 0.0 xs
+    where select _ ((a,p):[]) = return a
+          select acc ((a,p):xs) = do
+            test <- gaRand (0,1.0)
+            if test < p / (1 - acc)
+               then return a
+               else select (p + acc) xs
diff --git a/_darcs/pristine/examples/ANNTest.hs b/_darcs/pristine/examples/ANNTest.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/examples/ANNTest.hs
@@ -0,0 +1,70 @@
+import GA
+import qualified Population.List as L
+import Random
+import Control.Monad.State
+import List
+import qualified Chromosome.ANN as ANN
+import Control.Monad
+
+
+-- This function takes a population ("pop"), then mutates it, then applies roulette selection
+mynewPopulation pop = mutateM pop >>= rouletteM
+
+
+myconfig = defaultConfig {
+             -- cConfig configures the chromosome model and the genetic operators
+             cConfig = ANN.config {
+                         fitness = ANN.fitnessMSE xorExamples,
+                         mutate = ANN.mutateShift 0.1 1.0,
+                         cross = ANN.uniformCross
+                         },
+
+             -- The population will be represented as a list
+             pConfig = L.config,
+
+             -- To generate the next population, mynewPopulation will be called
+             newPopulation = mynewPopulation,
+
+             -- Stop after 1000 generations
+             maxGeneration = Just 1000,
+
+             -- Initialize the random number generator to 42
+             -- 42 is chosen for obvious reasons
+             gen = mkStdGen 42
+             }
+
+-- Create an initial population of 20 ANN's
+-- Each will have 2 inputs and two hidden layers of [2,1] nodes, respectively
+-- The weights will be randomly initialized to +/- 2.0
+initPop = replicateM 20 $ ANN.randomANN 2 [2,1] 2.0
+
+-- The examples are a list of (in, out)
+xorExamples =
+    zip xorIn xorOut
+    where xorIn = [[0.0,0.0], [1.0,1.0], [1.0,0.0], [0.0,1.0]]
+          xorOut = [[0.0], [0.0], [1.0], [1.0]]
+
+getBest = do
+  pop <- initPop
+  
+  -- Grab the best chromosome at the start for comparision
+  before <- bestChromosome pop
+  
+  -- Evaluation of the GA
+  answer <- run pop
+  
+  -- Find the new best chromosome after running the GA
+  after <- bestChromosome answer
+  
+  return (before, after)
+
+main = do
+  -- Run the GA with the config "myconfig"
+  let (before, after) = evalState getBest myconfig
+  
+  -- Tell how many examples are correct within +/0 0.3
+  putStrLn $ show $ round $ ANN.correctExamples xorExamples 0.3 before
+  putStrLn $ show $ round $ ANN.correctExamples xorExamples 0.3 after
+  
+  -- Print out the final neural network
+  putStrLn $ show $ after
diff --git a/_darcs/pristine/examples/BitTest.hs b/_darcs/pristine/examples/BitTest.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/examples/BitTest.hs
@@ -0,0 +1,64 @@
+import GA
+import qualified Population.List as L
+import Random
+import Control.Monad.State
+import List
+import qualified Chromosome.Bits as B
+import Control.Monad
+
+myconfig = defaultConfig {
+             -- cConfig configures the chromosome model and the genetic operators
+             cConfig = B.config {
+                         -- This (trivial) fitness function just converts the bits to a double
+                         -- Larger numbers are "more fit"; the maximally fit chromosome is all 1's (True's)
+                         fitness = fromIntegral . B.bits2int,
+                         mutate = B.mutateBits (0.1 :: Double)
+                         -- The crossover operator defaults to point cross
+                         -- This only works for some chromosomes, such as bits
+                         },
+
+             -- The population will be represented as a list
+             pConfig = L.config,
+
+             -- To generate the next population, mynewPopulation will be called
+             newPopulation = mynewPopulation,
+             
+             -- Stop after 100 generations
+             maxGeneration = Just 100,
+             
+             -- Initialize the random number generator to 42
+             -- 42 is chosen for obvious reasons
+             gen = mkStdGen 42
+             }
+
+-- This function takes a population ("pop"), then mutates it, then applies roulette selection
+mynewPopulation pop = mutateM pop >>= rouletteM
+
+-- Create an initial population of 100 bit lists
+-- Each will have the 4 LSB randomly generated and the 4 MSB set to False
+initPop = liftM (map (++[False,False,False,False])) $ replicateM 100 (B.randomBits 4)
+
+getBest = do
+  pop <- initPop
+  
+  -- Grab the best chromosome at the start for comparision
+  before <- bestChromosome pop
+  
+  -- Evaluation of the GA
+  answer <- run pop
+  
+  -- Find the new best chromosome after running the GA
+  after <- bestChromosome answer
+  
+  return (before, after)
+
+main = do
+  -- Run the GA with the config "myconfig"
+  let (before, after) = evalState getBest myconfig
+  
+  -- Show the starting and ending fitness
+  putStrLn $ show $ round $ fromIntegral $ B.bits2int before
+  putStrLn $ show $ round $ fromIntegral $ B.bits2int after
+
+  -- Print out the final chromosome
+  putStrLn $ show after
diff --git a/_darcs/pristine/examples/GPTest.hs b/_darcs/pristine/examples/GPTest.hs
new file mode 100644
--- /dev/null
+++ b/_darcs/pristine/examples/GPTest.hs
@@ -0,0 +1,75 @@
+import GA
+import qualified Population.List as L
+import Random
+import Control.Monad.State
+import List
+import qualified Chromosome.GP as GP
+import Control.Monad
+
+-- Defines the operators available for the GP
+-- You must specify the function, then the arity (number of arguments), then the textual representation
+ops :: [GP.Op Double Double]
+ops = [
+ GP.Op (\[x,y] -> return $ x + y) 2 "+", -- Addition
+ GP.Op (\[x,y] -> return $ x - y) 2 "-", -- Subtraction
+ GP.Op (\[x,y] -> return $ x * y) 2 "*", -- Multiplication
+ GP.Op (\[] -> return 1) 0 "1", -- The constant 1
+ GP.Op (\[] -> get) 0 "x" -- The independant variable
+ ]
+
+-- Examples for the function f(x) = 3x^2 + 1
+examples :: [(Double,Double)]
+examples = zip [1..10] $ map (\x -> 3 * x * x + 1) [1..10]
+
+myconfig = defaultConfig {
+             -- cConfig configures the chromosome model and the genetic operators
+             cConfig = ChromosomeConfig {
+                         -- Compute fitness based on the mean square error across the examples
+                         fitness = GP.mseFitness examples,
+                         -- Max tree depth of 4, mutation rate of 0.05
+                         mutate = GP.mutate 4 ops (0.05 :: Double),
+                         -- Oops! crossover not yet implemented for GP, see GP.hs for details
+                         cross = error "Attempt to cross GP"
+                         },
+             
+             -- The population will be represented as a list
+             pConfig = L.config,
+
+             -- To generate the next population, mynewPopulation will be called
+             newPopulation = mynewPopulation,
+             
+             -- Stop after 100 generations
+             maxGeneration = Just 500,
+             
+             -- Initialize the random number generator to 42
+             -- 42 is chosen for obvious reasons
+             gen = mkStdGen 42
+             }
+-- This function takes a population ("pop"), then mutates it, then applies roulette selection
+mynewPopulation pop = mutateM pop >>= rouletteM
+
+-- Create an initial population of 100 GP's 
+-- Tree depth of 4 using ops as the pool of available tree nodes
+initPop = replicateM 100 $ GP.random 4 ops
+
+getBest = do
+  pop <- initPop
+  
+  -- Grab the best chromosome at the start for comparision
+  before <- bestChromosome pop
+  
+  -- Evaluation of the GA
+  answer <- run pop
+  
+  -- Find the new best chromosome after running the GA
+  after <- bestChromosome answer
+  
+  return (before, after)
+
+main = do
+  -- Run the GA with the config "myconfig"
+  let (before,after) = evalState getBest myconfig
+  
+  -- Show the before/after s-expressions
+  putStrLn $ show $ before
+  putStrLn $ show $ after
diff --git a/_darcs/tentative_pristine b/_darcs/tentative_pristine
new file mode 100644
--- /dev/null
+++ b/_darcs/tentative_pristine
@@ -0,0 +1,16 @@
+hunk ./examples/GPTest.hs 15
++ GP.Op (\[x,y] -> return $ x * y) 2 "*", -- Multiplication
+hunk ./examples/GPTest.hs 20
+--- Examples for the function f(x) = 2x + 1
++-- Examples for the function f(x) = 3x^2 + 1
+hunk ./examples/GPTest.hs 22
+-examples = zip [1..10] $ map (\x -> 2 * x + 1) [1..10]
++examples = zip [1..10] $ map (\x -> 3 * x * x + 1) [1..10]
+hunk ./examples/GPTest.hs 42
+-             maxGeneration = Just 100,
++             maxGeneration = Just 500,
+hunk ./examples/GPTest.hs 52
+--- Tree depth of 3 using ops as the pool of available tree nodes
+-initPop = replicateM 100 $ GP.random 3 ops
++-- Tree depth of 4 using ops as the pool of available tree nodes
++initPop = replicateM 100 $ GP.random 4 ops
diff --git a/examples/ANNTest.hs b/examples/ANNTest.hs
new file mode 100644
--- /dev/null
+++ b/examples/ANNTest.hs
@@ -0,0 +1,70 @@
+import GA
+import qualified Population.List as L
+import Random
+import Control.Monad.State
+import List
+import qualified Chromosome.ANN as ANN
+import Control.Monad
+
+
+-- This function takes a population ("pop"), then mutates it, then applies roulette selection
+mynewPopulation pop = mutateM pop >>= rouletteM
+
+
+myconfig = defaultConfig {
+             -- cConfig configures the chromosome model and the genetic operators
+             cConfig = ANN.config {
+                         fitness = ANN.fitnessMSE xorExamples,
+                         mutate = ANN.mutateShift 0.1 1.0,
+                         cross = ANN.uniformCross
+                         },
+
+             -- The population will be represented as a list
+             pConfig = L.config,
+
+             -- To generate the next population, mynewPopulation will be called
+             newPopulation = mynewPopulation,
+
+             -- Stop after 1000 generations
+             maxGeneration = Just 1000,
+
+             -- Initialize the random number generator to 42
+             -- 42 is chosen for obvious reasons
+             gen = mkStdGen 42
+             }
+
+-- Create an initial population of 20 ANN's
+-- Each will have 2 inputs and two hidden layers of [2,1] nodes, respectively
+-- The weights will be randomly initialized to +/- 2.0
+initPop = replicateM 20 $ ANN.randomANN 2 [2,1] 2.0
+
+-- The examples are a list of (in, out)
+xorExamples =
+    zip xorIn xorOut
+    where xorIn = [[0.0,0.0], [1.0,1.0], [1.0,0.0], [0.0,1.0]]
+          xorOut = [[0.0], [0.0], [1.0], [1.0]]
+
+getBest = do
+  pop <- initPop
+  
+  -- Grab the best chromosome at the start for comparision
+  before <- bestChromosome pop
+  
+  -- Evaluation of the GA
+  answer <- run pop
+  
+  -- Find the new best chromosome after running the GA
+  after <- bestChromosome answer
+  
+  return (before, after)
+
+main = do
+  -- Run the GA with the config "myconfig"
+  let (before, after) = evalState getBest myconfig
+  
+  -- Tell how many examples are correct within +/0 0.3
+  putStrLn $ show $ round $ ANN.correctExamples xorExamples 0.3 before
+  putStrLn $ show $ round $ ANN.correctExamples xorExamples 0.3 after
+  
+  -- Print out the final neural network
+  putStrLn $ show $ after
diff --git a/examples/BitTest.hs b/examples/BitTest.hs
new file mode 100644
--- /dev/null
+++ b/examples/BitTest.hs
@@ -0,0 +1,64 @@
+import GA
+import qualified Population.List as L
+import Random
+import Control.Monad.State
+import List
+import qualified Chromosome.Bits as B
+import Control.Monad
+
+myconfig = defaultConfig {
+             -- cConfig configures the chromosome model and the genetic operators
+             cConfig = B.config {
+                         -- This (trivial) fitness function just converts the bits to a double
+                         -- Larger numbers are "more fit"; the maximally fit chromosome is all 1's (True's)
+                         fitness = fromIntegral . B.bits2int,
+                         mutate = B.mutateBits (0.1 :: Double)
+                         -- The crossover operator defaults to point cross
+                         -- This only works for some chromosomes, such as bits
+                         },
+
+             -- The population will be represented as a list
+             pConfig = L.config,
+
+             -- To generate the next population, mynewPopulation will be called
+             newPopulation = mynewPopulation,
+             
+             -- Stop after 100 generations
+             maxGeneration = Just 100,
+             
+             -- Initialize the random number generator to 42
+             -- 42 is chosen for obvious reasons
+             gen = mkStdGen 42
+             }
+
+-- This function takes a population ("pop"), then mutates it, then applies roulette selection
+mynewPopulation pop = mutateM pop >>= rouletteM
+
+-- Create an initial population of 100 bit lists
+-- Each will have the 4 LSB randomly generated and the 4 MSB set to False
+initPop = liftM (map (++[False,False,False,False])) $ replicateM 100 (B.randomBits 4)
+
+getBest = do
+  pop <- initPop
+  
+  -- Grab the best chromosome at the start for comparision
+  before <- bestChromosome pop
+  
+  -- Evaluation of the GA
+  answer <- run pop
+  
+  -- Find the new best chromosome after running the GA
+  after <- bestChromosome answer
+  
+  return (before, after)
+
+main = do
+  -- Run the GA with the config "myconfig"
+  let (before, after) = evalState getBest myconfig
+  
+  -- Show the starting and ending fitness
+  putStrLn $ show $ round $ fromIntegral $ B.bits2int before
+  putStrLn $ show $ round $ fromIntegral $ B.bits2int after
+
+  -- Print out the final chromosome
+  putStrLn $ show after
diff --git a/examples/GPTest.hs b/examples/GPTest.hs
new file mode 100644
--- /dev/null
+++ b/examples/GPTest.hs
@@ -0,0 +1,75 @@
+import GA
+import qualified Population.List as L
+import Random
+import Control.Monad.State
+import List
+import qualified Chromosome.GP as GP
+import Control.Monad
+
+-- Defines the operators available for the GP
+-- You must specify the function, then the arity (number of arguments), then the textual representation
+ops :: [GP.Op Double Double]
+ops = [
+ GP.Op (\[x,y] -> return $ x + y) 2 "+", -- Addition
+ GP.Op (\[x,y] -> return $ x - y) 2 "-", -- Subtraction
+ GP.Op (\[x,y] -> return $ x * y) 2 "*", -- Multiplication
+ GP.Op (\[] -> return 1) 0 "1", -- The constant 1
+ GP.Op (\[] -> get) 0 "x" -- The independant variable
+ ]
+
+-- Examples for the function f(x) = 3x^2 + 1
+examples :: [(Double,Double)]
+examples = zip [1..10] $ map (\x -> 3 * x * x + 1) [1..10]
+
+myconfig = defaultConfig {
+             -- cConfig configures the chromosome model and the genetic operators
+             cConfig = ChromosomeConfig {
+                         -- Compute fitness based on the mean square error across the examples
+                         fitness = GP.mseFitness examples,
+                         -- Max tree depth of 4, mutation rate of 0.05
+                         mutate = GP.mutate 4 ops (0.05 :: Double),
+                         -- Oops! crossover not yet implemented for GP, see GP.hs for details
+                         cross = error "Attempt to cross GP"
+                         },
+             
+             -- The population will be represented as a list
+             pConfig = L.config,
+
+             -- To generate the next population, mynewPopulation will be called
+             newPopulation = mynewPopulation,
+             
+             -- Stop after 100 generations
+             maxGeneration = Just 500,
+             
+             -- Initialize the random number generator to 42
+             -- 42 is chosen for obvious reasons
+             gen = mkStdGen 42
+             }
+-- This function takes a population ("pop"), then mutates it, then applies roulette selection
+mynewPopulation pop = mutateM pop >>= rouletteM
+
+-- Create an initial population of 100 GP's 
+-- Tree depth of 4 using ops as the pool of available tree nodes
+initPop = replicateM 100 $ GP.random 4 ops
+
+getBest = do
+  pop <- initPop
+  
+  -- Grab the best chromosome at the start for comparision
+  before <- bestChromosome pop
+  
+  -- Evaluation of the GA
+  answer <- run pop
+  
+  -- Find the new best chromosome after running the GA
+  after <- bestChromosome answer
+  
+  return (before, after)
+
+main = do
+  -- Run the GA with the config "myconfig"
+  let (before,after) = evalState getBest myconfig
+  
+  -- Show the before/after s-expressions
+  putStrLn $ show $ before
+  putStrLn $ show $ after
diff --git a/hgalib.cabal b/hgalib.cabal
new file mode 100644
--- /dev/null
+++ b/hgalib.cabal
@@ -0,0 +1,20 @@
+name:                hgalib
+version:             0.1
+synopsis:            Haskell Genetic Algorithm Library
+description:         Haskell Genetic Algorithm Library
+category:            AI
+license:             PublicDomain
+license-file:        LICENSE
+author:              Kevin Ellis
+maintainer:          Kevin Ellis <ellisk@catlin.edu>
+build-type:          Simple
+Cabal-Version: >= 1.2
+Library
+    exposed-modules: GA,
+                     Population.List,
+                     Population.Array,
+                     Chromosome.Bits,
+                     Chromosome.ANN,
+                     Chromosome.GP
+    ghc-options:     -O2
+    build-depends:   base >= 3, array, mtl, haskell98
