-- | -- This is an internal relapse module. -- -- It zips patterns to reduce the state space. module Zip ( Zipper, zippy, unzipby ) where import qualified Data.Set as S import Data.List (elemIndex) import Patterns data ZipEntry = ZipVal Int | ZipZAny | ZipNotZAny deriving (Eq, Ord) newtype Zipper = Zipper [ZipEntry] deriving (Eq, Ord) zippy :: [Pattern] -> ([Pattern], Zipper) zippy ps = let s = S.fromList ps s' = S.delete ZAny s s'' = S.delete (Not ZAny) s' l = S.toAscList s'' in (l, Zipper $ map (indexOf l) ps) indexOf :: [Pattern] -> Pattern -> ZipEntry indexOf _ ZAny = ZipZAny indexOf _ (Not ZAny) = ZipNotZAny indexOf ps p = case elemIndex p ps of (Just i) -> ZipVal i unzipby :: Zipper -> [Bool] -> [Bool] unzipby (Zipper z) bs = map (ofIndexb bs) z ofIndexb :: [Bool] -> ZipEntry -> Bool ofIndexb _ ZipZAny = True ofIndexb _ ZipNotZAny = False ofIndexb bs (ZipVal i) = bs !! i