@@ -1216,156 +1216,8 @@ nequal _ _ = True
1216
1216
--------------------------------------------------------------------}
1217
1217
1218
1218
instance Ord IntSet where
1219
- compare Nil Nil = EQ
1220
- compare Nil _ = LT
1221
- compare _ Nil = GT
1222
- compare t1@ (Tip _ _) t2@ (Tip _ _)
1223
- = orderingOf $ relateTipTip t1 t2
1224
- compare xs ys
1225
- | (xsNeg, xsNonNeg) <- splitSign xs
1226
- , (ysNeg, ysNonNeg) <- splitSign ys
1227
- = case relate xsNeg ysNeg of
1228
- Less -> LT
1229
- Prefix -> if null xsNonNeg then LT else GT
1230
- Equals -> orderingOf (relate xsNonNeg ysNonNeg)
1231
- FlipPrefix -> if null ysNonNeg then GT else LT
1232
- Greater -> GT
1233
-
1234
- -- | detailed outcome of lexicographic comparison of lists.
1235
- -- w.r.t. Ordering, there are two extra cases,
1236
- -- since (++) is not monotonic w.r.t. lex. order on lists
1237
- -- (which is used by definition):
1238
- -- consider comparison of (Bin [0,3,4] [ 6] ) to (Bin [0,3] [7] )
1239
- -- where [0,3,4] > [0,3] but [0,3,4,6] < [0,3,7].
1240
-
1241
- data Relation
1242
- = Less -- ^ holds for [0,3,4] [0,3,5,1]
1243
- | Prefix -- ^ holds for [0,3,4] [0,3,4,5]
1244
- | Equals -- ^ holds for [0,3,4] [0,3,4]
1245
- | FlipPrefix -- ^ holds for [0,3,4] [0,3]
1246
- | Greater -- ^ holds for [0,3,4] [0,2,5]
1247
- deriving (Show , Eq )
1248
-
1249
- orderingOf :: Relation -> Ordering
1250
- {-# INLINE orderingOf #-}
1251
- orderingOf r = case r of
1252
- Less -> LT
1253
- Prefix -> LT
1254
- Equals -> EQ
1255
- FlipPrefix -> GT
1256
- Greater -> GT
1257
-
1258
- -- | precondition: each argument is non-mixed
1259
- relate :: IntSet -> IntSet -> Relation
1260
- relate Nil Nil = Equals
1261
- relate Nil _t2 = Prefix
1262
- relate _t1 Nil = FlipPrefix
1263
- relate t1@ Tip {} t2@ Tip {} = relateTipTip t1 t2
1264
- relate t1@ (Bin _p1 m1 l1 r1) t2@ (Bin _p2 m2 l2 r2)
1265
- | succUpperbound t1 <= lowerbound t2 = Less
1266
- | lowerbound t1 >= succUpperbound t2 = Greater
1267
- | otherwise = case compare (natFromInt m1) (natFromInt m2) of
1268
- GT -> combine_left (relate l1 t2)
1269
- EQ -> combine (relate l1 l2) (relate r1 r2)
1270
- LT -> combine_right (relate t1 l2)
1271
- relate t1@ (Bin _p1 m1 l1 _r1) t2@ (Tip p2 _bm2)
1272
- | succUpperbound t1 <= lowerbound t2 = Less
1273
- | lowerbound t1 >= succUpperbound t2 = Greater
1274
- | 0 == (m1 .&. p2) = combine_left (relate l1 t2)
1275
- | otherwise = Less
1276
- relate t1@ (Tip p1 _bm1) t2@ (Bin _p2 m2 l2 _r2)
1277
- | succUpperbound t1 <= lowerbound t2 = Less
1278
- | lowerbound t1 >= succUpperbound t2 = Greater
1279
- | 0 == (p1 .&. m2) = combine_right (relate t1 l2)
1280
- | otherwise = Greater
1281
-
1282
- relateTipTip :: IntSet -> IntSet -> Relation
1283
- {-# INLINE relateTipTip #-}
1284
- relateTipTip (Tip p1 bm1) (Tip p2 bm2) = case compare p1 p2 of
1285
- LT -> Less
1286
- EQ -> relateBM bm1 bm2
1287
- GT -> Greater
1288
- relateTipTip _ _ = error " relateTipTip"
1289
-
1290
- relateBM :: BitMap -> BitMap -> Relation
1291
- {-# inline relateBM #-}
1292
- relateBM w1 w2 | w1 == w2 = Equals
1293
- relateBM w1 w2 =
1294
- let delta = xor w1 w2
1295
- lowest_diff_mask = delta .&. complement (delta- 1 )
1296
- prefix = (complement lowest_diff_mask + 1 )
1297
- .&. (complement lowest_diff_mask)
1298
- in if 0 == lowest_diff_mask .&. w1
1299
- then if 0 == w1 .&. prefix
1300
- then Prefix else Greater
1301
- else if 0 == w2 .&. prefix
1302
- then FlipPrefix else Less
1303
-
1304
- -- | This function has the property
1305
- -- relate t1@(Bin p m l1 r1) t2@(Bin p m l2 r2) = combine (relate l1 l2) (relate r1 r2)
1306
- -- It is important that `combine` is lazy in the second argument (achieved by inlining)
1307
- combine :: Relation -> Relation -> Relation
1308
- {-# inline combine #-}
1309
- combine r eq = case r of
1310
- Less -> Less
1311
- Prefix -> Greater
1312
- Equals -> eq
1313
- FlipPrefix -> Less
1314
- Greater -> Greater
1315
-
1316
- -- | This function has the property
1317
- -- relate t1@(Bin p1 m1 l1 r1) t2 = combine_left (relate l1 t2)
1318
- -- under the precondition that the range of l1 contains the range of t2,
1319
- -- and r1 is non-empty
1320
- combine_left :: Relation -> Relation
1321
- {-# inline combine_left #-}
1322
- combine_left r = case r of
1323
- Less -> Less
1324
- Prefix -> Greater
1325
- Equals -> FlipPrefix
1326
- FlipPrefix -> FlipPrefix
1327
- Greater -> Greater
1328
-
1329
- -- | This function has the property
1330
- -- relate t1 t2@(Bin p2 m2 l2 r2) = combine_right (relate t1 l2)
1331
- -- under the precondition that the range of t1 is included in the range of l2,
1332
- -- and r2 is non-empty
1333
- combine_right :: Relation -> Relation
1334
- {-# inline combine_right #-}
1335
- combine_right r = case r of
1336
- Less -> Less
1337
- Prefix -> Prefix
1338
- Equals -> Prefix
1339
- FlipPrefix -> Less
1340
- Greater -> Greater
1341
-
1342
- -- | shall only be applied to non-mixed non-Nil trees
1343
- lowerbound :: IntSet -> Int
1344
- {-# INLINE lowerbound #-}
1345
- lowerbound Nil = error " lowerbound: Nil"
1346
- lowerbound (Tip p _) = p
1347
- lowerbound (Bin p _ _ _) = p
1348
-
1349
- -- | this is one more than the actual upper bound (to save one operation)
1350
- -- shall only be applied to non-mixed non-Nil trees
1351
- succUpperbound :: IntSet -> Int
1352
- {-# INLINE succUpperbound #-}
1353
- succUpperbound Nil = error " succUpperbound: Nil"
1354
- succUpperbound (Tip p _) = p + wordSize
1355
- succUpperbound (Bin p m _ _) = p + shiftR m 1
1356
-
1357
- -- | split a set into subsets of negative and non-negative elements
1358
- splitSign :: IntSet -> (IntSet ,IntSet )
1359
- {-# INLINE splitSign #-}
1360
- splitSign t@ (Tip kx _)
1361
- | kx >= 0 = (Nil , t)
1362
- | otherwise = (t, Nil )
1363
- splitSign t@ (Bin p m l r)
1364
- -- m < 0 is the usual way to find out if we have positives and negatives (see findMax)
1365
- | m < 0 = (r, l)
1366
- | p < 0 = (t, Nil )
1367
- | otherwise = (Nil , t)
1368
- splitSign Nil = (Nil , Nil )
1219
+ compare s1 s2 = compare (toAscList s1) (toAscList s2)
1220
+ -- tentative implementation. See if more efficient exists.
1369
1221
1370
1222
{- -------------------------------------------------------------------
1371
1223
Show
0 commit comments