ngram-0.1.0.0: src/Codec/Compression/PPM/Coding.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ExplicitNamespaces #-}
{-# LANGUAGE RecordWildCards #-}
module Codec.Compression.PPM.Coding (-- encode
--, decode
--, probability
--, shiftCommonPrefix
--, bitsToInteger
) where
import Prelude hiding (subtract, lookup, last)
import qualified Data.Map as Map
import Data.Map (Map)
import qualified Data.Maybe as M
import Data.Bits
import Control.Monad (join, liftM)
import qualified Data.List as L
import Data.Foldable (toList)
import qualified Data.Sequence as Seq
import Data.Sequence ((|>))
--import Codec.Compression.PPM.Trie (Trie(..), lookup)
--import Codec.Compression.PPM.Utils (windows)
import Data.Ratio ((%))
import Debug.Trace hiding (trace)
-- first :: Word
-- first = zeroBits `setBit` 0
-- last :: Word
-- last = zeroBits `setBit` i
-- where
-- i = (finiteBitSize first) - 1
-- secondToLast :: Word
-- secondToLast = zeroBits `setBit` i
-- where
-- i = (finiteBitSize first) - 2
-- shiftCommonPrefix :: State -> State
-- shiftCommonPrefix (State {..}) = case lb == hb of
-- True -> State { low=low `shiftL` 1, high=high `shiftL` 1 `setBit` 0, underflow=underflow, bits=lb:bits }
-- False -> case lsb /= hsb of
-- True -> State { low=low, high=high, underflow=underflow, bits=bits }
-- False -> State { low=low, high=high, underflow=underflow, bits=bits }
-- where
-- i = (finiteBitSize low) - 1
-- lb = low `testBit` i
-- hb = high `testBit` i
-- lsb = low `testBit` (i - 1)
-- hsb = high `testBit` (i - 1)
-- --where
-- -- go l' h' bs = case lb == hb of
-- -- True -> go (shiftL l' 1 `clearBit` 0) (shiftL h' 1 `setBit` 0) (lb:bs)
-- -- False -> (bs, l', h')
-- bitsToInteger :: [Bool] -> Integer
-- bitsToInteger = go 0
-- where
-- go i [] = i
-- go i (b:bs) = go ((if b == True then setBit else clearBit) (i `shift` 1) 0) bs
-- data Symbol = Symbol { lowCount :: Integer
-- , highCount :: Integer
-- , scale :: Integer
-- } deriving (Show)
-- data State = State { low :: Word
-- , high :: Word
-- , underflow :: Int
-- , bits :: [Bool]
-- } deriving (Show)
-- type Code = Trie (Maybe Char) (Integer, Integer)
-- -- -- | Under a given trie and with the current range, return the updated range
-- -- updateRange :: Code -> Word -> Word -> [Maybe Char] -> (Word, Word)
-- -- updateRange tr cl ch i = shiftCommonPrefix l' h'
-- -- where
-- -- range = (ch - cl) + 1
-- -- Just (nl, nh) = case lookup i tr of
-- -- Nothing -> error $ "No entry for: " ++ show es
-- -- Just x -> value x
-- -- Just (_, sc) = value tr
-- -- l' = cl + ((range * nl) `div` sc)
-- -- h' = cl + ((range * nh) `div` sc) - 1
-- trace :: (Show a) => a -> a
-- trace a = a -- traceShow a a
-- trace' :: (Show a) => String -> a -> a
-- trace' s a = a --traceShow (s, a) a
-- -- |
-- encodeItem :: State -> Symbol -> State
-- encodeItem (State{..}) (Symbol{..}) = shiftCommonPrefix $ State { low=fromIntegral (trace low'), high=fromIntegral (trace high'), underflow=underflow, bits=bits }
-- where
-- range = trace' "range: " $ (fromIntegral $ high - low :: Integer) + 1
-- l = fromIntegral low
-- low' = l + (range * lowCount) `div` scale
-- high' = l + (range * highCount) `div` scale - 1
-- --(shifted, low'', high'') = shiftCommonPrefix low' high'
-- type Input = [Maybe Char]
-- encode :: Code -> Int -> Input -> [Bool]
-- encode code n xs = (reverse . bits) $ foldl encodeItem iState cs''
-- where
-- iState = State zeroBits (complement zeroBits) 0 []
-- Just (_, top) = value code
-- cs = [lookup i code | i <- windows n xs]
-- cs' = [value tr | Just tr <- cs]
-- cs'' = trace [Symbol l h top | Just (l, h) <- cs']
-- decode :: Trie e v -> Integer -> [e]
-- decode tr i = go tr i []
-- where
-- go tr' i' (Nothing:bs) = M.catMaybes $ reverse bs
-- go tr' i' bs = go tr' i' (Nothing:bs)
-- probability :: Trie e v -> [e] -> Double
-- probability tr xs = 0.5