-- | ViennaRNA folding based on an algebraic ring structure. This should -- combine the goals of few lines of codes, multiple different folding -- functions and extensibility. -- -- NOTE Assume that you want '-d 3' for folding with dangles. Then you can just -- instanciate the folding functions, replacing only those functions where the -- folding changes based on the new dangle options. -- -- NOTE compile with: -fno-method-sharing module BioInf.RNAFold where import Control.Monad import Control.Monad.ST import Biobase.RNA import Biobase.Types.Ring import Data.PrimitiveArray import Biobase.Structure import BioInf.RNAFold.Functions import Debug.Trace.Tools import Debug.Trace -- | Folding works on unboxed values of a Ring-type for which a FoldFunctions -- instance does exist. By default, we have this for Energy values. Again, we -- use a class as we could be interested in probabilistic backtracking or -- something like that. type ResultTables a = ( Table a -- weak structures , Table a -- strong structures , Table a -- exactly one component , Table a -- one or more components , Table a -- complete external structures ) type Pairlist = [(Int,Int)] class (FoldFunctions a) => Fold a where fold :: TurnerTables a -> Primary -> (ResultTables a) foldST :: TurnerTables a -> Primary -> ST s (ResultTables a) backtrack :: TurnerTables a -> Primary -> (ResultTables a) -> a -> [(Secondary,a)] -- | We have a default instance for folding based on Rings fold trnr inp = runST $ foldST trnr inp {-# INLINE fold #-} foldST trnr inp = do let n = snd $ bounds inp (weakM,weak) <- mkTable n (strongM,strong) <- mkTable n (externM,extern) <- mkTableWith one n (mbr1M,mbr1) <- mkTable n (mbrM,mbr) <- mkTable n forM_ [n,n-1..0] $ \i -> forM_ [i,i+1..n] $ \j -> do let pIJ = pair inp i j when (pIJ/=vpNP&&i+30&&j do let extUP = {-# SCC "extUP" #-} if i