{-# Language TypeFamilies #-}
{-# Language TypeApplications #-}
module Data.Connection.Property where
import Data.Proxy
import Data.Prd
import Data.Connection
import qualified Test.Property.Function.Idempotent as Prop
import qualified Test.Property.Function.Invertible as Prop
import qualified Test.Property.Function.Monotone as Prop
import Test.Property.Util
import Prelude hiding (Ord(..))
connection :: Prd a => Prd b => Conn a b -> a -> b -> Bool
connection (Conn f g) = Prop.adjoint_on (<~) (<~) f g
closed :: Prd a => Prd b => Conn a b -> a -> Bool
closed (Conn f g) = Prop.invertible_on (>~) f g
closed' :: Prd a => Prd b => Trip a b -> a -> Bool
closed' t x = closed (tripl t) x && kernel (tripr t) x
kernel :: Prd a => Prd b => Conn a b -> b -> Bool
kernel (Conn f g) = Prop.invertible_on (<~) g f
kernel' :: Prd a => Prd b => Trip a b -> b -> Bool
kernel' t x = closed (tripr t) x && kernel (tripl t) x
monotone :: Prd a => Prd b => Conn a b -> b -> b -> Bool
monotone (Conn _ g) = Prop.monotone_on (<~) (<~) g
monotone' :: Prd a => Prd b => Conn a b -> a -> a -> Bool
monotone' (Conn f _) = Prop.monotone_on (<~) (<~) f
idempotent_unit :: Prd a => Prd b => Conn a b -> a -> Bool
idempotent_unit conn = Prop.idempotent_on (=~) $ unit conn
idempotent_counit :: Prd a => Prd b => Conn a b -> b -> Bool
idempotent_counit conn = Prop.idempotent_on (=~) $ counit conn
projective_l :: Prd a => Prd b => Conn a b -> a -> Bool
projective_l conn@(Conn f _) = Prop.projective_on (=~) f $ counit conn
projective_r :: Prd a => Prd b => Conn a b -> b -> Bool
projective_r conn@(Conn _ g) = Prop.projective_on (=~) g $ unit conn