packages feed

ADPfusion 0.0.1.2 → 0.1.0.0

raw patch · 7 files changed

+941/−20 lines, 7 filesdep +QuickCheckdep +criteriondep +ghc-primdep ~PrimitiveArraydep ~primitivedep ~vectornew-component:exe:GAPcriterionPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck, criterion, ghc-prim

Dependency ranges changed: PrimitiveArray, primitive, vector

API changes (from Hackage documentation)

+ ADP.Fusion.GAPlike: (%) :: a -> b -> (a, b)
+ ADP.Fusion.GAPlike: (...) :: (t1 -> s) -> (s -> t) -> t1 -> t
+ ADP.Fusion.GAPlike: (..@) :: (t1 -> s) -> (t1 -> s -> t) -> t1 -> t
+ ADP.Fusion.GAPlike: (<<<) :: (Build x, StreamElement (BuildStack x), MkStream m (BuildStack x), Apply (StreamArg (BuildStack x) -> b), Monad m) => Fun (StreamArg (BuildStack x) -> b) -> x -> (Int, Int) -> Stream m b
+ ADP.Fusion.GAPlike: (|||) :: Monad m => (t -> Stream m a) -> (t -> Stream m a) -> t -> Stream m a
+ ADP.Fusion.GAPlike: (~~) :: a -> b -> (a, b)
+ ADP.Fusion.GAPlike: ArgZ :: ArgZ
+ ADP.Fusion.GAPlike: BTtbl :: t -> g -> BTtbl c t g
+ ADP.Fusion.GAPlike: Chr :: !(Vector e) -> Chr e
+ ADP.Fusion.GAPlike: Empty :: Empty
+ ADP.Fusion.GAPlike: MTbl :: !es -> MTbl c es
+ ADP.Fusion.GAPlike: None :: None
+ ADP.Fusion.GAPlike: RRegion :: !Int -> !Int -> !(Vector e) -> RestrictedRegion e
+ ADP.Fusion.GAPlike: Tbl :: !es -> Tbl c es
+ ADP.Fusion.GAPlike: apply :: Apply x => Fun x -> x
+ ADP.Fusion.GAPlike: bttblE :: t -> g -> BTtbl E t g
+ ADP.Fusion.GAPlike: bttblN :: t -> g -> BTtbl N t g
+ ADP.Fusion.GAPlike: build :: Build x => x -> BuildStack x
+ ADP.Fusion.GAPlike: class Apply x where type family Fun x :: *
+ ADP.Fusion.GAPlike: class Build x where type family BuildStack x :: * type instance BuildStack x = None :. x build x = None :. x
+ ADP.Fusion.GAPlike: class StreamConstraint x => MkStream m x where type family StreamConstraint x :: Constraint type instance StreamConstraint x = ()
+ ADP.Fusion.GAPlike: class StreamElement x where data family StreamElm x :: * type family StreamTopIdx x :: * type family StreamArg x :: *
+ ADP.Fusion.GAPlike: class TblType tt
+ ADP.Fusion.GAPlike: class TransToN t where type family TransTo t :: *
+ ADP.Fusion.GAPlike: data ArgZ
+ ADP.Fusion.GAPlike: data BTtbl c t g
+ ADP.Fusion.GAPlike: data Chr e
+ ADP.Fusion.GAPlike: data E
+ ADP.Fusion.GAPlike: data Empty
+ ADP.Fusion.GAPlike: data MTbl c es
+ ADP.Fusion.GAPlike: data N
+ ADP.Fusion.GAPlike: data None
+ ADP.Fusion.GAPlike: data RestrictedRegion e
+ ADP.Fusion.GAPlike: data Tbl c es
+ ADP.Fusion.GAPlike: getArg :: StreamElement x => StreamElm x -> StreamArg x
+ ADP.Fusion.GAPlike: getTopIdx :: StreamElement x => StreamElm x -> StreamTopIdx x
+ ADP.Fusion.GAPlike: initDeltaIdx :: TblType tt => tt -> Int
+ ADP.Fusion.GAPlike: instance (Monad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, PrimArrayOps arr DIM2 e, TblType c) => MkStream m (x :. Tbl c (arr DIM2 e))
+ ADP.Fusion.GAPlike: instance (Monad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, Unbox e) => MkStream m (x :. Chr e)
+ ADP.Fusion.GAPlike: instance (Monad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, Unbox e) => MkStream m (x :. RestrictedRegion e)
+ ADP.Fusion.GAPlike: instance (Monad m, MkStream m x, StreamElement x, Unbox e, StreamTopIdx x ~ Int, TblType c) => MkStream m (x :. BTtbl c (Arr0 DIM2 e) (BTfun m b))
+ ADP.Fusion.GAPlike: instance (Monad m, PrimMonad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, MPrimArrayOps marr DIM2 e, TblType c, s ~ PrimState m) => MkStream m (x :. MTbl c (marr s DIM2 e))
+ ADP.Fusion.GAPlike: instance (Monad m, StreamElement x, TblType c) => StreamElement (x :. BTtbl c (Arr0 DIM2 e) (BTfun m b))
+ ADP.Fusion.GAPlike: instance (StreamElement x, MPrimArrayOps marr DIM2 e, TblType c) => StreamElement (x :. MTbl c (marr s DIM2 e))
+ ADP.Fusion.GAPlike: instance (StreamElement x, PrimArrayOps arr DIM2 e, TblType c) => StreamElement (x :. Tbl c (arr DIM2 e))
+ ADP.Fusion.GAPlike: instance Apply ((((((((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) :. j) :. k) :. l) :. m) :. n) :. o) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((((((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) :. j) :. k) :. l) :. m) :. n) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((((((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) :. j) :. k) :. l) :. m) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) :. j) :. k) :. l) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) :. j) :. k) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) :. j) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) :. i) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) :. h) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) :. g) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((((((ArgZ :. a) :. b) :. c) :. d) :. e) :. f) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((((((ArgZ :. a) :. b) :. c) :. d) :. e) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((((ArgZ :. a) :. b) :. c) :. d) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((((ArgZ :. a) :. b) :. c) -> res)
+ ADP.Fusion.GAPlike: instance Apply (((ArgZ :. a) :. b) -> res)
+ ADP.Fusion.GAPlike: instance Apply ((ArgZ :. a) -> res)
+ ADP.Fusion.GAPlike: instance Build (BTtbl c t g)
+ ADP.Fusion.GAPlike: instance Build (Chr e)
+ ADP.Fusion.GAPlike: instance Build (MTbl c es)
+ ADP.Fusion.GAPlike: instance Build (RestrictedRegion e)
+ ADP.Fusion.GAPlike: instance Build (Tbl c es)
+ ADP.Fusion.GAPlike: instance Build Empty
+ ADP.Fusion.GAPlike: instance Build x => Build (x, y)
+ ADP.Fusion.GAPlike: instance Monad m => MkStream m Empty
+ ADP.Fusion.GAPlike: instance Monad m => MkStream m None
+ ADP.Fusion.GAPlike: instance StreamElement Empty
+ ADP.Fusion.GAPlike: instance StreamElement None
+ ADP.Fusion.GAPlike: instance StreamElement x => StreamElement (x :. Chr e)
+ ADP.Fusion.GAPlike: instance StreamElement x => StreamElement (x :. RestrictedRegion e)
+ ADP.Fusion.GAPlike: instance TblType E
+ ADP.Fusion.GAPlike: instance TblType N
+ ADP.Fusion.GAPlike: instance TransToN (BTtbl c t g)
+ ADP.Fusion.GAPlike: instance TransToN (MTbl c es)
+ ADP.Fusion.GAPlike: instance TransToN (Tbl c es)
+ ADP.Fusion.GAPlike: mkStream :: (MkStream m x, StreamConstraint x) => x -> (Int, Int) -> Stream m (StreamElm x)
+ ADP.Fusion.GAPlike: mkStreamInner :: (MkStream m x, StreamConstraint x) => x -> (Int, Int) -> Stream m (StreamElm x)
+ ADP.Fusion.GAPlike: mtblE :: es -> MTbl E es
+ ADP.Fusion.GAPlike: mtblN :: es -> MTbl N es
+ ADP.Fusion.GAPlike: tEtoN :: Tbl E x -> Tbl N x
+ ADP.Fusion.GAPlike: tNtoE :: Tbl N x -> Tbl E x
+ ADP.Fusion.GAPlike: transToN :: TransToN t => t -> TransTo t
+ ADP.Fusion.GAPlike: type BTfun m b = (Int, Int) -> m (Stream m b)
- ADP.Fusion: singlePreStreamGen :: (Monad m, Num head, Ord head) => :. (:. Z head) head -> Stream m (:. (:. Z head) head, Z, Z)
+ ADP.Fusion: singlePreStreamGen :: (Ord head, Num head, Monad m) => (:.) ((:.) Z head) head -> Stream m ((:.) ((:.) Z head) head, Z, Z)
- ADP.Fusion.Monadic: (!-~+) :: (Monad m1, Monad m, Num head1, Num head, Ord head1, Ord head) => xs -> ys -> Box ((:. (:. tail head) head, t, t1) -> m (:. (:. (:. tail head) head) head, t, t1)) ((:. (:. (:. tail1 head2) head1) head1, t2, t3) -> m1 (Step (:. (:. (:. tail1 head2) head1) head1, t2, t3) (:. (:. (:. tail1 head2) head1) head1, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (!-~+) :: (Ord head1, Ord head, Num head1, Num head, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head) head, t, t1) -> m ((:.) ((:.) ((:.) tail head) head) head, t, t1)) (((:.) ((:.) ((:.) tail1 head2) head1) head1, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head2) head1) head1, t2, t3) ((:.) ((:.) ((:.) tail1 head2) head1) head1, t2, t3))) xs ys
- ADP.Fusion.Monadic: (#<<) :: (Apply (t2 -> m b), StreamGen m t3 (t, t1, t2)) => Fun (t2 -> m b) -> t3 -> DIM2 -> Stream m b
+ ADP.Fusion.Monadic: (#<<) :: (StreamGen m t3 (t, t1, t2), Apply (t2 -> m b)) => Fun (t2 -> m b) -> t3 -> DIM2 -> Stream m b
- ADP.Fusion.Monadic: (+~+) :: (Monad m1, Monad m, Num head2, Num head1, Ord head2) => xs -> ys -> Box ((:. (:. tail head1) head, t, t1) -> m (:. (:. (:. tail head1) head1) head, t, t1)) ((:. (:. (:. tail1 head3) head2) head2, t2, t3) -> m1 (Step (:. (:. (:. tail1 head3) head2) head2, t2, t3) (:. (:. (:. tail1 head3) head2) head2, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (+~+) :: (Ord head2, Num head2, Num head1, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head, t, t1)) (((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3) ((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3))) xs ys
- ADP.Fusion.Monadic: (+~-!) :: (Eq head2, Monad m1, Monad m, Num head2, Num head) => xs -> ys -> Box ((:. (:. tail head1) head, t, t1) -> m (:. (:. (:. tail head1) head) head, t, t1)) ((:. (:. (:. tail1 head3) head2) head2, t2, t3) -> m1 (Step (:. (:. (:. tail1 head3) head2) head2, t2, t3) (:. (:. (:. tail1 head3) head2) head2, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (+~-!) :: (Num head2, Num head, Monad m1, Monad m, Eq head2) => xs -> ys -> Box (((:.) ((:.) tail head1) head, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head) head, t, t1)) (((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3) ((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3))) xs ys
- ADP.Fusion.Monadic: (+~-) :: (Monad m1, Monad m, Num head, Num head1, Ord head, Ord head1) => xs -> ys -> Box ((:. (:. tail head1) head1, t, t1) -> m (:. (:. (:. tail head1) head1) head1, t, t1)) ((:. (:. (:. tail1 head2) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head2) head) head, t2, t3) (:. (:. (:. tail1 head2) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (+~-) :: (Ord head1, Ord head, Num head1, Num head, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head1, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head1, t, t1)) (((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3))) xs ys
- ADP.Fusion.Monadic: (+~--) :: (Monad m1, Monad m, Num head, Num head1, Ord head, Ord head1) => xs -> ys -> Box ((:. (:. tail head1) head1, t, t1) -> m (:. (:. (:. tail head1) head1) head1, t, t1)) ((:. (:. (:. tail1 head2) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head2) head) head, t2, t3) (:. (:. (:. tail1 head2) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (+~--) :: (Ord head1, Ord head, Num head1, Num head, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head1, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head1, t, t1)) (((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3))) xs ys
- ADP.Fusion.Monadic: (-~+) :: (Monad m1, Monad m, Num head, Num head1, Ord head) => xs -> ys -> Box ((:. (:. tail head1) head2, t, t1) -> m (:. (:. (:. tail head1) head1) head2, t, t1)) ((:. (:. (:. tail1 head) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head) head) head, t2, t3) (:. (:. (:. tail1 head) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (-~+) :: (Ord head, Num head1, Num head, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head2, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head2, t, t1)) (((:.) ((:.) ((:.) tail1 head) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head) head) head, t2, t3))) xs ys
- ADP.Fusion.Monadic: (-~-) :: (Eq head2, Monad m1, Monad m, Num head2, Num head1) => xs -> ys -> Box ((:. (:. tail head1) head, t, t1) -> m (:. (:. (:. tail head1) head1) head, t, t1)) ((:. (:. (:. tail1 head2) head2) head2, t2, t3) -> m1 (Step (:. (:. (:. tail1 head2) head2) head2, t2, t3) (:. (:. (:. tail1 head2) head2) head2, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (-~-) :: (Num head2, Num head1, Monad m1, Monad m, Eq head2) => xs -> ys -> Box (((:.) ((:.) tail head1) head, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head, t, t1)) (((:.) ((:.) ((:.) tail1 head2) head2) head2, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head2) head2) head2, t2, t3) ((:.) ((:.) ((:.) tail1 head2) head2) head2, t2, t3))) xs ys
- ADP.Fusion.Monadic: (-~~) :: (Monad m1, Monad m, Num head, Num head1, Ord head) => xs -> ys -> Box ((:. (:. tail head1) head2, t, t1) -> m (:. (:. (:. tail head1) head1) head2, t, t1)) ((:. (:. (:. tail1 head) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head) head) head, t2, t3) (:. (:. (:. tail1 head) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (-~~) :: (Ord head, Num head1, Num head, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head2, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head2, t, t1)) (((:.) ((:.) ((:.) tail1 head) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head) head) head, t2, t3))) xs ys
- ADP.Fusion.Monadic: (...) :: (t2 -> t1) -> (t1 -> t) -> t2 -> t
+ ADP.Fusion.Monadic: (...) :: (t1 -> s) -> (s -> t) -> t1 -> t
- ADP.Fusion.Monadic: (..@) :: (t2 -> t1) -> (t2 -> t1 -> t) -> t2 -> t
+ ADP.Fusion.Monadic: (..@) :: (t1 -> s) -> (t1 -> s -> t) -> t1 -> t
- ADP.Fusion.Monadic: (<<<) :: (Apply (t2 -> b), StreamGen m t3 (t, t1, t2)) => Fun (t2 -> b) -> t3 -> DIM2 -> Stream m b
+ ADP.Fusion.Monadic: (<<<) :: (StreamGen m t3 (t, t1, t2), Apply (t2 -> b)) => Fun (t2 -> b) -> t3 -> DIM2 -> Stream m b
- ADP.Fusion.Monadic: (~~-) :: (Monad m1, Monad m, Num head, Num head1, Ord head, Ord head1) => xs -> ys -> Box ((:. (:. tail head1) head1, t, t1) -> m (:. (:. (:. tail head1) head1) head1, t, t1)) ((:. (:. (:. tail1 head2) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head2) head) head, t2, t3) (:. (:. (:. tail1 head2) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (~~-) :: (Ord head1, Ord head, Num head1, Num head, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head1, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head1, t, t1)) (((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3))) xs ys
- ADP.Fusion.Monadic: (~~~) :: (Monad m1, Monad m, Num head2, Ord head2) => xs -> ys -> Box ((:. (:. tail head1) head, t, t1) -> m (:. (:. (:. tail head1) head1) head, t, t1)) ((:. (:. (:. tail1 head3) head2) head2, t2, t3) -> m1 (Step (:. (:. (:. tail1 head3) head2) head2, t2, t3) (:. (:. (:. tail1 head3) head2) head2, t2, t3))) xs ys
+ ADP.Fusion.Monadic: (~~~) :: (Ord head2, Num head2, Monad m1, Monad m) => xs -> ys -> Box (((:.) ((:.) tail head1) head, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head, t, t1)) (((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3) ((:.) ((:.) ((:.) tail1 head3) head2) head2, t2, t3))) xs ys
- ADP.Fusion.Monadic: makeLeft_MinRight :: (Monad m, Monad m1, Num head1, Num head, Ord head) => (head1, head) -> head -> xs -> ys -> Box ((:. (:. tail head1) head2, t, t1) -> m (:. (:. (:. tail head1) head1) head2, t, t1)) ((:. (:. (:. tail1 head) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head) head) head, t2, t3) (:. (:. (:. tail1 head) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: makeLeft_MinRight :: (Ord head, Num head1, Num head, Monad m1, Monad m) => (head1, head) -> head -> xs -> ys -> Box (((:.) ((:.) tail head1) head2, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head2, t, t1)) (((:.) ((:.) ((:.) tail1 head) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head) head) head, t2, t3))) xs ys
- ADP.Fusion.Monadic: makeMinLeft_Right :: (Monad m, Monad m1, Num head1, Num head, Ord head1, Ord head) => head1 -> (head, head1) -> xs -> ys -> Box ((:. (:. tail head1) head1, t, t1) -> m (:. (:. (:. tail head1) head1) head1, t, t1)) ((:. (:. (:. tail1 head2) head) head, t2, t3) -> m1 (Step (:. (:. (:. tail1 head2) head) head, t2, t3) (:. (:. (:. tail1 head2) head) head, t2, t3))) xs ys
+ ADP.Fusion.Monadic: makeMinLeft_Right :: (Ord head1, Ord head, Num head1, Num head, Monad m1, Monad m) => head1 -> (head, head1) -> xs -> ys -> Box (((:.) ((:.) tail head1) head1, t, t1) -> m ((:.) ((:.) ((:.) tail head1) head1) head1, t, t1)) (((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) -> m1 (Step ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3) ((:.) ((:.) ((:.) tail1 head2) head) head, t2, t3))) xs ys

Files

+ ADP/Fusion/GAPlike.hs view
@@ -0,0 +1,571 @@+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PackageImports #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++-- | +--+-- HINTS for writing your own (Non-) terminals:+--+-- - ALWAYS provide types for local functions of 'mkStream' and+-- 'mkStreamInner'. Otherwise stream-fusion gets confused and doesn't optimize.+-- (Observable in core by looking for 'Left', 'RIght' constructors and 'SPEC'+-- constructors.++module ADP.Fusion.GAPlike where++import Control.Monad.Primitive+import Data.Primitive.Types (Prim(..))+import Data.Vector.Fusion.Stream.Size+import GHC.Prim (Constraint)+import qualified Data.Vector.Fusion.Stream.Monadic as S+import qualified Data.Vector.Unboxed as VU++import Data.PrimitiveArray (PrimArrayOps(..), MPrimArrayOps(..))+import "PrimitiveArray" Data.Array.Repa.Index+import qualified Data.PrimitiveArray as PA+import qualified Data.PrimitiveArray.Zero.Unboxed as ZU++++-- * The required type classes. Each class does its own thing.++-- | The 'Build' class. Combines the arguments into a stack before they are+-- turned into a stream.+--+--+--+-- To use, simply write "instance Build MyDataCtor" as we have sensible default+-- instances.++class Build x where+  -- | The stack of arguments we are building.+  type BuildStack x :: *+  -- | The default is for the left-most element.+  type BuildStack x = None :. x+  -- | Given an element, create the stack.+  build :: x -> BuildStack x+  -- | Default for the left-most element.+  default build :: (BuildStack x ~ (None :. x)) => x -> BuildStack x+  build x = None :. x+  {-# INLINE build #-}++-- | The stream element. Creates a type-level recursive data type containing+-- the extracted arguments.++class StreamElement x where+  -- | one element of the stream, recursively defined+  data StreamElm x :: *+  -- | top-most index of the stream -- typically int+  type StreamTopIdx  x :: *+  -- | complete, recursively defined argument of the stream+  type StreamArg  x :: *+  -- | Given a stream element, we extract the top-most idx+  getTopIdx :: StreamElm x -> StreamTopIdx x+  -- | extract the recursively defined argument in a well-defined way for 'apply'+  getArg :: StreamElm x -> StreamArg x++-- | Given the arguments, creates a stream of 'StreamElement's.++class (StreamConstraint x) => MkStream m x where+  type StreamConstraint x :: Constraint+  type StreamConstraint x = ()+  mkStream      :: (StreamConstraint x) => x -> (Int,Int) -> S.Stream m (StreamElm x)+  mkStreamInner :: (StreamConstraint x) => x -> (Int,Int) -> S.Stream m (StreamElm x)++++-- * Terminates the stack of arguments++-- | Very simple data ctor++data None = None++-- | For CORE-language, we have our own Arg-terminator++data ArgZ = ArgZ++instance StreamElement None where+  data StreamElm None    = SeNone !Int+  type StreamTopIdx None = Int+  type StreamArg    None = ArgZ+  getTopIdx (SeNone k) = k+  getArg _ = ArgZ+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++instance (Monad m) => MkStream m None where+  mkStream None (i,j) = S.unfoldr step i where+    step k+      | k<=j = Just (SeNone i, j+1)+      | otherwise = Nothing+    {-# INLINE step #-}+  {-# INLINE mkStream #-}+  mkStreamInner = mkStream+  {-# INLINE mkStreamInner #-}++++-- * A single character terminal. Using unboxed vector to hold the input. Note+-- that "character" means parsing a scalar, not that the 'Chr' parser only+-- accepts "Char"s.++data Chr e = Chr !(VU.Vector e)++instance Build (Chr e)++instance (StreamElement x) => StreamElement (x:.Chr e) where+  data StreamElm (x:.Chr e) = SeChr !(StreamElm x) !Int !e+  type StreamTopIdx (x:.Chr e) = Int+  type StreamArg (x:.Chr e) = StreamArg x :. e+  getTopIdx (SeChr _ k _) = k+  getArg (SeChr x _ e) = getArg x :. e+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++-- TODO I think, we can rewrite both versions to use S.map instead of S.flatten.++instance (Monad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, VU.Unbox e) => MkStream m (x:.Chr e) where+  mkStream (x:.Chr es) (i,j) = S.flatten mk step Unknown $ mkStream x (i,j-1) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x)+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.Chr e)))+    step (x,k)+      | k+1 == j = return $ S.Yield (SeChr x (k+1) (VU.unsafeIndex es k)) (x,j+1)+      | otherwise = return S.Done+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStream #-}+  mkStreamInner (x:.Chr es) (i,j) = S.flatten mk step Unknown $ mkStreamInner x (i,j-1) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x)+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.Chr e)))+    step (x,k)+      | k < j     = return $ S.Yield (SeChr x (k+1) (VU.unsafeIndex es k)) (x,j+1)+      | otherwise = return $ S.Done+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStreamInner #-}++++-- * Empty and non-empty tables.+--+-- TODO This will probably become more funny with triangular tables ...++-- | empty subwords allowed++data E++-- | only non-empty subwords++data N++class TransToN t where+  type TransTo t :: *+  transToN :: t -> TransTo t++-- | Used by the instances below for index calculations.++class TblType tt where+  initDeltaIdx :: tt -> Int++instance TblType E where+  initDeltaIdx _ = 0+  {-# INLINE initDeltaIdx #-}++instance TblType N where+  initDeltaIdx _ = 1+  {-# INLINE initDeltaIdx #-}++-- ** Immutable tables++data Tbl c es = Tbl !es++instance TransToN (Tbl c es) where+  type TransTo (Tbl c es) = Tbl N es+  transToN (Tbl es) = Tbl es+  {-# INLINE transToN #-}++instance Build (Tbl c es)++instance (StreamElement x, PrimArrayOps arr DIM2 e, TblType c) => StreamElement (x:.Tbl c (arr DIM2 e)) where+  data StreamElm    (x:.Tbl c (arr DIM2 e)) = SeTbl !(StreamElm x) !Int !e+  type StreamTopIdx (x:.Tbl c (arr DIM2 e)) = Int+  type StreamArg    (x:.Tbl c (arr DIM2 e)) = StreamArg x :. e+  getTopIdx (SeTbl _ k _) = k+  getArg    (SeTbl x _ e) = getArg x :. e+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++instance (Monad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, PrimArrayOps arr DIM2 e, TblType c) => MkStream m (x:.Tbl c (arr DIM2 e)) where+  -- | The outer stream function assumes that mkStreamInner generates a valid+  -- stream that does not need to be checked. (This should always be true!).+  -- The table entry to read is [k,j], as we supposedly are generating the+  -- outermost stream. Even more "outermost" streams will have changed 'j'+  -- beforehand. 'mkStream' should only ever be used if 'j' can be fixed.+  mkStream (x:.Tbl t) (i,j) = S.map step $ mkStreamInner x (i,j - initDeltaIdx (undefined :: c)) where+    step :: StreamElm x -> StreamElm (x:.Tbl c (arr DIM2 e))+    step x = let k = getTopIdx x in SeTbl x j (t PA.! (Z:.k:.j))+    {-# INLINE step #-}+  -- | The inner stream will, in each step, check if the current subword [k,l]+  -- (forall l>=k) is valid and terminate the stream once l>j.+  mkStreamInner (x:.Tbl t) (i,j) = S.flatten mk step Unknown $ mkStreamInner x (i,j) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x + initDeltaIdx (undefined :: c))+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.Tbl c (arr DIM2 e))))+    step (x,l)+      | l<=j      = return $ S.Yield (SeTbl x l (t PA.! (Z:.k:.l))) (x,l+1)+      | otherwise = return $ S.Done+      where k = getTopIdx x+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStream #-}+  {-# INLINE mkStreamInner #-}++-- ** Mutable tables in some monad.++data MTbl c es = MTbl !es++instance TransToN (MTbl c es) where+  type TransTo (MTbl c es) = MTbl N es+  transToN (MTbl es) = MTbl es+  {-# INLINE transToN #-}++mtblN :: es -> MTbl N es+mtblN es = MTbl es+{-# INLINE mtblN #-}++mtblE :: es -> MTbl E es+mtblE es = MTbl es+{-# INLINE mtblE #-}++instance Build (MTbl c es)++instance (StreamElement x, MPrimArrayOps marr DIM2 e, TblType c) => StreamElement (x:.MTbl c (marr s DIM2 e)) where+  data StreamElm    (x:.MTbl c (marr s DIM2 e)) = SeMTbl !(StreamElm x) !Int !e+  type StreamTopIdx (x:.MTbl c (marr s DIM2 e)) = Int+  type StreamArg    (x:.MTbl c (marr s DIM2 e)) = StreamArg x :. e+  getTopIdx (SeMTbl _ k _) = k+  getArg    (SeMTbl x _ e) = getArg x :. e+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++instance+  ( Monad m+  , PrimMonad m+  , MkStream m x+  , StreamElement x+  , StreamTopIdx x ~ Int+  , MPrimArrayOps marr DIM2 e+  , TblType c+  , s ~ PrimState m+  ) => MkStream m (x:.MTbl c (marr s DIM2 e)) where+  -- | The outer stream function assumes that mkStreamInner generates a valid+  -- stream that does not need to be checked. (This should always be true!).+  -- The table entry to read is [k,j], as we supposedly are generating the+  -- outermost stream. Even more "outermost" streams will have changed 'j'+  -- beforehand. 'mkStream' should only ever be used if 'j' can be fixed.+  mkStream (x:.MTbl t) (i,j) = S.mapM step $ mkStreamInner x (i,j - initDeltaIdx (undefined :: c)) where+    step :: StreamElm x -> m (StreamElm (x:.MTbl c (marr s DIM2 e)))+    step x = let k = getTopIdx x in PA.readM t (Z:.k:.j) >>= \e -> return $ SeMTbl x j e+    {-# INLINE step #-}+  -- | The inner stream will, in each step, check if the current subword [k,l]+  -- (forall l>=k) is valid and terminate the stream once l>j.+  mkStreamInner (x:.MTbl t) (i,j) = S.flatten mk step Unknown $ mkStreamInner x (i,j) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x + initDeltaIdx (undefined :: c))+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.MTbl c (marr s DIM2 e))))+    step (x,l)+      | l<=j      = readM t (Z:.k:.l) >>= \e -> return $ S.Yield (SeMTbl x l e) (x,l+1)+      | otherwise = return $ S.Done+      where k = getTopIdx x+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStream #-}+  {-# INLINE mkStreamInner #-}++-- ** Some convenience functions.++tNtoE :: Tbl N x -> Tbl E x+tNtoE (Tbl x) = Tbl x+{-# INLINE tNtoE #-}++tEtoN :: Tbl E x -> Tbl N x+tEtoN (Tbl x) = Tbl x+{-# INLINE tEtoN #-}++++-- * Parses an empty subword.++-- | The empty subword. Can not be part of a more complex RHS for obvious+-- reasons: "S -> E S" doesn't make sense. Used in some grammars as the base+-- case.++data Empty = Empty++instance Build Empty where+  type BuildStack Empty = Empty+  build c = c+  {-# INLINE build #-}++instance StreamElement (Empty) where+  data StreamElm    Empty = SeEmpty !Int+  type StreamTopIdx Empty = Int+  type StreamArg    Empty = ArgZ :. ()+  getTopIdx (SeEmpty k) = k+  getArg    (SeEmpty _) = ArgZ :. ()+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++instance (Monad m) => MkStream m (Empty) where+  mkStream Empty (i,j) = S.unfoldr step i where+    step k+      | k==j      = Just (SeEmpty k, j+1)+      | otherwise = Nothing+    {-# INLINE step #-}+  mkStreamInner = error "undefined for Empty"+  {-# INLINE mkStream #-}+  {-# INLINE mkStreamInner #-}++++-- * Parsing subwords with restriced size. Both min- and max-size are given+-- when binding input.++data RestrictedRegion e = RRegion !Int !Int !(VU.Vector e)++instance Build (RestrictedRegion e)++instance (StreamElement x) => StreamElement (x:.RestrictedRegion e) where+  data StreamElm (x:.RestrictedRegion e) = SeResRegion !(StreamElm x) !Int (VU.Vector e)+  type StreamTopIdx (x:.RestrictedRegion e) = Int+  type StreamArg (x:.RestrictedRegion e) = StreamArg x :. (VU.Vector e)+  getTopIdx (SeResRegion _ k _) = k+  getArg (SeResRegion x _ e) = getArg x :. e+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++instance (Monad m, MkStream m x, StreamElement x, StreamTopIdx x ~ Int, VU.Unbox e) => MkStream m (x:.RestrictedRegion e) where+  mkStream (x:.RRegion minR maxR xs) (i,j) = S.flatten mk step Unknown $ mkStream x (i,j-1) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x)+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.RestrictedRegion e)))+    step (x,k)+      | k+minR <= j && k+maxR >= j = return $ S.Yield (SeResRegion x k (VU.unsafeSlice k (max maxR (j-k)) xs)) (x,j+1)+      | otherwise = return S.Done+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStream #-}+  mkStreamInner (x:.RRegion minR maxR xs) (i,j) = S.flatten mk step Unknown $ mkStream x (i,j) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x + minR)+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.RestrictedRegion e)))+    step (x,l)+      | l<=j && (l-k)<=maxR = return $ S.Yield (SeResRegion x l (VU.unsafeSlice k (l-k) xs)) (x,j+1)+      | otherwise           = return S.Done+      where k = getTopIdx x+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStreamInner #-}++++-- * Backtracking tables.+--+-- Since we want the slow forward phase to be fast, in the backtracking phase,+-- we need to keep track of additional things. The backtracking table 'BTtbl'+-- requires the table and an additional backtracking function. You should use+-- the same composed function as for the forward pahse creating the bound table+-- in the first place.++-- | The backtracking table 'BTtbl" captures a DP table and the function used+-- to fill it.++data BTtbl c t g = BTtbl t g++instance TransToN (BTtbl c t g) where+  type TransTo (BTtbl c t g) = BTtbl N t g+  transToN (BTtbl t g) = BTtbl t g+  {-# INLINE transToN #-}++bttblN :: t -> g -> BTtbl N t g+bttblN t g = BTtbl t g+{-# INLINE bttblN #-}++bttblE :: t -> g -> BTtbl E t g+bttblE t g = BTtbl t g+{-# INLINE bttblE #-}++instance Build (BTtbl c t g)++-- | The backtracking function, given our index pair, return a stream of+-- backtracked results. (Return as in we are in a monad).+--+-- TODO Should this be "(Int,Int) -> m (SM.Stream Id b)" or are there cases+-- where we'd like to have monadic effects on the "b"s?++type BTfun m b = (Int,Int) -> m (S.Stream m b)++instance (Monad m, StreamElement x, TblType c) => StreamElement (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b)) where+  data StreamElm    (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b)) = SeBTtbl !(StreamElm x) !Int !e (m (S.Stream m b))+  type StreamTopIdx (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b)) = Int+  type StreamArg    (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b)) = StreamArg x :. (e, m (S.Stream m b))+  getTopIdx (SeBTtbl _ k _ _) = k+  getArg    (SeBTtbl x _ e g) = getArg x :. (e,g)+  {-# INLINE getTopIdx #-}+  {-# INLINE getArg #-}++instance+  ( Monad m+  , MkStream m x+  , StreamElement x+  , VU.Unbox e+  , StreamTopIdx x ~ Int+  , TblType c+  ) => MkStream m (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b)) where+  mkStream (x:.BTtbl t g) (i,j) = S.map step $ mkStreamInner x (i,j - initDeltaIdx (undefined :: c)) where+    step :: StreamElm x -> StreamElm (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b))+    step x = let k = getTopIdx x in SeBTtbl x j (t PA.! (Z:.k:.j)) (g (k,j))+    {-# INLINE step #-}+  mkStreamInner (x:.BTtbl t g) (i,j) = S.flatten mk step Unknown $ mkStreamInner x (i,j) where+    mk :: StreamElm x -> m (StreamElm x, Int)+    mk x = return (x, getTopIdx x + initDeltaIdx (undefined :: c))+    step :: (StreamElm x, Int) -> m (S.Step (StreamElm x, Int) (StreamElm (x:.BTtbl c (ZU.Arr0 DIM2 e) (BTfun m b))))+    step (x,l)+      | l<=j      = return $ S.Yield (SeBTtbl x l (t PA.! (Z:.k:.l)) (g (k,l))) (x,l+1)+      | otherwise = return $ S.Done+      where k = getTopIdx x+    {-# INLINE mk #-}+    {-# INLINE step #-}+  {-# INLINE mkStream #-}+  {-# INLINE mkStreamInner #-}++++-- * Build complex stacks++instance Build x => Build (x,y) where+  type BuildStack (x,y) = BuildStack x :. y+  build (x,y) = build x :. y+  {-# INLINE build #-}++++-- * combinators++infixl 8 <<<+(<<<) f t ij = S.map (\s -> apply f $ getArg s) $ mkStream (build t) ij+{-# INLINE (<<<) #-}++infixl 7 |||+(|||) xs ys ij = xs ij S.++ ys ij+{-# INLINE (|||) #-}++infixl 6 ...+(...) s h ij = h $ s ij+{-# INLINE (...) #-}++infixl 6 ..@+(..@) s h ij = h ij $ s ij+{-# INLINE (..@) #-}++infixl 9 ~~+(~~) = (,)+{-# INLINE (~~) #-}++infixl 9 %+(%) = (,)+{-# INLINE (%) #-}++++-- * Apply function 'f' in '(<<<)'++class Apply x where+  type Fun x :: *+  apply :: Fun x -> x++instance Apply (ArgZ:.a -> res) where+  type Fun (ArgZ:.a -> res) = a -> res+  apply fun (ArgZ:.a) = fun a+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b -> res) where+  type Fun (ArgZ:.a:.b -> res) = a->b -> res+  apply fun (ArgZ:.a:.b) = fun a b+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c -> res) where+  type Fun (ArgZ:.a:.b:.c -> res) = a->b->c -> res+  apply fun (ArgZ:.a:.b:.c) = fun a b c+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d -> res) where+  type Fun (ArgZ:.a:.b:.c:.d -> res) = a->b->c->d -> res+  apply fun (ArgZ:.a:.b:.c:.d) = fun a b c d+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e -> res) = a->b->c->d->e -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e) = fun a b c d e+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f -> res) = a->b->c->d->e->f -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f) = fun a b c d e f+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g -> res) = a->b->c->d->e->f->g -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g) = fun a b c d e f g+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h -> res) = a->b->c->d->e->f->g->h -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h) = fun a b c d e f g h+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i -> res) = a->b->c->d->e->f->g->h->i -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i) = fun a b c d e f g h i+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j -> res) = a->b->c->d->e->f->g->h->i->j -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j) = fun a b c d e f g h i j+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k -> res) = a->b->c->d->e->f->g->h->i->j->k -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k) = fun a b c d e f g h i j k+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l -> res) = a->b->c->d->e->f->g->h->i->j->k->l -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l) = fun a b c d e f g h i j k l+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m -> res) = a->b->c->d->e->f->g->h->i->j->k->l->m -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m) = fun a b c d e f g h i j k l m+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m:.n -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m:.n -> res) = a->b->c->d->e->f->g->h->i->j->k->l->m->n -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m:.n) = fun a b c d e f g h i j k l m n+  {-# INLINE apply #-}++instance Apply (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m:.n:.o -> res) where+  type Fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m:.n:.o -> res) = a->b->c->d->e->f->g->h->i->j->k->l->m->n->o -> res+  apply fun (ArgZ:.a:.b:.c:.d:.e:.f:.g:.h:.i:.j:.k:.l:.m:.n:.o) = fun a b c d e f g h i j k l m n o+  {-# INLINE apply #-}+
+ ADP/Fusion/GAPlike/Criterion.hs view
@@ -0,0 +1,179 @@+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE PackageImports #-}++module ADP.Fusion.GAPlike.Criterion where++import Control.Monad.ST+import Criterion.Main+import Data.Char+import qualified Data.Vector.Fusion.Stream.Monadic as S+import qualified Data.Vector.Fusion.Stream as SP++import Data.PrimitiveArray+import Data.PrimitiveArray.Unboxed.VectorZero as UVZ+import Data.PrimitiveArray.Unboxed.Zero as UZ+import "PrimitiveArray" Data.Array.Repa.Index+import "PrimitiveArray" Data.Array.Repa.Shape++import ADP.Fusion.GAPlike+import ADP.Fusion.GAPlike.DevelCommon++++criterionMain = defaultMain+  [ bgroup "testTTT3"+    [ bench "  10" (whnf (testTTT 0)   10)+    , bench " 100" (whnf (testTTT 0)  100)+    , bench "1000" (whnf (testTTT 0) 1000)+    ]+  , bgroup "testTTTT4"+    [ bench "  10" (whnf (testTTTT 0)   10)+    , bench " 100" (whnf (testTTTT 0)  100)+    , bench "1000" (whnf (testTTTT 0) 1000)+    ]+  , bgroup "testTTTT4ga"+    [ bench "  10" (whnf (testTTTTga 0)   10)+    , bench " 100" (whnf (testTTTTga 0)  100)+    , bench "1000" (whnf (testTTTTga 0) 1000)+    ]+  , bgroup "testTTTT4gaPA"+    [ bench "  10" (whnf (testTTTTgaPA 0)   10)+    , bench " 100" (whnf (testTTTTgaPA 0)  100)+    , bench "1000" (whnf (testTTTTgaPA 0) 1000)+    ]+  , bgroup "testTTTT4gaImmu"+    [ bench "  10" (whnf (testTTTTgaImmu 0)   10)+    , bench " 100" (whnf (testTTTTgaImmu 0)  100)+    , bench "1000" (whnf (testTTTTgaImmu 0) 1000)+    ]+  , bgroup "testTTTT4gaImmuPA"+    [ bench "  10" (whnf (testTTTTgaImmuPA 0)   10)+    , bench " 100" (whnf (testTTTTgaImmuPA 0)  100)+    , bench "1000" (whnf (testTTTTgaImmuPA 0) 1000)+    ]+  ]++++-- * Criterion tests++testC :: Int -> Int -> Int+testC i j = runST doST where+  doST :: ST s Int+  doST = do+    let c = Chr dvu+    (gord1 <<< c ... ghsum) (i,j)+{-# NOINLINE testC #-}++gTestC (ord1,hsum) c =+  (ord1 <<< c ... hsum)++aTestC = (ord1,hsum) where+  ord1 = gord1+  hsum = ghsum++testCC :: Int -> Int -> Int+testCC i j = runST doST where+  doST :: ST s Int+  doST = do+    let c = Chr dvu+    let d = Chr dvu+    (gord2 <<< c % d ... ghsum) (i,j)+{-# NOINLINE testCC #-}++type TBL s = Tbl N (UVZ.MArr0 s DIM2 Int)++testT :: Int -> Int -> Int+testT i j = runST doST where+  doST :: ST s Int+  doST = do+    tbl :: TBL s <- Tbl `fmap` fromAssocsM (Z:.0:.0) (Z:.j:.j) 1 []+    (id <<< tbl ... ghsum) (i,j)+{-# NOINLINE testT #-}++testTT :: Int -> Int -> Int+testTT i j = runST doST where+  doST :: ST s Int+  doST = do+    tbl :: TBL s <- Tbl `fmap` fromAssocsM (Z:.0:.0) (Z:.j:.j) 1 []+    (gplus2 <<< tbl % tbl ... ghsum) (i,j)+  {-# INLINE doST #-}+{-# NOINLINE testTT #-}++testTTT :: Int -> Int -> Int+testTTT i j = runST doST where+  doST :: ST s Int+  doST = do+    tbl :: TBL s <- Tbl `fmap` fromAssocsM (Z:.0:.0) (Z:.j:.j) 1 []+    (gplus3 <<< tbl % tbl % tbl ... ghsum) (i,j)+{-# NOINLINE testTTT #-}++testTTTT :: Int -> Int -> Int+testTTTT i j = runST doST where+  doST :: ST s Int+  doST = do+    tbl :: TBL s <- Tbl `fmap` fromAssocsM (Z:.0:.0) (Z:.j:.j) (1::Int) []+    (gplus4 <<< tbl % tbl % tbl % tbl ... ghsum) (i,j)+  {-# INLINE doST #-}+{-# NOINLINE testTTTT #-}++testTTTTga :: Int -> Int -> Int+testTTTTga i j = runST doST where+  doST :: ST s Int+  doST = do+    tbl :: TBL s <- Tbl `fmap` fromAssocsM (Z:.0:.0) (Z:.j:.j) (1::Int) []+    gTTTga aTTTga tbl (i,j)+  {-# INLINE doST #-}+{-# NOINLINE testTTTTga #-}++testTTTTgaPA :: Int -> Int -> Int+testTTTTgaPA i j = runST doST where+  doST :: ST s Int+  doST = do+    tbl :: Tbl N (UZ.MArr0 s DIM2 Int) <- Tbl `fmap` fromAssocsM (Z:.0:.0) (Z:.j:.j) (1::Int) []+    gTTTga aTTTga tbl (i,j)+  {-# INLINE doST #-}+{-# NOINLINE testTTTTgaPA #-}++testTTTTgaImmu :: Int -> Int -> Int+testTTTTgaImmu i j =+    let tbl = (Tbl $ fromAssocs (Z:.0:.0) (Z:.j:.j) 1 []) :: Tbl N (UVZ.Arr0 DIM2 Int) +    in tbl `seq` gTTTga aTTTgaImmu tbl (i,j)+{-# NOINLINE testTTTTgaImmu #-}++testTTTTgaImmuPA :: Int -> Int -> Int+testTTTTgaImmuPA i j =+    let tbl = (Tbl $ fromAssocs (Z:.0:.0) (Z:.j:.j) 1 []) :: Tbl N (UZ.Arr0 DIM2 Int) +    in tbl `seq` gTTTga aTTTgaImmu tbl (i,j)+{-# NOINLINE testTTTTgaImmuPA #-}++gTTTga (plus4, hsum) tbl =+  (plus4 <<< tbl % tbl % tbl % tbl ... hsum)+{-# INLINE gTTTga #-}++aTTTga = (plus4, hsum) where+  plus4 = gplus4+  hsum = ghsum++aTTTgaImmu = (plus4, hsum) where+  plus4 = gplus4+  hsum = gihsum+{-# INLINE aTTTgaImmu #-}++gord1 a = ord a++gord2 a b = ord a + ord b++gord3 a b c = ord a + ord b + ord c++gplus2 a b = a+b++gplus3 a b c = a+b+c++gplus4 a b c d = a+b+c+d++ghsum :: S.Stream (ST s) Int -> ST s Int+ghsum = S.foldl' (+) 0++gihsum :: SP.Stream Int -> Int+gihsum = SP.foldl' (+) 0
+ ADP/Fusion/GAPlike/DevelCommon.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE PackageImports #-}++module ADP.Fusion.GAPlike.DevelCommon where++import qualified Data.PrimitiveArray as PA+import qualified Data.Vector.Unboxed as VU++import Data.PrimitiveArray.Unboxed.VectorZero as UVZ+import Data.PrimitiveArray.Unboxed.Zero as UZ+import "PrimitiveArray" Data.Array.Repa.Index+import "PrimitiveArray" Data.Array.Repa.Shape++++dvu = VU.fromList $ concat $ replicate 10 ['a'..'z']+{-# NOINLINE dvu #-}++type PAT = UVZ.Arr0 DIM2 Int+pat :: PAT+pat = PA.fromAssocs (Z:.0:.0) (Z:.1000:.1000) 0 [(Z:.i:.j,j-i) | i <-[0..1000], j<-[i..1000] ]+{-# NOINLINE pat #-}+
+ ADP/Fusion/GAPlike/QuickCheck.hs view
@@ -0,0 +1,57 @@+{-# LANGUAGE PackageImports #-}+{-# LANGUAGE TemplateHaskell #-}++module ADP.Fusion.GAPlike.QuickCheck where++import Test.QuickCheck+import Test.QuickCheck.All+import qualified Data.Vector.Fusion.Stream as SP+import qualified Data.Vector.Unboxed as VU++import "PrimitiveArray" Data.Array.Repa.Index+import "PrimitiveArray" Data.Array.Repa.Shape+import Data.PrimitiveArray++import ADP.Fusion.QuickCheck.Arbitrary+import ADP.Fusion.GAPlike.DevelCommon+import ADP.Fusion.GAPlike++++-- * QuickCheck++checkC_fusion (i,j) = id <<< Chr dvu ... SP.toList $ (i,j)+checkC_list   (i,j) = [dvu VU.! i | i+1==j]+prop_checkC = checkC_fusion === checkC_list++checkCC_fusion (i,j) = (,) <<< Chr dvu % Chr dvu ... SP.toList $ (i,j)+checkCC_list   (i,j) = [ (dvu VU.! i, dvu VU.! (i+1)) | i+2==j ]+prop_checkCC = checkCC_fusion === checkCC_list++checkP_fusion (i,j) = id <<< (Tbl pat :: Tbl E PAT)  ... SP.toList $ (i,j)+checkP_list   (i,j) = [ (pat!(Z:.i:.j)) | i<=j ]+prop_checkP = checkP_fusion === checkP_list++checkPP_fusion (i,j) = let tbl = Tbl pat :: Tbl E PAT+                       in  (,) <<< tbl % tbl ... SP.toList $ (i,j)+checkPP_list   (i,j) = [ (pat!(Z:.i:.k), pat!(Z:.k:.j)) | k<-[i..j] ]+prop_checkPP = checkPP_fusion === checkPP_list++checkCPC_fusion (i,j) = let tbl = Tbl pat :: Tbl E PAT+                        in  (,,) <<< Chr dvu % tbl % Chr dvu ... SP.toList $ (i,j)+checkCPC_list (i,j) = [ (dvu VU.! i, pat!(Z:.i+1:.j-1), dvu VU.! (j-1)) | i+2<=j ]+prop_checkCPC = checkCPC_fusion === checkCPC_list++checkNN_fusion (i,j) = let tbl = Tbl pat :: Tbl N PAT+                       in  (,) <<< tbl % tbl ... SP.toList $ (i,j)+checkNN_list   (i,j) = [ (pat!(Z:.i:.k), pat!(Z:.k:.j)) | k<-[i+1..j-1] ]+prop_checkNN = checkNN_fusion === checkNN_list++++options = stdArgs {maxSuccess = 1000}++customCheck = quickCheckWithResult options++allProps = $forAllProperties customCheck+
ADP/Fusion/Monadic/Internal.hs view
@@ -39,7 +39,7 @@ import Text.Printf  import qualified Data.PrimitiveArray as PA-import qualified Data.PrimitiveArray.Unboxed.Zero as UZ+import qualified Data.PrimitiveArray.Zero.Unboxed as ZU import qualified Data.PrimitiveArray.Zero as Z  @@ -62,8 +62,8 @@ mkStreamGen(DIM2 -> ScalarM elm) mkStreamGen(DIM2 -> Vect elm) mkStreamGen(DIM2 -> VectM elm)-mkStreamGen(UZ.MArr0 s sh elm)-mkStreamGen(UZ.Arr0 sh elm)+mkStreamGen(ZU.MArr0 s sh elm)+mkStreamGen(ZU.Arr0 sh elm)  mkStreamGen(Z.MArr0 s sh (VU.Vector elm)) mkStreamGen(Z.Arr0 sh (VU.Vector elm))@@ -114,8 +114,8 @@ mkPreStreamGen(DIM2 -> ScalarM elm) mkPreStreamGen(DIM2 -> Vect elm) mkPreStreamGen(DIM2 -> VectM elm)-mkPreStreamGen(UZ.MArr0 s sh elm)-mkPreStreamGen(UZ.Arr0 sh elm)+mkPreStreamGen(ZU.MArr0 s sh elm)+mkPreStreamGen(ZU.Arr0 sh elm)  mkPreStreamGen(Z.MArr0 s sh (VU.Vector elm)) mkPreStreamGen(Z.Arr0 sh (VU.Vector elm))@@ -178,12 +178,12 @@  instance   ( PrimMonad m-  , Prim elm+  , VU.Unbox elm   , PrimState m ~ s   , DIM2 ~ sh-  ) => ExtractValue m (UZ.MArr0 s sh elm) where-  type Asor (UZ.MArr0 s sh elm) = Z-  type Elem (UZ.MArr0 s sh elm) = elm+  ) => ExtractValue m (ZU.MArr0 s sh elm) where+  type Asor (ZU.MArr0 s sh elm) = Z+  type Elem (ZU.MArr0 s sh elm) = elm   extractValue cnt ij z = do     x <- PA.readM cnt ij     x `seq` return x@@ -203,11 +203,11 @@  instance   ( Monad m-  , Prim elm+  , VU.Unbox elm   , DIM2 ~ sh-  ) => ExtractValue m (UZ.Arr0 sh elm) where-  type Asor (UZ.Arr0 sh elm) = Z-  type Elem (UZ.Arr0 sh elm) = elm+  ) => ExtractValue m (ZU.Arr0 sh elm) where+  type Asor (ZU.Arr0 sh elm) = Z+  type Elem (ZU.Arr0 sh elm) = elm   extractValue cnt ij z = do     let x = PA.index cnt ij     x `seq` return x
ADPfusion.cabal view
@@ -1,5 +1,5 @@ name:           ADPfusion-version:        0.0.1.2+version:        0.1.0.0 author:         Christian Hoener zu Siederdissen, 2011-2012 copyright:      Christian Hoener zu Siederdissen, 2011-2012 homepage:       http://www.tbi.univie.ac.at/~choener/adpfusion@@ -31,10 +31,27 @@                 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).+                As a simple benchmark, consider the Nussinov78 algorithm which+                translates to three nested for loops (for C). In the figure,+                four different approaches are compared using inputs with size+                100 characters to 1000 characters in increments of 100+                characters. "C" is an implementation ("./C/" directory) in "C"+                using "gcc -O3". "ADP" is the original ADP approach (see link+                above), while "GAPC" uses the "GAP" language+                (<http://gapc.eu/>).+                <<https://github.com/choener/ADPfusion/gaplike-performance.png>>                 .+                Please note that actual performance will depend much on table+                layout and data structures accessed during calculations, but in+                general performance is very good: close to C and better than+                other high-level approaches (that I know of).+                .+                .+                .+                Even complex ADP code tends to be completely optimized to loops+                that use only unboxed variables (Int# and others,+                indexIntArray# and others).+                .                 Completely novel (compared to ADP), is the idea of allowing                 efficient monadic combinators. This facilitates writing code                 that performs backtracking, or samples structures@@ -44,6 +61,29 @@                 multiple recent improvements in GHC. This is particularly true                 for the monadic interface.                 .+                .+                .+                Newley added are the ADP.Fusion.GAPlike modules. These allow+                for writing grammars with only one (non)-terminal combinator.+                The logic for index manipulation is now moved into data types+                for terminals and non-terminals.+                .+                While this change leads to slightly more complicated instances+                for each new terminal or non-terminal, the overall code+                complexity is significantly lower. In addition, Constraint+                Kinds make complex interactions between (non)-terminals+                possible, while still managing to produce high-performance+                code.+                .+                The final goal would, of course, be to have no inter-terminal+                combinators anymore.+                .+                * GHC 7.6, LLVM, and -fnew-codegen recommended: gives a speedup+                  of x2 for GAPcriterion+                .+                .+                .+                .                 Long term goals: Outer indices with more than two dimensions,                 specialized table design, a combinator library, a library for                 computational biology.@@ -54,11 +94,28 @@                 <http://hackage.haskell.org/package/Nussinov78> and                 <http://hackage.haskell.org/package/RNAFold>.                 .+                Changes since 0.0.1.2:+                .+                * require GHC 7.6+                .+                * ADP.Fusion.GAPlike module for (almost) combinator-less grammars+                .+                * ConstraintKinds for constrained parsers in GAPlike.+                .+                .+                .                 Changes since 0.0.1.0:                 .                 * compatibility with GHC 7.4                 .                 * note: still using fundeps & and TFs together. The TF-only version does not optimize as well (I know why but not yet how to fix it)+                .+                .+                .+                Using the new code generator?+                .+                The new code generator is not official yet, but I recommend trying it out:+                <<https://github.com/choener/ADPfusion/gaplike-newcodegen.png>>   @@ -68,21 +125,47 @@   ADP/Fusion/QuickCheck/Arbitrary.hs  +Flag devel+  description: build criterion benchmarks and pull in QuickCheck+  default: False + library   build-depends:     base >= 4 && < 5,-    primitive      == 0.4.*   ,-    vector         == 0.9.*   ,-    PrimitiveArray == 0.2.2.0+    ghc-prim,+    primitive      == 0.5.*   ,+    vector         == 0.10.*  ,+    PrimitiveArray == 0.4.*   exposed-modules:     ADP.Fusion     ADP.Fusion.Monadic     ADP.Fusion.Monadic.Internal+    ADP.Fusion.GAPlike    ghc-options:     -O2 -funbox-strict-fields +executable GAPcriterion+  buildable:+    False+  if flag(devel)+    buildable:+      True+    build-depends:+      criterion  == 0.6.* ,+      QuickCheck == 2.5+  other-modules:+    ADP.Fusion.GAPlike.DevelCommon+    ADP.Fusion.GAPlike.Criterion+    ADP.Fusion.GAPlike.QuickCheck+  main-is:+    Tests/GAPcriterion.hs+  ghc-options:+    -fllvm -O2 -funbox-strict-fields -optlo-O3 -optlo-std-compile-opts+  if impl(GHC > 7.4)+    ghc-options:+      -fnew-codegen   source-repository head
+ Tests/GAPcriterion.hs view
@@ -0,0 +1,9 @@++module Main where++import ADP.Fusion.GAPlike2.Criterion++++main = criterionMain+