5
5
module Main where
6
6
7
7
import Data.IntSet (IntSet )
8
+ import Data.IntSet.Internal
8
9
import qualified Data.IntSet as IS
9
10
import Data.IntMap (IntMap )
10
11
import qualified Data.IntMap as IM
11
12
import qualified Data.Set as S
12
13
import qualified Data.Map.Strict as M
13
14
import qualified Data.Foldable as F
14
- import Data.List (foldl' )
15
+ import qualified Data.List
16
+ import Data.Bits (shift , complement , (.&.) , (.|.) , xor , bit , countLeadingZeros )
17
+ import Utils.Containers.Internal.BitUtil
15
18
import Data.Monoid (Sum (.. ))
16
- import Control.Monad (guard )
19
+ import Control.Monad (guard , forM_ )
20
+ import Test.LeanCheck
21
+ import Test.LeanCheck.Utils.Types (unNat )
17
22
import Gauge (bgroup , bench , defaultMain , whnf )
18
23
19
24
main = do
20
25
defaultMain
21
26
[ bgroup " det/hard" $ do
22
27
n <- [1 .. 20 ]
23
28
return $ bench (" n=" <> show n)
24
- $ whnf (size . det0 2 ) $ hard_nfa n
29
+ $ whnf (IM. size . det0 2 ) $ hard_nfa n
25
30
]
26
31
32
+ test2 = do
33
+ print $ toList (Tip (- 1024 ) 11 )
34
+
35
+ let t1 = fromList [0 ]
36
+ t2@ (Bin p m l r) = fromList [- 1 ,0 ]
37
+ print (p,m,l,r)
38
+ print $ relate t1 t2
39
+ print $ relate t1 l
40
+
41
+ putStrLn " compare==cis (Tip, Tip)"
42
+ checkFor (10 ^ 5 ) $ \ a b -> a == 0 || b == 0 ||
43
+ let p = 2 ^ 12 ; q = negate $ 2 ^ 12
44
+ in compare (Tip p a) (Tip q b) == cis (Tip p a) (Tip q b)
45
+
46
+ forM_ [0 , 2 ^ 10 , negate $ 2 ^ 10 ] $ \ p -> do
47
+ putStrLn $ " compare==cis (Tip (" <> show p <> " ) *)"
48
+ checkFor (10 ^ 5 ) $ \ a b ->
49
+ compare (Tip p a) (Tip p b) == cis (Tip p a) (Tip p b)
50
+
51
+ putStrLn " compare==cis"
52
+ checkFor (10 ^ 6 ) $ \ a b -> compare a b == cis a b
53
+
54
+ instance Listable IntSet where
55
+ tiers = mapT (IS. fromList {- . Prelude.map unNat -} ) tiers
56
+
57
+ -- | detailed outcome of lexicographic comparison of lists.
58
+ -- w.r.t. Ordering, there are two extra cases.
59
+ data Relation
60
+ = Less -- ^ holds for [0,3,4] [0,3,5,1]
61
+ | Prefix -- ^ holds for [0,3,4] [0,3,4,5]
62
+ | Equals -- ^ holds for [0,3,4] [0,3,4]
63
+ | FlipPrefix -- ^ holds for [0,3,4] [0,3]
64
+ | Greater -- ^ holds for [0,3,4] [0,2,5]
65
+ deriving Show
66
+
67
+ -- | compare IntSet
68
+ cis :: IntSet -> IntSet -> Ordering
69
+ cis a b = case relate a b of
70
+ Less -> LT
71
+ Prefix -> LT
72
+ Equals -> EQ
73
+ FlipPrefix -> GT
74
+ Greater -> GT
75
+
76
+ relate :: IntSet -> IntSet -> Relation
77
+ relate Nil Nil = Equals
78
+ relate Nil t2 = Prefix
79
+ relate t1 Nil = FlipPrefix
80
+ relate (Tip p1 bm1) (Tip p2 bm2) = case compare p1 p2 of
81
+ LT -> Less
82
+ EQ -> relateBM bm1 bm2
83
+ GT -> Greater
84
+ relate t1@ (Bin p1 m1 l1 r1) t2@ (Bin p2 m2 l2 r2)
85
+ | p1 == p2 = combine (relate l1 l2) (relate r1 r2)
86
+ | shorter m1 m2 = combine (relate l1 t2) FlipPrefix
87
+ | shorter m2 m1 = combine (relate t1 l2) Prefix
88
+ | otherwise = case compare p1 p2 of
89
+ LT -> Less
90
+ GT -> Greater
91
+ relate t1@ (Bin p1 m1 l1 r1) t2@ (Tip p2 bm2)
92
+ = combine (relate l1 t2) FlipPrefix
93
+ relate t1@ (Tip p1 bm1) t2@ (Bin p2 m2 l2 r2) = case compare p1 p2 of
94
+ LT -> Less
95
+ EQ -> combine (relate t1 l2) Prefix
96
+ GT -> Greater
97
+
98
+ combine :: Relation -> Relation -> Relation
99
+ combine r eq = case r of
100
+ Less -> Less
101
+ Prefix -> Greater
102
+ Equals -> eq
103
+ FlipPrefix -> Less
104
+ Greater -> Greater
105
+
106
+ bmtol m = toList $ Tip 0 m
107
+
108
+ relateBM :: BitMap -> BitMap -> Relation
109
+ relateBM w1 w2 | w1 == w2 = Equals
110
+ relateBM w1 w2 = -- e.g., 3=11 1=01
111
+ let delta = xor w1 w2 -- 2=10
112
+ lowest_diff_mask = delta .&. complement (delta- 1 ) -- 10
113
+ prefix = (complement lowest_diff_mask + 1 )
114
+ .&. (complement lowest_diff_mask) -- 1..100
115
+ in if 0 == lowest_diff_mask .&. w1
116
+ then if 0 == w1 .&. prefix
117
+ then Prefix else Greater
118
+ else if 0 == w2 .&. prefix
119
+ then FlipPrefix else Less
120
+
121
+ shorter :: Mask -> Mask -> Bool
122
+ shorter m1 m2
123
+ = (natFromInt m1) > (natFromInt m2)
124
+ {-# INLINE shorter #-}
125
+
126
+ -- A "Nat" is a natural machine word (an unsigned Int)
127
+ type Nat = Word
128
+
129
+ natFromInt :: Int -> Nat
130
+ natFromInt i = fromIntegral i
131
+ {-# INLINE natFromInt #-}
132
+
133
+ intFromNat :: Nat -> Int
134
+ intFromNat w = fromIntegral w
135
+ {-# INLINE intFromNat #-}
136
+
27
137
28
138
-- evaluate this expression while typing:
29
139
-- ghcid -W -Ttest benchmarks/OrdIntSet.hs
@@ -79,7 +189,7 @@ det sigma initial aut =
79
189
return (t, s, next)
80
190
in go (union_dfa (dfa ts) accu)
81
191
(S. insert t done)
82
- (foldl' (\ o (_,_,q) -> S. insert q o) odo ts)
192
+ (Data.List. foldl' (\ o (_,_,q) -> S. insert q o) odo ts)
83
193
in go IM. empty S. empty $ S. singleton initial
84
194
85
195
@@ -90,12 +200,12 @@ type Transition = (State, Sigma, State)
90
200
91
201
nfa :: [Transition ] -> NFA
92
202
nfa ts = IM. fromListWith ( IM. unionWith IS. union )
93
- $ map (\ (State p,Sigma s,State q) ->
203
+ $ Prelude. map (\ (State p,Sigma s,State q) ->
94
204
(s, IM. singleton p (IS. singleton q))) ts
95
205
96
206
dfa :: [(IntSet , Sigma , IntSet )] -> DFA
97
207
dfa ts = IM. fromListWith ( M. unionWith ( error " WAT" ) )
98
- $ map (\ ( p, Sigma s, q) ->
208
+ $ Prelude. map (\ ( p, Sigma s, q) ->
99
209
(s, M. singleton p q)) ts
100
210
101
211
union_dfa a b = IM. unionWith (M. unionWith (error " WAT" )) a b
0 commit comments