-
Notifications
You must be signed in to change notification settings - Fork 1
/
Encoding.hs
137 lines (110 loc) · 3.86 KB
/
Encoding.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
module Encoding
(order,
gap,
pad,
gap_encode',
gap_encode,
gap_decode,
Encoder,Decoder,
prop_unbitify_bitify,
prop_bitify_unbitify,
prop_bitify_ilog,
prop_order_encode_decode,
prop_decode_encode,
prop_order_1,
prop_elias,
prop_gap
)
where
--import Prelude hiding (length,splitAt,(++),concat,replicate,break,take,repeat,init,all)
import Util
import Test.QuickCheck
--import Test.QuickCheck.Property
import Data.List -- .Stream
import Data.Bits
import Data.Maybe
import Debug.Trace
{-
bitify :: Int -> Integer -> [Bool]
bitify n i = map (testBit i) [0..n-1]
-}
type Encoder = [Bool]->[Bool]
type Decoder = [Bool]->[Bool]
calc_o :: Integer -> Integer -> [Bool] -> Integer
calc_o t c xs = go 0 t c xs
where go acc t c (False:xs)
= go acc (t-1) c xs
go acc t c (True:xs)
= go (acc + binom (t-1) c) (t-1) (c-1) xs
go acc _ _ [] = acc
calc_c :: [Bool] -> Integer
calc_c xs = fromIntegral $ count id xs
encode_order :: Integer -> [Bool] -> (Integer,Integer)
encode_order t xs = (c,o)
where c = calc_c xs
o = calc_o t c xs
decode_order :: Integer -> (Integer,Integer) -> [Bool]
decode_order t (c,o) = go t c o
where
go 0 _ _ = []
go t c o
| o >= binom (t-1) c = True: go (t-1) (c-1) (o-binom (t-1) c)
| otherwise = False:go (t-1) c o
prop_order_encode_decode =
forAll (do t <- choose (1,18)
c <- choose (0,fromIntegral t -1)
o <- choose (0,binom t c -1)
return (t,c,o))
(\(t,c,o) -> encode_order t (decode_order t (c,o)) == (c,o))
prop_decode_encode xs = let t = genericLength xs in
t < 18 ==> decode_order t (encode_order t xs) == xs
order :: Int -> (Encoder,Decoder)
order t = (enc,dec)
where l = ilog2 t
enc x = let (c,o) = encode_order (fromIntegral t) x
in pad l (bitify c) ++ bitify o
dec x = let (c',o') = splitAt l x
in decode_order (fromIntegral t) (unbitify c',unbitify o')
prop_order_1 xs = let t = length xs
(e,d) = order t
in t <= 15 ==> d (e xs) == xs
safeinit :: [a] -> [a]
safeinit [] = []
safeinit xs = init xs
elias_encode :: Int -> [Bool]
elias_encode i = let l = ilog2 i
ll = ilog2 l
in replicate ll False ++
[True] ++
safeinit (bitify l) ++
safeinit (bitify i)
elias_decode :: [Bool] -> (Int,[Bool])
elias_decode (True:xs) = (0,xs)
elias_decode xs = let (llpart, True:rest) = break id xs
ll = length llpart
(lpart, rest') = splitAt (ll-1) rest
l = fromIntegral $ unbitify (lpart++[True])
(xpart, rest'') = splitAt (l-1) rest'
x = fromIntegral $ unbitify (xpart++[True])
in (x, rest'')
prop_elias :: Int -> Property
prop_elias i = i >= 0 ==> elias_decode (elias_encode i) == (i,[])
gap_encode' :: [Bool] -> [[Bool]]
gap_encode' xs = let (gap,rest) = break id xs
code = elias_encode $ length gap
restEnc = case rest of
[] -> []
(True:rest') -> gap_encode' rest'
in
code : restEnc
gap_encode :: Encoder
gap_encode xs = concat $ gap_encode' xs
gap_decode :: Decoder
gap_decode [] = []
gap_decode xs = case elias_decode xs of
(i,[]) -> replicate i False
(i,rest) -> replicate i False ++ True:gap_decode rest
prop_gap :: [Bool] -> Bool
prop_gap xs = gap_decode (gap_encode xs) == xs
gap :: (Encoder,Decoder)
gap = (gap_encode,gap_decode)