module Language.Lexer.Tlex.Machine.State (
    StateNum,
    initialStateNum,

    StateSet,
    emptySet,
    singletonSet,
    listToSet,
    setToList,
    nullSet,
    insertSet,
    intersectSet,
    diffSet,
    unionSet,
    lengthSet,
    memberSet,

    StateMap,
    emptyMap,
    insertOrUpdateMap,
    insertMap,
    lookupMap,
    assocsMap,

    StateArray,
    totalStateMapToArray,
    mapArrayWithIx,
    indexArray,
    arrayAssocs,

    StateGraph,
    stateArrayToGraph,
    liftGraphOp,
    indexGraph,
) where

import           Language.Lexer.Tlex.Prelude

import qualified Data.Array                  as Array
import qualified Data.Graph                  as Graph
import qualified Data.Hashable               as Hashable
import qualified Data.IntMap.Strict          as IntMap
import qualified Data.IntSet                 as IntSet


newtype StateNum = StateNum Int
    deriving (StateNum -> StateNum -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StateNum -> StateNum -> Bool
$c/= :: StateNum -> StateNum -> Bool
== :: StateNum -> StateNum -> Bool
$c== :: StateNum -> StateNum -> Bool
Eq, Eq StateNum
StateNum -> StateNum -> Bool
StateNum -> StateNum -> Ordering
StateNum -> StateNum -> StateNum
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: StateNum -> StateNum -> StateNum
$cmin :: StateNum -> StateNum -> StateNum
max :: StateNum -> StateNum -> StateNum
$cmax :: StateNum -> StateNum -> StateNum
>= :: StateNum -> StateNum -> Bool
$c>= :: StateNum -> StateNum -> Bool
> :: StateNum -> StateNum -> Bool
$c> :: StateNum -> StateNum -> Bool
<= :: StateNum -> StateNum -> Bool
$c<= :: StateNum -> StateNum -> Bool
< :: StateNum -> StateNum -> Bool
$c< :: StateNum -> StateNum -> Bool
compare :: StateNum -> StateNum -> Ordering
$ccompare :: StateNum -> StateNum -> Ordering
Ord, Vertex -> StateNum -> ShowS
[StateNum] -> ShowS
StateNum -> String
forall a.
(Vertex -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StateNum] -> ShowS
$cshowList :: [StateNum] -> ShowS
show :: StateNum -> String
$cshow :: StateNum -> String
showsPrec :: Vertex -> StateNum -> ShowS
$cshowsPrec :: Vertex -> StateNum -> ShowS
Show, Ord StateNum
(StateNum, StateNum) -> Vertex
(StateNum, StateNum) -> [StateNum]
(StateNum, StateNum) -> StateNum -> Bool
(StateNum, StateNum) -> StateNum -> Vertex
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Vertex)
-> ((a, a) -> a -> Vertex)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Vertex)
-> ((a, a) -> Vertex)
-> Ix a
unsafeRangeSize :: (StateNum, StateNum) -> Vertex
$cunsafeRangeSize :: (StateNum, StateNum) -> Vertex
rangeSize :: (StateNum, StateNum) -> Vertex
$crangeSize :: (StateNum, StateNum) -> Vertex
inRange :: (StateNum, StateNum) -> StateNum -> Bool
$cinRange :: (StateNum, StateNum) -> StateNum -> Bool
unsafeIndex :: (StateNum, StateNum) -> StateNum -> Vertex
$cunsafeIndex :: (StateNum, StateNum) -> StateNum -> Vertex
index :: (StateNum, StateNum) -> StateNum -> Vertex
$cindex :: (StateNum, StateNum) -> StateNum -> Vertex
range :: (StateNum, StateNum) -> [StateNum]
$crange :: (StateNum, StateNum) -> [StateNum]
Ix)
    deriving (Eq StateNum
Vertex -> StateNum -> Vertex
StateNum -> Vertex
forall a.
Eq a -> (Vertex -> a -> Vertex) -> (a -> Vertex) -> Hashable a
hash :: StateNum -> Vertex
$chash :: StateNum -> Vertex
hashWithSalt :: Vertex -> StateNum -> Vertex
$chashWithSalt :: Vertex -> StateNum -> Vertex
Hashable.Hashable, Vertex -> StateNum
StateNum -> Vertex
StateNum -> [StateNum]
StateNum -> StateNum
StateNum -> StateNum -> [StateNum]
StateNum -> StateNum -> StateNum -> [StateNum]
forall a.
(a -> a)
-> (a -> a)
-> (Vertex -> a)
-> (a -> Vertex)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: StateNum -> StateNum -> StateNum -> [StateNum]
$cenumFromThenTo :: StateNum -> StateNum -> StateNum -> [StateNum]
enumFromTo :: StateNum -> StateNum -> [StateNum]
$cenumFromTo :: StateNum -> StateNum -> [StateNum]
enumFromThen :: StateNum -> StateNum -> [StateNum]
$cenumFromThen :: StateNum -> StateNum -> [StateNum]
enumFrom :: StateNum -> [StateNum]
$cenumFrom :: StateNum -> [StateNum]
fromEnum :: StateNum -> Vertex
$cfromEnum :: StateNum -> Vertex
toEnum :: Vertex -> StateNum
$ctoEnum :: Vertex -> StateNum
pred :: StateNum -> StateNum
$cpred :: StateNum -> StateNum
succ :: StateNum -> StateNum
$csucc :: StateNum -> StateNum
Enum) via Int

