packages feed

creatur 5.9.6 → 5.9.7

raw patch · 5 files changed

+140/−76 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

+ ALife.Creatur.Genetics.BRGCBool: getWithName :: Genetic g => String -> Reader (Either [String] g)
+ ALife.Creatur.Genetics.BRGCWord16: getWithName :: Genetic g => String -> Reader (Either [String] g)
+ ALife.Creatur.Genetics.BRGCWord8: getAndReport :: Int -> ([Word8] -> (Either String (g, String))) -> Reader (Either [String] g)
+ ALife.Creatur.Genetics.BRGCWord8: putAndReport :: [Word8] -> String -> Writer ()
- ALife.Creatur.Genetics.BRGCBool: class Genetic g where put = gput . from get = do { a <- gget; return $ fmap to a } getWithDefault d = fmap (fromEither d) get
+ ALife.Creatur.Genetics.BRGCBool: class Genetic g where put = gput . from get = do { a <- gget; return $ fmap to a } getWithDefault d = fmap (fromEither d) get getWithName s = do { g0 <- get; return $ case g0 of { (Left xs) -> Left ((s ++ ":") : xs) (Right g1) -> Right g1 } }
- ALife.Creatur.Genetics.BRGCWord16: class Genetic g where put = gput . from get = do { a <- gget; return $ fmap to a } getWithDefault d = fmap (fromEither d) get
+ ALife.Creatur.Genetics.BRGCWord16: class Genetic g where put = gput . from get = do { a <- gget; return $ fmap to a } getWithDefault d = fmap (fromEither d) get getWithName s = do { g0 <- get; return $ case g0 of { (Left xs) -> Left ((s ++ ":") : xs) (Right g1) -> Right g1 } }
- ALife.Creatur.Genetics.BRGCWord8: runReader :: Reader g -> Sequence -> g
+ ALife.Creatur.Genetics.BRGCWord8: runReader :: Reader (Either [String] g) -> Sequence -> (Either [String] g, [String])
- ALife.Creatur.Genetics.BRGCWord8: runWriter :: Writer () -> Sequence
+ ALife.Creatur.Genetics.BRGCWord8: runWriter :: Writer () -> (Sequence, [String])
- ALife.Creatur.Genetics.BRGCWord8: type DiploidReader = StateT ((Sequence, Int), (Sequence, Int)) Identity
+ ALife.Creatur.Genetics.BRGCWord8: type DiploidReader = StateT ((Sequence, Int, [String]), (Sequence, Int, [String])) Identity
- ALife.Creatur.Genetics.BRGCWord8: type Reader = StateT (Sequence, Int) Identity
+ ALife.Creatur.Genetics.BRGCWord8: type Reader = StateT (Sequence, Int, [String]) Identity
- ALife.Creatur.Genetics.BRGCWord8: type Writer = StateT Sequence Identity
+ ALife.Creatur.Genetics.BRGCWord8: type Writer = StateT (Sequence, [String]) Identity

Files

