Rel.hs revision a74f814d3b445eadad6f68737a98a7a303698aff
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannModule : $Header$
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannDescription : Relations, based on maps
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannCopyright : (c) Uni Bremen 2003-2005
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannLicense : GPLv2 or higher, see LICENSE.txt
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannMaintainer : Christian.Maeder@dfki.de
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannStability : provisional
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannPortability : portable
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannsupply a simple data type for (precedence or subsort) relations. A
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannrelation is conceptually a set of (ordered) pairs,
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannbut the hidden implementation is based on a map of sets.
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannAn alternative view is that of a directed Graph
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannwithout isolated nodes.
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann'Rel' is a directed graph with elements (Ord a) as (uniquely labelled) nodes
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannand (unlabelled) edges (with a multiplicity of at most one).
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannUsage: start with an 'empty' relation, 'insert' edges, and test for
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannan edge 'member' (before or after calling 'transClosure').
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannIt is possible to insert self edges or bigger cycles.
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannChecking for a 'path' corresponds to checking for a member in the
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmanntransitive (possibly non-reflexive) closure. A further 'insert', however,
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannmay destroy the closedness property of a relation.
304d15b2ffa9376d78bddcfc63569824381714abDaniel HausmannThe functions 'image', and 'setInsert' are utility functions
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmannfor plain maps involving sets.
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann ( Rel(), empty, null, insert, member, toMap, map
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann , union, intersection, isSubrelOf, difference, path
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann , delete, succs, predecessors, irreflex, sccOfClosure
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann , transClosure, fromList, toList, image, toPrecMap
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann , intransKernel, mostRight, restrict, delSet
304d15b2ffa9376d78bddcfc63569824381714abDaniel Hausmann , toSet, fromSet, topSort, nodes, collaps
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.List as List
empty = Rel Map.empty
null (Rel m) = Map.null m
union a b = fromSet $ Set.union (toSet a) $ toSet b
intersection a b = fromSet $ Set.intersection (toSet a) $ toSet b
isSubrelOf a b = Set.isSubsetOf (toSet a) $ toSet b
member a b r = Set.member b $ succs r a
succs :: Ord a => Rel a -> a -> Set.Set a
reachable :: Ord a => Rel a -> a -> Set.Set a
reach e s = if Set.member e s then s
preds r a = Set.filter ( \ s -> member s a r)
predecessors :: Ord a => Rel a -> a -> Set.Set a
predecessors r@(Rel m) a = preds r a $ Map.keysSet m
path a b r = Set.member b $ reachable r a
transClosure r@(Rel m) = Rel $ Map.mapWithKey ( \ k _ -> reachable r k) m
transpose = fromList . List.map ( \ (a, b) -> (b, a)) . toList
sccOfClosure :: Ord a => Rel a -> [Set.Set a]
if Map.null m then []
else let ((k, v), p) = Map.deleteFindMin m in
if Set.member k v then -- has a cycle
collaps :: Ord a => [Set.Set a] -> Rel a -> Rel a
of a transitively closed DAG (i.e. without cycles)! -}
Set.filter ( \ j ->
toList (Rel m) = concatMap (\ (a , bs) -> List.map ( \ b -> (a, b) )
show = show . Set.fromDistinctAscList . toList
where ins x = case Map.lookup x f of
Just y -> Set.insert y
map f (Rel m) = Rel $ Map.foldWithKey
restrict :: Ord a => Rel a -> Set.Set a -> Rel a
delSet :: Ord a => Set.Set a -> Rel a -> Rel a
delSet s (Rel m) = Rel $ rmNull (Map.map (Set.\\ s) m) Map.\\ setToMap s
toSet :: (Ord a) => Rel a -> Set.Set (a, a)
toSet = Set.fromDistinctAscList . toList
fromSet :: (Ord a) => Set.Set (a, a) -> Rel a
fromSet = fromAscList . Set.toList
fromAscList = Rel . Map.fromDistinctAscList
. List.map ( \ l -> (fst (head l),
. List.groupBy ( \ (a, _) (b, _) -> a == b)
nodes :: Ord a => Rel a -> Set.Set a
toPrecMap :: Ord a => Rel a -> (Map.Map a Int, Int)
(Map.empty, 0) . topSort
topSortDAG :: Ord a => Rel a -> [Set.Set a]
topSortDAG r@(Rel m) = if Map.null m then [] else
ml = Map.keysSet m Set.\\ es -- most left
rs = es Set.\\ Map.keysSet m2 -- re-insert loose ends
topSort :: Ord a => Rel a -> [Set.Set a]
List.map (expandCycle cs) $ topSortDAG $ irreflex $ collaps cs r
let (a, b) = Set.deleteFindMin c in
mostRightOfCollapsed :: Ord a => Rel a -> Set.Set a
mr = elemsSet im Set.\\ Map.keysSet im
((==) . Set.singleton) m
mostRight :: (Ord a) => Rel a -> (Set.Set a)
addCycle :: Ord a => Set.Set a -> Rel a -> Rel a
let (a, b) = Set.deleteFindMin c
(m, d) = Set.deleteFindMax c
-- | Divide a Set (List) into equivalence classes w.r.t. eq
leqClasses :: Ord a => (a -> a -> Bool) -> Set.Set a -> [[a]]
leqClasses f = partList f . Set.toList
then error "Common.Lib.Rel.flatSet"
else Set.findMin s)
check s = Set.null s ||
Set.fold (\ y ->
where (x, s') = Set.deleteFindMin s