initialStateNum :: StateNum
initialStateNum :: StateNum
initialStateNum = Vertex -> StateNum
StateNum Vertex
0


newtype StateSet = StateSet IntSet.IntSet
    deriving (StateSet -> StateSet -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StateSet -> StateSet -> Bool
$c/= :: StateSet -> StateSet -> Bool
== :: StateSet -> StateSet -> Bool
$c== :: StateSet -> StateSet -> Bool
Eq, Vertex -> StateSet -> ShowS
[StateSet] -> ShowS
StateSet -> String
forall a.
(Vertex -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StateSet] -> ShowS
$cshowList :: [StateSet] -> ShowS
show :: StateSet -> String
$cshow :: StateSet -> String
showsPrec :: Vertex -> StateSet -> ShowS
$cshowsPrec :: Vertex -> StateSet -> ShowS
Show)

instance Hashable.Hashable StateSet where
    hashWithSalt :: Vertex -> StateSet -> Vertex
hashWithSalt Vertex
s (StateSet IntSet
x) = forall a. Hashable a => Vertex -> a -> Vertex
Hashable.hashWithSalt Vertex
s do IntSet -> [Vertex]
IntSet.toAscList IntSet
x

emptySet :: StateSet
emptySet :: StateSet
emptySet = IntSet -> StateSet
StateSet IntSet
IntSet.empty

singletonSet :: StateNum -> StateSet
singletonSet :: StateNum -> StateSet
singletonSet (StateNum Vertex
s) = IntSet -> StateSet
StateSet do Vertex -> IntSet
IntSet.singleton Vertex
s

insertSet :: StateNum -> StateSet -> StateSet
insertSet :: StateNum -> StateSet -> StateSet
insertSet (StateNum Vertex
s) (StateSet IntSet
ss) = IntSet -> StateSet
StateSet do Vertex -> IntSet -> IntSet
IntSet.insert Vertex
s IntSet
ss

listToSet :: [StateNum] -> StateSet
listToSet :: [StateNum] -> StateSet
listToSet [StateNum]
ss = IntSet -> StateSet
StateSet do [Vertex] -> IntSet
IntSet.fromList do coerce :: forall a b. Coercible a b => a -> b
coerce [StateNum]
ss

setToList :: StateSet -> [StateNum]
setToList :: StateSet -> [StateNum]
setToList (StateSet IntSet
ss) = coerce :: forall a b. Coercible a b => a -> b
coerce do IntSet -> [Vertex]
IntSet.toList IntSet
ss

nullSet :: StateSet -> Bool
nullSet :: StateSet -> Bool
nullSet (StateSet IntSet
ss) = IntSet -> Bool
IntSet.null IntSet
ss

