Skip to content

Commit

Permalink
Revert union, difference, etc. complexity changes (#958)
Browse files Browse the repository at this point in the history
As discussed in #870, the complexities for union, difference, etc. on
Set and Map were changed in #830 to fix some partiality in the
expressions, but along the way new partiality was introduced, and useful
special cases like m = 1 get incorrect complexity values from the new
formulas.

The original formula was as stated in the original paper:
  https://dl.acm.org/doi/10.1145/322123.322127
and this holds for 0 < m <= n, which seems sufficient to me. (The m=0
case is excluded, but for m=0 nothing needs to be done anyway. This
contrary to the m=1 case, in which useful work with very specific
complexity (namely, O(log(n))) needs to be done.)

This commit reverts all occurrences of the modified complexity formula
back to the original one.
  • Loading branch information
tomsmeding committed Sep 27, 2023
1 parent 9d395e4 commit 269f53e
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 25 deletions.
28 changes: 14 additions & 14 deletions containers/src/Data/Map/Internal.hs
Expand Up @@ -1811,7 +1811,7 @@ unionsWith f ts
{-# INLINABLE unionsWith #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
-- The expression (@'union' t1 t2@) takes the left-biased union of @t1@ and @t2@.
-- It prefers @t1@ when duplicate keys are encountered,
-- i.e. (@'union' == 'unionWith' 'const'@).
Expand All @@ -1835,7 +1835,7 @@ union t1@(Bin _ k1 x1 l1 r1) t2 = case split k1 t2 of
{--------------------------------------------------------------------
Union with a combining function
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Union with a combining function.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Union with a combining function.
--
-- > unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]

Expand All @@ -1855,7 +1855,7 @@ unionWith f (Bin _ k1 x1 l1 r1) t2 = case splitLookup k1 t2 of
{-# INLINABLE unionWith #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
-- Union with a combining function.
--
-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
Expand Down Expand Up @@ -1886,7 +1886,7 @@ unionWithKey f (Bin _ k1 x1 l1 r1) t2 = case splitLookup k1 t2 of
-- relies on doing it the way we do, and it's not clear whether that
-- bound holds the other way.

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Difference of two maps.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Difference of two maps.
-- Return elements of the first map not existing in the second map.
--
-- > difference (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 3 "b"
Expand All @@ -1905,7 +1905,7 @@ difference t1 (Bin _ k _ l2 r2) = case split k t1 of
{-# INLINABLE difference #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Remove all keys in a 'Set' from a 'Map'.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Remove all keys in a 'Set' from a 'Map'.
--
-- @
-- m \`withoutKeys\` s = 'filterWithKey' (\\k _ -> k ``Set.notMember`` s) m
Expand Down Expand Up @@ -1964,7 +1964,7 @@ differenceWithKey f =
{--------------------------------------------------------------------
Intersection
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Intersection of two maps.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Intersection of two maps.
-- Return data in the first map for the keys existing in both maps.
-- (@'intersection' m1 m2 == 'intersectionWith' 'const' m1 m2@).
--
Expand All @@ -1986,7 +1986,7 @@ intersection t1@(Bin _ k x l1 r1) t2
{-# INLINABLE intersection #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Restrict a 'Map' to only those keys
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Restrict a 'Map' to only those keys
-- found in a 'Set'.
--
-- @
Expand All @@ -2011,7 +2011,7 @@ restrictKeys m@(Bin _ k x l1 r1) s
{-# INLINABLE restrictKeys #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Intersection with a combining function.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Intersection with a combining function.
--
-- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"

Expand All @@ -2031,7 +2031,7 @@ intersectionWith f (Bin _ k x1 l1 r1) t2 = case mb of
{-# INLINABLE intersectionWith #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Intersection with a combining function.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Intersection with a combining function.
--
-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
-- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
Expand All @@ -2053,7 +2053,7 @@ intersectionWithKey f (Bin _ k x1 l1 r1) t2 = case mb of
{--------------------------------------------------------------------
Disjoint
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Check whether the key sets of two
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Check whether the key sets of two
-- maps are disjoint (i.e., their 'intersection' is empty).
--
-- > disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())]) == True
Expand Down Expand Up @@ -2752,7 +2752,7 @@ mergeWithKey f g1 g2 = go
{--------------------------------------------------------------------
Submap
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
-- This function is defined as (@'isSubmapOf' = 'isSubmapOfBy' (==)@).
--
isSubmapOf :: (Ord k,Eq a) => Map k a -> Map k a -> Bool
Expand All @@ -2761,7 +2761,7 @@ isSubmapOf m1 m2 = isSubmapOfBy (==) m1 m2
{-# INLINABLE isSubmapOf #-}
#endif

{- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
{- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
The expression (@'isSubmapOfBy' f t1 t2@) returns 'True' if
all keys in @t1@ are in tree @t2@, and when @f@ returns 'True' when
applied to their respective values. For example, the following
Expand Down Expand Up @@ -2810,7 +2810,7 @@ submap' f (Bin _ kx x l r) t
{-# INLINABLE submap' #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Is this a proper submap? (ie. a submap but not equal).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Is this a proper submap? (ie. a submap but not equal).
-- Defined as (@'isProperSubmapOf' = 'isProperSubmapOfBy' (==)@).
isProperSubmapOf :: (Ord k,Eq a) => Map k a -> Map k a -> Bool
isProperSubmapOf m1 m2
Expand All @@ -2819,7 +2819,7 @@ isProperSubmapOf m1 m2
{-# INLINABLE isProperSubmapOf #-}
#endif

{- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Is this a proper submap? (ie. a submap but not equal).
{- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Is this a proper submap? (ie. a submap but not equal).
The expression (@'isProperSubmapOfBy' f m1 m2@) returns 'True' when
@keys m1@ and @keys m2@ are not equal,
all keys in @m1@ are in @m2@, and when @f@ returns 'True' when
Expand Down
8 changes: 4 additions & 4 deletions containers/src/Data/Map/Strict/Internal.hs
Expand Up @@ -980,7 +980,7 @@ unionsWith f ts
{--------------------------------------------------------------------
Union with a combining function
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Union with a combining function.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Union with a combining function.
--
-- > unionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == fromList [(3, "b"), (5, "aA"), (7, "C")]

Expand All @@ -996,7 +996,7 @@ unionWith f (Bin _ k1 x1 l1 r1) t2 = case splitLookup k1 t2 of
{-# INLINABLE unionWith #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
-- Union with a combining function.
--
-- > let f key left_value right_value = (show key) ++ ":" ++ left_value ++ "|" ++ right_value
Expand Down Expand Up @@ -1054,7 +1054,7 @@ differenceWithKey f = merge preserveMissing dropMissing (zipWithMaybeMatched f)
Intersection
--------------------------------------------------------------------}

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Intersection with a combining function.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Intersection with a combining function.
--
-- > intersectionWith (++) (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "aA"

Expand All @@ -1072,7 +1072,7 @@ intersectionWith f (Bin _ k x1 l1 r1) t2 = case mb of
{-# INLINABLE intersectionWith #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Intersection with a combining function.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Intersection with a combining function.
--
-- > let f k al ar = (show k) ++ ":" ++ al ++ "|" ++ ar
-- > intersectionWithKey f (fromList [(5, "a"), (3, "b")]) (fromList [(5, "A"), (7, "C")]) == singleton 5 "5:a|A"
Expand Down
14 changes: 7 additions & 7 deletions containers/src/Data/Set/Internal.hs
Expand Up @@ -269,7 +269,7 @@ import Language.Haskell.TH ()
--------------------------------------------------------------------}
infixl 9 \\ --

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). See 'difference'.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). See 'difference'.
(\\) :: Ord a => Set a -> Set a -> Set a
m1 \\ m2 = difference m1 m2
#if __GLASGOW_HASKELL__
Expand Down Expand Up @@ -654,7 +654,7 @@ alteredSet x0 s0 = go x0 s0
{--------------------------------------------------------------------
Subset
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
-- @(s1 \`isProperSubsetOf\` s2)@ indicates whether @s1@ is a
-- proper subset of @s2@.
--
Expand All @@ -669,7 +669,7 @@ isProperSubsetOf s1 s2
#endif


-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\).
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\).
-- @(s1 \`isSubsetOf\` s2)@ indicates whether @s1@ is a subset of @s2@.
--
-- @
Expand Down Expand Up @@ -724,7 +724,7 @@ isSubsetOfX (Bin _ x l r) t
{--------------------------------------------------------------------
Disjoint
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Check whether two sets are disjoint
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Check whether two sets are disjoint
-- (i.e., their intersection is empty).
--
-- > disjoint (fromList [2,4,6]) (fromList [1,3]) == True
Expand Down Expand Up @@ -815,7 +815,7 @@ unions = Foldable.foldl' union empty
{-# INLINABLE unions #-}
#endif

-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). The union of two sets, preferring the first set when
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). The union of two sets, preferring the first set when
-- equal elements are encountered.
union :: Ord a => Set a -> Set a -> Set a
union t1 Tip = t1
Expand All @@ -835,7 +835,7 @@ union t1@(Bin _ x l1 r1) t2 = case splitS x t2 of
{--------------------------------------------------------------------
Difference
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). Difference of two sets.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). Difference of two sets.
--
-- Return elements of the first set not existing in the second set.
--
Expand All @@ -856,7 +856,7 @@ difference t1 (Bin _ x l2 r2) = case split x t1 of
{--------------------------------------------------------------------
Intersection
--------------------------------------------------------------------}
-- | \(O\bigl(m \log\bigl(\frac{n+1}{m+1}\bigr)\bigr), \; m \leq n\). The intersection of two sets.
-- | \(O\bigl(m \log\bigl(\frac{n}{m}+1\bigr)\bigr), \; 0 < m \leq n\). The intersection of two sets.
-- Elements of the result come from the first set, so for example
--
-- > import qualified Data.Set as S
Expand Down

0 comments on commit 269f53e

Please sign in to comment.