creatur.cabal view
@@ -1,22 +1,22 @@ Name:              creatur-Version:           5.9.6+Version:           5.9.7 Stability:         experimental Synopsis:          Framework for artificial life experiments. Description:       A software framework for automating experiments                    with artificial life. It provides a daemon which-                   maintains its own "clock", schedules events, -                   provides logging, and ensures that each agent gets -                   its turn to use the CPU. You can use other +                   maintains its own "clock", schedules events,+                   provides logging, and ensures that each agent gets+                   its turn to use the CPU. You can use other                    applications on the computer at the same time                    without fear of interfering with experiments; they-                   will run normally, just more slowly. See the -                   tutorial at +                   will run normally, just more slowly. See the+                   tutorial at                    <https://github.com/mhwombat/creatur-examples/raw/master/Tutorial.pdf>                    for examples on how to use the                    Créatúr framework.                    .                    About the name: \"Créatúr\" (pronounced kray-toor)-                   is an Irish word meaning animal, creature, or an +                   is an Irish word meaning animal, creature, or an                    unfortunate person. Category:          AI License:           BSD3@@ -36,12 +36,12 @@ source-repository this   type:     git   location: https://github.com/mhwombat/creatur.git-  tag:      5.9.6+  tag:      5.9.7  library   GHC-Options:      -Wall -fno-warn-orphans   Hs-source-dirs:   src-  exposed-modules:  +  exposed-modules:                     ALife.Creatur,                     ALife.Creatur.Checklist,                     ALife.Creatur.Clock,@@ -68,7 +68,7 @@                     ALife.Creatur.Task,                     ALife.Creatur.Util   Other-modules:    Paths_creatur-  Build-Depends:    +  Build-Depends:                     array ==0.5.*,                     base ==4.*,                     bytestring ==0.10.*,@@ -95,7 +95,7 @@   Main-is:          TestAll.hs   GHC-Options:      -Wall   Hs-source-dirs:   test-  Build-Depends:    +  Build-Depends:                     array ==0.5.*,                     base ==4.*,                     binary ==0.7.*,@@ -126,17 +126,16 @@                     ALife.Creatur.PersistentQC                     ALife.Creatur.UniverseQC                     ALife.Creatur.UtilQC-                     + -- Benchmark creatur-bench --   Type:             exitcode-stdio-1.0 --   Main-is:          BenchAll.hs --   GHC-Options:      -Wall --   Hs-source-dirs:   test---   Build-Depends:    +--   Build-Depends: --                     base ==4.*, --                     creatur, --                     criterion ==0.8.*, --                     test-framework ==0.8.* --   Other-modules:    ALife.Creatur.Genetics.BRGCWord8Bench-
src/ALife/Creatur/Genetics/BRGCBool.hs view
@@ -118,6 +118,13 @@   getWithDefault :: g -> Reader g   getWithDefault d = fmap (fromEither d) get +  getWithName :: String -> Reader (Either [String] g)+  getWithName s = do+    g0 <- get+    return $ case g0 of+               (Left xs) -> Left ((s ++ ":"):xs)+               (Right g1) -> Right g1+ class GGenetic f where   gput :: f a -> Writer ()   gget :: Reader (Either [String] (f a))
src/ALife/Creatur/Genetics/BRGCWord16.hs view
@@ -120,6 +120,13 @@   getWithDefault :: g -> Reader g   getWithDefault d = fmap (fromEither d) get +  getWithName :: String -> Reader (Either [String] g)+  getWithName s = do+    g0 <- get+    return $ case g0 of+               (Left xs) -> Left ((s ++ ":"):xs)+               (Right g1) -> Right g1+ class GGenetic f where   gput :: f a -> Writer ()   gget :: Reader (Either [String] (f a))
src/ALife/Creatur/Genetics/BRGCWord8.hs view
@@ -24,6 +24,7 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE CPP #-} module ALife.Creatur.Genetics.BRGCWord8@@ -46,6 +47,8 @@     getAndExpressWithDefault,     copy2,     consumed2,+    putAndReport,+    getAndReport,     putRawWord8,     getRawWord8,     putRawWord8s,@@ -56,6 +59,7 @@ import ALife.Creatur.Genetics.Diploid (Diploid, express) import ALife.Creatur.Util (fromEither) import Codec.Gray (integralToGray, grayToIntegral)+import Control.Monad (replicateM) import Control.Monad.State.Lazy (StateT, runState, execState, evalState) import qualified Control.Monad.State.Lazy as S (put, get, gets) import Data.Char (ord, chr)@@ -71,30 +75,33 @@  type Sequence = [Word8] -type Writer = StateT Sequence Identity+type Writer = StateT (Sequence, [String]) Identity  write :: Genetic x => x -> Sequence-write x = runWriter (put x)+write x = fst $ runWriter (put x) -runWriter :: Writer () -> Sequence-runWriter w = execState (w >> finalise) []+runWriter :: Writer () -> (Sequence, [String])+runWriter w = execState (w >> finalise) ([], []) -type Reader = StateT (Sequence, Int) Identity+type Reader = StateT (Sequence, Int, [String]) Identity  read :: Genetic g => Sequence -> Either [String] g-read s = evalState get (s, 0)+read s = fst $ runReader get s -runReader :: Reader g -> Sequence -> g-runReader r s = evalState r (s, 0)+runReader+  :: Reader (Either [String] g) -> Sequence+    -> (Either [String] g, [String])+runReader r s = (x, reverse msgs)+  where (x, (_, _, msgs)) = runState r (s, 0, [])  -- | Return the entire genome. copy :: Reader Sequence-copy = S.gets fst+copy = S.gets (\(x, _, _) -> x)  -- | Return the portion of the genome that has been read. consumed :: Reader Sequence consumed = do-  (xs, i) <- S.get+  (xs, i, _) <- S.get   return $ take i xs  -- | A class representing anything which is represented in, and@@ -140,17 +147,23 @@  -- | Meta-information (constructor names, etc.) instance (GGenetic a, GGenetic b) => GGenetic (a :+: b) where-  gput (L1 x) = putRawWord8 0 >> gput x-  gput (R1 x) = putRawWord8 1 >> gput x+  gput (L1 x) = putAndReport [0] "L1" >> gput x+  gput (R1 x) = putAndReport [1] "R1" >> gput x   gget = do-    a <- getRawWord8+    a <- getAndReport 1 convertLR     case a of-      Right x -> do-        if even x -- Only care about the last bit-          then fmap (fmap L1) gget-          else fmap (fmap R1) gget-      Left s -> return $ Left s+      Right L -> fmap (fmap L1) gget+      Right R -> fmap (fmap R1) gget+      Left s  -> return $ Left s +data LR = L | R++convertLR :: [Word8] -> Either String (LR, String)+convertLR (x:[]) = if even x -- Only care about the last bit+                     then Right (L, "L1")+                     else Right (R, "R1")+convertLR _ = Left "logic error"+   -- | Sums: encode choice between constructors instance (GGenetic a) => GGenetic (M1 i c a) where   gput (M1 x) = gput x@@ -168,35 +181,48 @@ --  instance Genetic Bool where-  put False = putRawWord8 0-  put True  = putRawWord8 1-  get = fmap (fmap word8ToBool) getRawWord8+  put b = putAndReport [fromIntegral $ fromEnum b] (show b)+  get = getAndReport 1 convert+    where convert (x:[]) = Right (g, show g)+            where g = word8ToBool x+          convert _ = Left "logic error"  word8ToBool :: Word8 -> Bool word8ToBool x = if even x then False else True  instance Genetic Char where-  put = putRawWord8 . fromIntegral . ord-  get = fmap (fmap (chr . fromIntegral)) getRawWord8+  put x = putAndReport [fromIntegral . ord $ x] (show x)+  get = getAndReport 1 convert+    where convert (x:[]) = Right (g, show g)+            where g = (chr . fromIntegral) x+          convert _ = Left "logic error"  instance Genetic Word8 where-  put = putRawWord8 . integralToGray-  get = fmap (fmap grayToIntegral) getRawWord8+  put x = putAndReport [integralToGray x] (show x ++ " Word8")+  get = getAndReport 1 convert+    where convert (x:[]) = Right (g, show g ++ " Word8")+            where g = grayToIntegral x+          convert _ = Left "logic error"  instance Genetic Word16 where-  put g = putRawWord8 high >> putRawWord8 low+  put g = putAndReport+            [fromIntegral $ x `div` 0x100, fromIntegral $ x `mod` 0x100]+              (show g ++ " Word16")     where x = integralToGray g-          high = fromIntegral (x `div` 0x100)-          low = fromIntegral (x `mod` 0x100)-  get = do-    h <- getRawWord8 :: Reader (Either [String] Word8)-    let high = fmap (\x -> fromIntegral x * 0x100) h :: Either [String] Word16-    l <- getRawWord8 :: Reader (Either [String] Word8)-    let low = fmap fromIntegral l :: Either [String] Word16-    return . fmap grayToIntegral $ (+) <$> high <*> low+  get = getAndReport 2 grayWord16 +grayWord16 :: [Word8] -> Either String (Word16, String)+grayWord16 (x:y:[]) = Right (g, show g ++ " Word16")+  where g = grayToIntegral (high + low) :: Word16+        high = fromIntegral x * 0x100+        low = fromIntegral y+grayWord16 _ = Left "logic error"+ instance (Genetic a) => Genetic [a] where-  put xs = put n' >> mapM_ put xs+  put xs = do+    put n'+    replaceReportW (show n' ++ " list length")+    mapM_ put xs     where n = length xs           n' = if n <= fromIntegral (maxBound :: Word16)                  then fromIntegral n@@ -204,7 +230,8 @@   get = do     n <- get :: Reader (Either [String] Word16)     case n of-      Right n' -> getList (fromIntegral n')+      Right n' -> do replaceReportR (show n' ++ " list length")+                     getList (fromIntegral n')       Left s   -> return $ Left s  instance (Genetic a) => Genetic (Maybe a)@@ -220,10 +247,11 @@  finalise :: Writer () finalise = do-  xs <- S.get-  S.put (reverse xs)+  (xs, msgs) <- S.get+  S.put (reverse xs, reverse msgs)  getList :: Genetic a => Int -> Reader (Either [String] [a])+getList 0 = return $ Right [] getList n = do   cs <- sequence $ replicate n get   let (mss, xs) = partitionEithers cs@@ -234,55 +262,78 @@ -- | Write a Word8 value to the genome without encoding it putRawWord8 :: Word8 -> Writer () putRawWord8 x = do-  xs <- S.get-  S.put (x:xs)+  (xs, msgs) <- S.get+  S.put (x:xs, msgs)  -- | Read a Word8 value from the genome without decoding it getRawWord8 :: Reader (Either [String] Word8) getRawWord8 = do-  (xs, i) <- S.get+  (xs, i, msgs) <- S.get   let xs' = drop i xs   if null xs'      then return $ Left ["End of sequence"]      else do        let x = head xs'-       S.put (xs, i+1)+       S.put (xs, i+1, msgs)        return $ Right x  -- | Write a raw sequence of Word8 values to the genome putRawWord8s :: [Word8] -> Writer ()-putRawWord8s ys = do-  xs <- S.get-  S.put (reverse ys ++ xs)+putRawWord8s ws = mapM_ putRawWord8 ws  -- | Read a raw sequence of Word8 values from the genome getRawWord8s :: Int -> Reader (Either [String] [Word8])-getRawWord8s n =-  if n == 0-    then return $ Right []-    else do-      (xs, i) <- S.get-      let xs' = drop i xs-      if null xs' || length xs' < n-        then return $ Left ["End of genes"]-        else do-          let ys = take n xs'-          S.put (xs, i+n)-          return $ Right ys+getRawWord8s n = fmap sequence $ replicateM n getRawWord8 +reportW :: String -> Writer ()+reportW desc = do+  (xs, msgs) <- S.get+  let msg = show (length xs) ++ ": wrote " ++ desc+  S.put (xs, msg:msgs)+  +putAndReport :: [Word8] -> String -> Writer ()+putAndReport bytes msg = putRawWord8s bytes >> reportW msg++replaceReportW :: String -> Writer ()+replaceReportW desc = do+  (xs, _:msgs) <- S.get+  let msg = show (length xs) ++ ": wrote " ++ desc+  S.put (xs, msg:msgs)+  +reportR :: String -> Reader ()+reportR desc = do+  (xs, i, msgs) <- S.get+  let msg = show i ++ ": read " ++ desc+  S.put (xs, i, msg:msgs)++getAndReport :: Int -> ([Word8] -> (Either String (g, String))) -> Reader (Either [String] g)+getAndReport n parse = do+  a <- getRawWord8s n+  case a of+   Right xs    -> case parse xs of+                    Right (g, msg) -> reportR msg >> return (Right g)+                    Left errMsg2   -> return $ Left [errMsg2]+   Left errMsg -> return $ Left errMsg++replaceReportR :: String -> Reader ()+replaceReportR desc = do+  (xs, i, _:msgs) <- S.get+  let msg = show i ++ ": read " ++ desc+  S.put (xs, i, msg:msgs)+   -- -- Diploid genes --  type DiploidSequence = (Sequence, Sequence) -type DiploidReader = StateT ((Sequence, Int), (Sequence, Int)) Identity+type DiploidReader = StateT ((Sequence, Int, [String]), (Sequence, Int, [String])) Identity  readAndExpress :: (Genetic g, Diploid g) => DiploidSequence -> Either [String] g-readAndExpress (s1, s2) = evalState getAndExpress ((s1, 0), (s2, 0))+readAndExpress (s1, s2) = evalState getAndExpress ((s1, 0, []), (s2, 0, []))  runDiploidReader :: DiploidReader g -> DiploidSequence -> g-runDiploidReader r (s1, s2) = evalState r ((s1, 0), (s2, 0))+runDiploidReader r (s1, s2) = evalState r ((s1, 0, []), (s2, 0, []))  -- | Return the entire genome. copy2 :: DiploidReader DiploidSequence
test/ALife/Creatur/Genetics/BRGCWord8QC.hs view
@@ -41,9 +41,9 @@  prop_rawWord8s_round_trippable :: [Word8] -> Property prop_rawWord8s_round_trippable g = property $ g' == g-  where x = runWriter (putRawWord8s g)+  where x = fst $ runWriter (putRawWord8s g)         g' = fromEither (error "read returned Nothing") .-               runReader (getRawWord8s n) $ x+               fst . runReader (getRawWord8s n) $ x         n = length g  data TestStructure = A | B Bool | C Word8 | D Word16 Char | E [TestStructure]