intersectSet :: StateSet -> StateSet -> StateSet
intersectSet :: StateSet -> StateSet -> StateSet
intersectSet (StateSet IntSet
ss1) (StateSet IntSet
ss2) = IntSet -> StateSet
StateSet do IntSet -> IntSet -> IntSet
IntSet.intersection IntSet
ss1 IntSet
ss2

diffSet :: StateSet -> StateSet -> StateSet
diffSet :: StateSet -> StateSet -> StateSet
diffSet (StateSet IntSet
ss1) (StateSet IntSet
ss2) = IntSet -> StateSet
StateSet do IntSet -> IntSet -> IntSet
IntSet.difference IntSet
ss1 IntSet
ss2

unionSet :: StateSet -> StateSet -> StateSet
unionSet :: StateSet -> StateSet -> StateSet
unionSet (StateSet IntSet
ss1) (StateSet IntSet
ss2) = IntSet -> StateSet
StateSet do IntSet -> IntSet -> IntSet
IntSet.union IntSet
ss1 IntSet
ss2

lengthSet :: StateSet -> Int
lengthSet :: StateSet -> Vertex
lengthSet (StateSet IntSet
ss) = IntSet -> Vertex
IntSet.size IntSet
ss

memberSet :: StateNum -> StateSet -> Bool
memberSet :: StateNum -> StateSet -> Bool
memberSet (StateNum Vertex
s) (StateSet IntSet
ss) = Vertex -> IntSet -> Bool
IntSet.member Vertex
s IntSet
ss


newtype StateMap a = StateMap (IntMap.IntMap a)
    deriving (StateMap a -> StateMap a -> Bool
forall a. Eq a => StateMap a -> StateMap a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StateMap a -> StateMap a -> Bool
$c/= :: forall a. Eq a => StateMap a -> StateMap a -> Bool
== :: StateMap a -> StateMap a -> Bool
$c== :: forall a. Eq a => StateMap a -> StateMap a -> Bool
Eq, Vertex -> StateMap a -> ShowS
forall a. Show a => Vertex -> StateMap a -> ShowS
forall a. Show a => [StateMap a] -> ShowS
forall a. Show a => StateMap a -> String
forall a.
(Vertex -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StateMap a] -> ShowS
$cshowList :: forall a. Show a => [StateMap a] -> ShowS
show :: StateMap a -> String
$cshow :: forall a. Show a => StateMap a -> String
showsPrec :: Vertex -> StateMap a -> ShowS
$cshowsPrec :: forall a. Show a => Vertex -> StateMap a -> ShowS
Show, forall a b. a -> StateMap b -> StateMap a
forall a b. (a -> b) -> StateMap a -> StateMap b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> StateMap b -> StateMap a
$c<$ :: forall a b. a -> StateMap b -> StateMap a
fmap :: forall a b. (a -> b) -> StateMap a -> StateMap b
$cfmap :: forall a b. (a -> b) -> StateMap a -> StateMap b
Functor)

emptyMap :: StateMap a
emptyMap :: forall a. StateMap a
emptyMap = forall a. IntMap a -> StateMap a
StateMap forall a. IntMap a
IntMap.empty

insertMap :: StateNum -> a -> StateMap a -> StateMap a
insertMap :: forall a. StateNum -> a -> StateMap a -> StateMap a
insertMap (StateNum Vertex
k) a
x (StateMap IntMap a
m) = forall a. IntMap a -> StateMap a
StateMap do forall a. Vertex -> a -> IntMap a -> IntMap a
IntMap.insert Vertex
k a
x IntMap a
m

insertOrUpdateMap :: StateNum -> a -> (a -> a) -> StateMap a -> StateMap a
insertOrUpdateMap :: forall a. StateNum -> a -> (a -> a) -> StateMap a -> StateMap a
insertOrUpdateMap (StateNum Vertex
k) ~a
dx ~a -> a
uf (StateMap IntMap a
m) = forall a. IntMap a -> StateMap a
StateMap case forall a. Vertex -> IntMap a -> Maybe a
IntMap.lookup Vertex
k IntMap a
m of
    Maybe a
