module Data.Relation.Ops ( -- $selectops (|$>) -- Restrict the range according to a subset. PICA. , (<$|) -- Restrict the domain according to a subset. PICA. , (<|) -- Domain restriction. Z. , (|>) -- Range restriction. z. ) where import Data.Relation.Internal (Relation) import Data.Set (Set) import qualified Data.Relation as R import qualified Data.Relation.Internal.Set as S import qualified Data.Set as S -- $selectops -- -- Primitive implementation for the /right selection/ and /left selection/ operators. -- -- PICA provides both operators: -- '|>' and '<|' -- and '|$>' and '<$|' -- -- in this library, for working with Relations and OIS (Ordered, Inductive Sets?). -- -- PICA exposes the operators defined here, so as not to interfere with the abstraction -- of the Relation type and because having access to Relation hidden components is a more -- efficient implementation of the operation of restriction. -- -- @ -- (a <$| b) r -- -- denotes: for every element @b@ from the Set @B@, -- select an element @a@ from the Set @A@ , -- if @a@ -- is related to @b@ -- in @r@ -- @ -- -- @ -- (a |$> b) r -- -- denotes: for every element @a@ from the Set @A@ , -- select an element @b@ from the Set @B@, -- if @a@ -- is related to @b@ -- in @r@ -- @ -- -- With regard to domain restriction and range restriction operators -- of the language, those are described differently and return the domain or the range. -- | -- @(Case b <| r a)@ (<$|) :: (Ord a, Ord b) => Set a -> Set b -> Relation a b -> Set a (as <$| bs) r = as `S.intersection` generarAS bs where generarAS = S.flatten . S.map (`R.lookupRan` r) -- The subsets of the domain (a) associated with each @b@ -- such that @b@ in @B@ and (b) are in the range of the relation. -- The expression 'S.map' returns a set of @Either (Set a)@. -- | -- @(Case a |> r b)@ (|$>) :: (Ord a, Ord b) => Set a -> Set b -> Relation a b -> Set b (as |$> bs) r = bs `S.intersection` generarBS as where generarBS = S.flatten . S.map (`R.lookupDom` r) -- | Domain restriction for a relation. Modeled on z. (<|) :: (Ord a, Ord b) => Set a -> Relation a b -> Relation a b s <| r = R.restrictDom s r -- | Range restriction for a relation. Modeled on z. (|>) :: (Ord a, Ord b) => Relation a b -> Set b -> Relation a b r |> t = R.restrictRan t r