module Satchmo.Relation.Prop
( implies
, symmetric
, transitive
, irreflexive
, reflexive
, regular
, empty
, complete
, disjoint
, equals
)
where
import Prelude hiding ( and, or, not, product )
import qualified Prelude
import Satchmo.Code
import Satchmo.Boolean hiding (implies, equals)
import Satchmo.Counting
import Satchmo.Relation.Data
import Satchmo.Relation.Op
import Control.Monad ( guard )
import Data.Ix
import Satchmo.SAT
implies :: ( Ix a, Ix b, MonadSAT m )
=> Relation a b -> Relation a b -> m Boolean
implies r s = monadic and $ do
i <- indices r
return $ or [ not $ r ! i, s ! i ]
empty :: ( Ix a, Ix b, MonadSAT m )
=> Relation a b -> m Boolean
empty r = and $ do
i <- indices r
return $ not $ r ! i
complete r = empty $ complement r
disjoint r s = do
i <- intersection r s
empty i
equals r s = do
rs <- implies r s
sr <- implies s r
and [ rs, sr ]
symmetric :: ( Ix a, MonadSAT m) => Relation a a -> m Boolean
symmetric r = implies r ( mirror r )
irreflexive :: ( Ix a, MonadSAT m) => Relation a a -> m Boolean
irreflexive r = and $ do
let ((a,b),(c,d)) = bounds r
x <- range ( a, c)
return $ Satchmo.Boolean.not $ r ! (x,x)
reflexive :: ( Ix a, MonadSAT m) => Relation a a -> m Boolean
reflexive r = and $ do
let ((a,b),(c,d)) = bounds r
x <- range (a,c)
return $ r ! (x,x)
regular :: ( Ix a, MonadSAT m) => Int -> Relation a a -> m Boolean
regular deg r = monadic and $ do
let ((a,b),(c,d)) = bounds r
x <- range ( a , c )
return $ exactly deg $ do
y <- range (b,d)
return $ r !(x,y)
transitive :: ( Ix a, MonadSAT m )
=> Relation a a -> m Boolean
transitive r = do
r2 <- product r r
implies r2 r