packages feed

ampersand-3.0.0: src/lib/DatabaseDesign/Ampersand/ADL1/Pair.hs

{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
module DatabaseDesign.Ampersand.ADL1.Pair
                    ( Paire,Pairs
                    , kleenejoin
                    , srcPaire,trgPaire
                    , mkPair
                    , closPair
                    , clos1
                    ) 
where
   import DatabaseDesign.Ampersand.Basics (Collection(isc,uni),eqCl)
   import Data.List (nub)
   import GHC.Exts (sortWith)

   type Pairs = [Paire]
   srcPaire :: Paire -> String
   trgPaire :: Paire -> String
   mkPair :: String -> String -> Paire
   type Paire = (String,String)
   mkPair a b = (a,b)
   srcPaire = fst
   trgPaire = snd


   -- | Operations for representations that act as a Kleene algebra (RA without complement and with the closure operators)
   -- | A Kleene algebra has two binary operations 'union' and 'kleenejoin', and one function 'closure' (usually written as +, � and * respectively)
   class KAComputable a where
     kleenejoin :: a->a->a
     closPair :: a->a
     -- TODO: add the 'uni' operator
   
   instance (KAComputable a) => KAComputable (Maybe a) where
     kleenejoin (Just a) (Just b) = Just (kleenejoin a b)
     kleenejoin _ _ = Nothing
     closPair (Just p) = Just (closPair p)
     closPair _ = Nothing
      
   instance KAComputable Pairs where
     kleenejoin a b = merge ((sortWith (trgPaire.head).eqCl trgPaire) a)
                      ((sortWith (srcPaire.head).eqCl srcPaire) b)
                where merge (xs:xss) (ys:yss)
                       | trgPaire (head xs)<srcPaire (head ys) = merge xss (ys:yss)
                       | trgPaire (head xs)>srcPaire (head ys) = merge (xs:xss) yss
                       | otherwise = [mkPair (srcPaire x) (trgPaire y) |x<-xs,y<-ys]++ merge xss yss
                      merge _ _ = []
     closPair ps = toPairs (clos1 (toList ps))
      where
       toPairs :: [(String,String)] -> Pairs
       toPairs pairs = [mkPair a b | (a,b)<-pairs]
       toList :: Pairs -> [(String,String)]
       toList pairs = [(srcPaire p, trgPaire p) | p<-pairs]
----------------------------------------------------
--  Warshall's transitive closure algorithm in Haskell:
----------------------------------------------------
   clos1 :: (Eq a) => [(a,a)] -> [(a,a)]     -- e.g. a list of pairs
   clos1 xs
     = foldl f xs (nub (map fst xs) `isc` nub (map snd xs))
       where
        f q x = q `uni` [(a, b') | (a, b) <- q, b == x, (a', b') <- q, a' == x]