Nothing -> forall a. Vertex -> a -> IntMap a -> IntMap a
IntMap.insert Vertex
k a
dx IntMap a
m
    Just a
x  -> forall a. Vertex -> a -> IntMap a -> IntMap a
IntMap.insert Vertex
k (a -> a
uf a
x) IntMap a
m

lookupMap :: StateNum -> StateMap a -> Maybe a
lookupMap :: forall a. StateNum -> StateMap a -> Maybe a
lookupMap (StateNum Vertex
sn) (StateMap IntMap a
m) = forall a. Vertex -> IntMap a -> Maybe a
IntMap.lookup Vertex
sn IntMap a
m

assocsMap :: StateMap a -> [(StateNum, a)]
assocsMap :: forall a. StateMap a -> [(StateNum, a)]
assocsMap (StateMap IntMap a
m) = coerce :: forall a b. Coercible a b => a -> b
coerce do forall a. IntMap a -> [(Vertex, a)]
IntMap.assocs IntMap a
m


newtype StateArray a = StateArray (Array.Array Int a)
    deriving (StateArray a -> StateArray a -> Bool
forall a. Eq a => StateArray a -> StateArray a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StateArray a -> StateArray a -> Bool
$c/= :: forall a. Eq a => StateArray a -> StateArray a -> Bool
== :: StateArray a -> StateArray a -> Bool
$c== :: forall a. Eq a => StateArray a -> StateArray a -> Bool
Eq, Vertex -> StateArray a -> ShowS
forall a. Show a => Vertex -> StateArray a -> ShowS
forall a. Show a => [StateArray a] -> ShowS
forall a. Show a => StateArray a -> String
forall a.
(Vertex -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StateArray a] -> ShowS
$cshowList :: forall a. Show a => [StateArray a] -> ShowS
show :: StateArray a -> String
$cshow :: forall a. Show a => StateArray a -> String
showsPrec :: Vertex -> StateArray a -> ShowS
$cshowsPrec :: forall a. Show a => Vertex -> StateArray a -> ShowS
Show, forall a b. a -> StateArray b -> StateArray a
forall a b. (a -> b) -> StateArray a -> StateArray b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> StateArray b -> StateArray a
$c<$ :: forall a b. a -> StateArray b -> StateArray a
fmap :: forall a b. (a -> b) -> StateArray a -> StateArray b
$cfmap :: forall a b. (a -> b) -> StateArray a -> StateArray b
Functor, forall a. Eq a => a -> StateArray a -> Bool
forall a. Num a => StateArray a -> a
forall a. Ord a => StateArray a -> a
forall m. Monoid m => StateArray m -> m
forall a. StateArray a -> Bool
forall a. StateArray a -> Vertex
forall a. StateArray a -> [a]
forall a. (a -> a -> a) -> StateArray a -> a
forall m a. Monoid m => (a -> m) -> StateArray a -> m
forall b a. (b -> a -> b) -> b -> StateArray a -> b
forall a b. (a -> b -> b) -> b -> StateArray a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Vertex)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
product :: forall a. Num a => StateArray a -> a
$cproduct :: forall a. Num a => StateArray a -> a
sum :: forall a. Num a => StateArray a -> a
$csum :: forall a. Num a => StateArray a -> a
minimum :: forall a. Ord a => StateArray a -> a
$cminimum :: forall a. Ord a => StateArray a -> a
maximum :: forall a. Ord a => StateArray a -> a
$cmaximum :: forall a. Ord a => StateArray a -> a
elem :: forall a. Eq a => a -> StateArray a -> Bool
$celem :: forall a. Eq a => a -> StateArray a -> Bool
length :: forall a. StateArray a -> Vertex
$clength :: forall a. StateArray a -> Vertex
null :: forall a. StateArray a -> Bool
$cnull :: forall a. StateArray a -> Bool
toList :: forall a. StateArray a -> [a]
$ctoList :: forall a. StateArray a -> [a]
foldl1 :: forall a. (a -> a -> a) -> StateArray a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> StateArray a -> a
foldr1 :: forall a. (a -> a -> a) -> StateArray a -> a
$cfoldr1 :: forall a. (a -> a -> a) -> StateArray a -> a
foldl' :: forall b a. (b -> a -> b) -> b -> StateArray a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> StateArray a -> b
foldl :: forall b a. (b -> a -> b) -> b -> StateArray a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> StateArray a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> StateArray a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> StateArray a -> b
foldr :: forall a b. (a -> b -> b) -> b -> StateArray a -> b
$cfoldr :: forall a b. (a -> b -> b) -> b -> StateArray a -> b
foldMap' :: forall m a. Monoid m => (a -> m) -> StateArray a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> StateArray a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> StateArray a -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> StateArray a -> m
fold :: forall m. Monoid m => StateArray m -> m
$cfold :: forall m. Monoid m => StateArray m -> m
Foldable)

