hunt-searchengine-0.3.0.0: src/Hunt/Common/Occurrences.hs
-- ----------------------------------------------------------------------------
{- |
Module : Hunt.Common.Occurrences
Copyright : Copyright (C) 2011 Sebastian M. Schlatt, Timo B. Huebel, Uwe Schmidt
License : MIT
Maintainer : Timo B. Huebel (tbh@holumbus.org)
Stability : experimental
Portability: none portable
Occurrences of words within the index.
A word occurs in document at specific locations.
-}
-- ----------------------------------------------------------------------------
module Hunt.Common.Occurrences
where
import Prelude hiding (subtract)
import Hunt.Common.BasicTypes
import Hunt.Common.DocId
import Hunt.Common.DocIdMap (DocIdMap)
import Hunt.Common.DocIdSet (DocIdSet)
import qualified Hunt.Common.DocIdMap as DM
import Hunt.Common.Positions (Positions)
import qualified Hunt.Common.Positions as Pos
-- ------------------------------------------------------------
-- | The occurrences of words in documents.
-- A mapping from document ids to the positions in the document.
type Occurrences = DocIdMap Positions
-- ------------------------------------------------------------
-- | Create an empty set of positions.
empty :: Occurrences
empty = DM.empty
-- | Create Occurrences from a 'DocIdSet'
-- Since the 'DocIdSet' contains no position information, we
-- assume position one for each 'DocId'
fromDocIdSet :: DocIdSet -> Occurrences
fromDocIdSet s = DM.fromDocIdSet (\_ -> Pos.singleton 1) s
-- | Create a single dcid set with a single position.
singleton :: DocId -> Position -> Occurrences
singleton d p = singleton' d [p]
-- | Create a single dcid set with a set of.
singleton' :: DocId -> [Position] -> Occurrences
singleton' d ps = DM.insert d (Pos.fromList ps) DM.empty
-- | Test on empty set of positions.
null :: Occurrences -> Bool
null = DM.null
-- | Determine the number of positions in a set of occurrences.
size :: Occurrences -> Int
size = DM.foldr ((+) . Pos.size) 0
-- | Add a position to occurrences.
insert :: DocId -> Position -> Occurrences -> Occurrences
insert d p = DM.insertWith Pos.union d (Pos.singleton p)
-- | Add multiple positions to occurrences
insert' :: DocId -> Positions -> Occurrences -> Occurrences
insert' d ps occs = Pos.foldr (insert d) occs ps
-- | Remove a position from occurrences.
deleteOccurrence :: DocId -> Position -> Occurrences -> Occurrences
deleteOccurrence d p = subtract (DM.singleton d (Pos.singleton p))
-- | Delete a document (by 'DocId') from occurrences.
delete :: DocId -> Occurrences -> Occurrences
delete = DM.delete
-- | Changes the DocIDs of the occurrences.
update :: (DocId -> DocId) -> Occurrences -> Occurrences
update f = DM.foldrWithKey
(\ d ps res -> DM.insertWith Pos.union (f d) ps res) empty
-- | Merge two occurrences.
merge :: Occurrences -> Occurrences -> Occurrences
merge = DM.unionWith Pos.union
-- | Merge occurrences
merges :: [Occurrences] -> Occurrences
merges = DM.unionsWith Pos.union
-- | Difference of occurrences.
difference :: Occurrences -> Occurrences -> Occurrences
difference = DM.difference
-- | Remove Set of DocIds from Occurrences
diffWithSet :: Occurrences -> DocIdSet -> Occurrences
diffWithSet = DM.diffWithSet
-- | Subtract occurrences from some other occurrences.
subtract :: Occurrences -> Occurrences -> Occurrences
subtract = DM.differenceWith subtractPositions
where
subtractPositions p1 p2
= if Pos.null diffPos
then Nothing
else Just diffPos
where
diffPos = Pos.difference p1 p2
intersectOccurrences :: (Positions -> Positions -> Positions) ->
Occurrences -> Occurrences -> Occurrences
intersectOccurrences pf os1 os2
= DM.filter (not . Pos.null) $ DM.intersectionWith pf os1 os2
-- ------------------------------------------------------------