RNAFold-1.99.1.0: BioInf/RNAfold/Combinators.hs
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
-- | RNAfold combinators, extracted for quickcheck
module BioInf.RNAfold.Combinators
( (~~#)
, (#~~)
) where
import Data.Array.Repa.Index
import qualified Data.Vector.Fusion.Stream as S
import Data.List
import qualified ADP.Fusion as F
import qualified ADP.Fusion.Monadic as M
import qualified ADP.Fusion.Monadic.Internal as F
import ADP.Fusion.Monadic (makeLeft_MinRight)
import ADP.Fusion.Monadic.Internal (Box(..))
infixl 9 #~~, ~~#
-- | The structure on the left is a subword with size 2-28. The maximal size
-- could be 30 but since the two combinators are linked, 29,30 would fail
-- anyways.
(#~~) = makeLeft_MinRight (3,30) 1
{-# INLINE (#~~) #-}
-- | The structure on the right is a subword with size 2-30, however we inspect
-- the stack an reduce the maximal size.
(~~#) xs ys = Box mk step xs ys where
minT = 8 -- minimal total size of region
minC = 3 -- minimal number of nuc's on the right
maxC = 32
{-# INLINE mk #-}
mk (z:.k:.j,a,b) = let (_:.i) = z
cnsmd = k-i -- consumed part
l = max k (j-maxC+cnsmd)
in return (z:.k:.l:.j,a,b)
{-# INLINE step #-}
step (z:.k:.l:.j,a,b)
| l<=j-(max 0 $ minT - cnsmd) && l+minC<=j
= return $ S.Yield (z:.k:.l:.j,a,b) (z:.k:.l+1:.j,a,b)
| otherwise = return $ S.Done
where cnsmd = k-i
(_:.i) = z
{-# INLINE (~~#) #-}