totalStateMapToArray :: StateNum -> StateMap a -> StateArray a
totalStateMapToArray :: forall a. StateNum -> StateMap a -> StateArray a
totalStateMapToArray (StateNum Vertex
boundState) (StateMap IntMap a
m) = forall a. Array Vertex a -> StateArray a
StateArray
    do forall i e. Ix i => (i, i) -> [(i, e)] -> Array i e
Array.array (Vertex
0, forall a. Enum a => a -> a
pred Vertex
boundState) do forall a. IntMap a -> [(Vertex, a)]
IntMap.toAscList IntMap a
m

mapArrayWithIx :: (StateNum -> a -> a) -> StateArray a -> StateArray a
mapArrayWithIx :: forall a. (StateNum -> a -> a) -> StateArray a -> StateArray a
mapArrayWithIx StateNum -> a -> a
f (StateArray Array Vertex a
arr) = forall a. Array Vertex a -> StateArray a
StateArray
    do forall i e. Ix i => (i, i) -> [e] -> Array i e
Array.listArray
        do forall i e. Array i e -> (i, i)
Array.bounds Array Vertex a
arr
        do [ StateNum -> a -> a
f (Vertex -> StateNum
StateNum Vertex
i) a
x | (Vertex
i, a
x) <- forall i e. Ix i => Array i e -> [(i, e)]
Array.assocs Array Vertex a
arr ]

indexArray :: StateArray a -> StateNum -> a
indexArray :: forall a. StateArray a -> StateNum -> a
indexArray (StateArray Array Vertex a
arr) (StateNum Vertex
i) = Array Vertex a
arr forall i e. Ix i => Array i e -> i -> e
Array.! Vertex
i

arrayAssocs :: StateArray a -> [(StateNum, a)]
arrayAssocs :: forall a. StateArray a -> [(StateNum, a)]
arrayAssocs (StateArray Array Vertex a
arr) = coerce :: forall a b. Coercible a b => a -> b
coerce do forall i e. Ix i => Array i e -> [(i, e)]
Array.assocs Array Vertex a
arr


newtype StateGraph = StateGraph Graph.Graph

stateArrayToGraph :: StateArray [StateNum] -> StateGraph
stateArrayToGraph :: StateArray [StateNum] -> StateGraph
stateArrayToGraph (StateArray Array Vertex [StateNum]
m) = Graph -> StateGraph
StateGraph do coerce :: forall a b. Coercible a b => a -> b
coerce Array Vertex [StateNum]
m

liftGraphOp :: (Graph.Graph -> Graph.Graph) -> StateGraph -> StateGraph
liftGraphOp :: (Graph -> Graph) -> StateGraph -> StateGraph
liftGraphOp Graph -> Graph
f StateGraph
x = coerce :: forall a b. Coercible a b => a -> b
coerce Graph -> Graph
f StateGraph
x

indexGraph :: StateGraph -> StateNum -> [StateNum]
indexGraph :: StateGraph -> StateNum -> [StateNum]
indexGraph (StateGraph Graph
x) (StateNum Vertex
i) = coerce :: forall a b. Coercible a b => a -> b
coerce do Graph
x forall i e. Ix i => Array i e -> i -> e
Array.! Vertex
i