module Data.Allen.Relation ( converse
, testRelation
, testRelationSet
, testRelationBits
, composeSingle
, compose
, bitsFromString
) where
import Data.Allen.Types
import Data.Bits
import qualified Data.Map.Strict as Map
import qualified Data.Vector.Unboxed as U
converseLookup :: [(RelationBits, RelationBits)]
converseLookup :: [(RelationBits, RelationBits)]
converseLookup = [RelationBits] -> [RelationBits] -> [(RelationBits, RelationBits)]
forall a b. [a] -> [b] -> [(a, b)]
zip [RelationBits]
bits ([RelationBits] -> [RelationBits]
forall a. [a] -> [a]
reverse [RelationBits]
bits)
where bits :: [RelationBits]
bits = (Relation -> RelationBits) -> [Relation] -> [RelationBits]
forall a b. (a -> b) -> [a] -> [b]
map Relation -> RelationBits
toBits [Relation]
allRelations
converse :: RelationBits -> RelationBits
converse :: RelationBits -> RelationBits
converse RelationBits
0 = RelationBits
0
converse RelationBits
x = [RelationBits] -> RelationBits
relationUnion ([RelationBits] -> RelationBits) -> [RelationBits] -> RelationBits
forall a b. (a -> b) -> a -> b
$ (IntervalID -> RelationBits) -> [IntervalID] -> [RelationBits]
forall a b. (a -> b) -> [a] -> [b]
map IntervalID -> RelationBits
func [IntervalID
0 .. Relation -> IntervalID
forall a. Enum a => a -> IntervalID
fromEnum (Relation
forall a. Bounded a => a
maxBound :: Relation)]
where func :: IntervalID -> RelationBits
func IntervalID
i | RelationBits -> IntervalID -> Bool
forall a. Bits a => a -> IntervalID -> Bool
testBit RelationBits
x IntervalID
i = (RelationBits, RelationBits) -> RelationBits
forall a b. (a, b) -> b
snd ((RelationBits, RelationBits) -> RelationBits)
-> (RelationBits, RelationBits) -> RelationBits
forall a b. (a -> b) -> a -> b
$ [(RelationBits, RelationBits)] -> (RelationBits, RelationBits)
forall a. HasCallStack => [a] -> a
head ([(RelationBits, RelationBits)] -> (RelationBits, RelationBits))
-> [(RelationBits, RelationBits)] -> (RelationBits, RelationBits)
forall a b. (a -> b) -> a -> b
$ ((RelationBits, RelationBits) -> Bool)
-> [(RelationBits, RelationBits)] -> [(RelationBits, RelationBits)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((RelationBits -> RelationBits -> Bool
forall a. Eq a => a -> a -> Bool
== IntervalID -> RelationBits
forall a. Bits a => IntervalID -> a
bit IntervalID
i) (RelationBits -> Bool)
-> ((RelationBits, RelationBits) -> RelationBits)
-> (RelationBits, RelationBits)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (RelationBits, RelationBits) -> RelationBits
forall a b. (a, b) -> a
fst) [(RelationBits, RelationBits)]
converseLookup
| Bool
otherwise = RelationBits
0
testRelation :: Relation -> IntervalID -> IntervalID -> Allen Bool
testRelation :: Relation -> IntervalID -> IntervalID -> Allen Bool
testRelation Relation
r IntervalID
id1 IntervalID
id2 = do
RelationBits
relations <- RelationBits
-> IntervalID -> Map IntervalID RelationBits -> RelationBits
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault RelationBits
0 IntervalID
id2 (Map IntervalID RelationBits -> RelationBits)
-> (Interval -> Map IntervalID RelationBits)
-> Interval
-> RelationBits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval -> Map IntervalID RelationBits
intervalRelations (Interval -> RelationBits)
-> StateT IntervalGraph Identity Interval
-> StateT IntervalGraph Identity RelationBits
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntervalID -> StateT IntervalGraph Identity Interval
fromID IntervalID
id1
Bool -> Allen Bool
forall a. a -> StateT IntervalGraph Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Allen Bool) -> Bool -> Allen Bool
forall a b. (a -> b) -> a -> b
$ Relation -> RelationBits
toBits Relation
r RelationBits -> RelationBits -> RelationBits
forall a. Bits a => a -> a -> a
.&. RelationBits
relations RelationBits -> RelationBits -> Bool
forall a. Eq a => a -> a -> Bool
/= RelationBits
0
testRelationSet :: [Relation] -> IntervalID -> IntervalID -> Allen Bool
testRelationSet :: [Relation] -> IntervalID -> IntervalID -> Allen Bool
testRelationSet [Relation]
r = RelationBits -> IntervalID -> IntervalID -> Allen Bool
testRelationBits ([RelationBits] -> RelationBits
relationUnion ([RelationBits] -> RelationBits) -> [RelationBits] -> RelationBits
forall a b. (a -> b) -> a -> b
$ (Relation -> RelationBits) -> [Relation] -> [RelationBits]
forall a b. (a -> b) -> [a] -> [b]
map Relation -> RelationBits
toBits [Relation]
r)
testRelationBits :: RelationBits -> IntervalID -> IntervalID -> Allen Bool
testRelationBits :: RelationBits -> IntervalID -> IntervalID -> Allen Bool
testRelationBits RelationBits
r IntervalID
id1 IntervalID
id2 = do
RelationBits
relations <- RelationBits
-> IntervalID -> Map IntervalID RelationBits -> RelationBits
forall k a. Ord k => a -> k -> Map k a -> a
Map.findWithDefault RelationBits
0 IntervalID
id2 (Map IntervalID RelationBits -> RelationBits)
-> (Interval -> Map IntervalID RelationBits)
-> Interval
-> RelationBits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Interval -> Map IntervalID RelationBits
intervalRelations (Interval -> RelationBits)
-> StateT IntervalGraph Identity Interval
-> StateT IntervalGraph Identity RelationBits
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IntervalID -> StateT IntervalGraph Identity Interval
fromID IntervalID
id1
Bool -> Allen Bool
forall a. a -> StateT IntervalGraph Identity a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> Allen Bool) -> Bool -> Allen Bool
forall a b. (a -> b) -> a -> b
$ RelationBits
r RelationBits -> RelationBits -> RelationBits
forall a. Bits a => a -> a -> a
.&. RelationBits
relations RelationBits -> RelationBits -> Bool
forall a. Ord a => a -> a -> Bool
>= RelationBits
r
relationFromChar :: Char -> Relation
relationFromChar :: Char -> Relation
relationFromChar Char
x = case Char
x of
Char
'p' -> Relation
Precedes
Char
'm' -> Relation
Meets
Char
'o' -> Relation
Overlaps
Char
'F' -> Relation
FinishedBy
Char
'D' -> Relation
Contains
Char
's' -> Relation
Starts
Char
'e' -> Relation
Equals
Char
'S' -> Relation
StartedBy
Char
'd' -> Relation
During
Char
'f' -> Relation
Finishes
Char
'O' -> Relation
OverlappedBy
Char
'M' -> Relation
MetBy
Char
'P' -> Relation
PrecededBy
Char
_ -> [Char] -> Relation
forall a. HasCallStack => [Char] -> a
error ([Char] -> Relation) -> [Char] -> Relation
forall a b. (a -> b) -> a -> b
$ [Char]
"relationFromChar: invalid relation " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char
x]
bitsFromString :: String -> RelationBits
bitsFromString :: [Char] -> RelationBits
bitsFromString [Char]
x | [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"full" = [Relation] -> RelationBits
rBits [Relation]
allRelations
| [Char]
x [Char] -> [Char] -> Bool
forall a. Eq a => a -> a -> Bool
== [Char]
"concur" = [Relation] -> RelationBits
rBits [Relation
Overlaps .. Relation
OverlappedBy]
| Bool
otherwise = [Relation] -> RelationBits
rBits ([Relation] -> RelationBits) -> [Relation] -> RelationBits
forall a b. (a -> b) -> a -> b
$ (Char -> Relation) -> [Char] -> [Relation]
forall a b. (a -> b) -> [a] -> [b]
map Char -> Relation
relationFromChar [Char]
x
where rBits :: [Relation] -> RelationBits
rBits = [RelationBits] -> RelationBits
relationUnion ([RelationBits] -> RelationBits)
-> ([Relation] -> [RelationBits]) -> [Relation] -> RelationBits
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Relation -> RelationBits) -> [Relation] -> [RelationBits]
forall a b. (a -> b) -> [a] -> [b]
map Relation -> RelationBits
toBits
composeLookup :: U.Vector RelationBits
composeLookup :: Vector RelationBits
composeLookup = [RelationBits] -> Vector RelationBits
forall a. Unbox a => [a] -> Vector a
U.fromList ([RelationBits] -> Vector RelationBits)
-> [RelationBits] -> Vector RelationBits
forall a b. (a -> b) -> a -> b
$ ([Char] -> RelationBits) -> [[Char]] -> [RelationBits]
forall a b. (a -> b) -> [a] -> [b]
map [Char] -> RelationBits
bitsFromString [[Char]]
table
where table :: [[Char]]
table = [ [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"pmosd", [Char]
"pmosd", [Char]
"pmosd", [Char]
"pmosd", [Char]
"full"
, [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"p", [Char]
"m", [Char]
"m", [Char]
"m", [Char]
"osd", [Char]
"osd", [Char]
"osd", [Char]
"Fef", [Char]
"DSOMP"
, [Char]
"p", [Char]
"p", [Char]
"pmo", [Char]
"pmo", [Char]
"pmoFD", [Char]
"o", [Char]
"o", [Char]
"oFD", [Char]
"osd", [Char]
"osd", [Char]
"concur", [Char]
"DSO", [Char]
"DSOMP"
, [Char]
"p", [Char]
"m", [Char]
"o", [Char]
"F", [Char]
"D", [Char]
"o", [Char]
"F", [Char]
"D", [Char]
"osd", [Char]
"Fef", [Char]
"DSO", [Char]
"DSO", [Char]
"DSOMP"
, [Char]
"pmoFD", [Char]
"oFD", [Char]
"oFD", [Char]
"D", [Char]
"D", [Char]
"oFD", [Char]
"D", [Char]
"D", [Char]
"concur", [Char]
"DSO", [Char]
"DSO", [Char]
"DSO", [Char]
"DSOMP"
, [Char]
"p", [Char]
"p", [Char]
"pmo", [Char]
"pmo", [Char]
"pmoFD", [Char]
"s", [Char]
"s", [Char]
"seS", [Char]
"d", [Char]
"d", [Char]
"dfO", [Char]
"M", [Char]
"P"
, [Char]
"p", [Char]
"m", [Char]
"o", [Char]
"F", [Char]
"D", [Char]
"s", [Char]
"e", [Char]
"S", [Char]
"d", [Char]
"f", [Char]
"O", [Char]
"M", [Char]
"P"
, [Char]
"pmoFD", [Char]
"oFD", [Char]
"oFD", [Char]
"D", [Char]
"D", [Char]
"seS", [Char]
"S", [Char]
"S", [Char]
"dfO", [Char]
"O", [Char]
"O", [Char]
"M", [Char]
"P"
, [Char]
"p", [Char]
"p", [Char]
"pmosd", [Char]
"pmosd", [Char]
"full", [Char]
"d", [Char]
"d", [Char]
"dfOMP", [Char]
"d", [Char]
"d", [Char]
"dfOMP", [Char]
"P", [Char]
"P"
, [Char]
"p", [Char]
"m", [Char]
"osd", [Char]
"Fef", [Char]
"DSOMP", [Char]
"d", [Char]
"f", [Char]
"OMP", [Char]
"d", [Char]
"f", [Char]
"OMP", [Char]
"P", [Char]
"P"
, [Char]
"pmoFD", [Char]
"oFD", [Char]
"concur", [Char]
"DSO", [Char]
"DSOMP", [Char]
"dfO", [Char]
"O", [Char]
"OMP", [Char]
"dfO", [Char]
"O", [Char]
"OMP", [Char]
"P", [Char]
"P"
, [Char]
"pmoFD", [Char]
"seS", [Char]
"dfO", [Char]
"M", [Char]
"P", [Char]
"dfO", [Char]
"M", [Char]
"P", [Char]
"dfO", [Char]
"M", [Char]
"P", [Char]
"P", [Char]
"P"
, [Char]
"full", [Char]
"dfOMP", [Char]
"dfOMOP", [Char]
"P", [Char]
"P", [Char]
"dfOMP", [Char]
"P", [Char]
"P", [Char]
"dfOMP", [Char]
"P", [Char]
"P", [Char]
"P", [Char]
"P"
]
composeSingle :: Relation -> Relation -> RelationBits
composeSingle :: Relation -> Relation -> RelationBits
composeSingle Relation
r1 Relation
r2 = Vector RelationBits
composeLookup Vector RelationBits -> IntervalID -> RelationBits
forall a. Unbox a => Vector a -> IntervalID -> a
U.! IntervalID
index
where index :: IntervalID
index = IntervalID
13 IntervalID -> IntervalID -> IntervalID
forall a. Num a => a -> a -> a
* Relation -> IntervalID
forall a. Enum a => a -> IntervalID
fromEnum Relation
r1 IntervalID -> IntervalID -> IntervalID
forall a. Num a => a -> a -> a
+ Relation -> IntervalID
forall a. Enum a => a -> IntervalID
fromEnum Relation
r2
compose :: RelationBits -> RelationBits -> RelationBits
compose :: RelationBits -> RelationBits -> RelationBits
compose RelationBits
r1 RelationBits
r2 = [RelationBits] -> RelationBits
relationUnion [Relation -> Relation -> RelationBits
composeSingle Relation
a Relation
b | Relation
a <- RelationBits -> [Relation]
fromBits RelationBits
r1, Relation
b <- RelationBits -> [Relation]
fromBits RelationBits
r2]