module Text.Regex.TDFA.TDFA(patternToRegex,DFA(..),DT(..)
,examineDFA,nfaToDFA,dfaMap) where
import Data.Monoid as Mon(Monoid(..))
import Control.Monad.State(State,MonadState(..),execState)
import Data.Array.IArray(Array,(!),bounds,)
import Data.IntMap(IntMap)
import qualified Data.IntMap as IMap(empty,keys,delete,null,lookup,fromDistinctAscList
,member,unionWith,singleton,union
,toAscList,Key,elems,toList,insert
,insertWith,insertWithKey)
import Data.IntMap.CharMap2(CharMap(..))
import qualified Data.IntMap.CharMap2 as Map(empty)
import qualified Data.IntSet as ISet(empty,singleton,null)
import Data.List(foldl')
import qualified Data.Map (Map,empty,member,insert,elems)
import Data.Sequence as S((|>),)
import Text.Regex.TDFA.Common
import Text.Regex.TDFA.IntArrTrieSet(TrieSet)
import qualified Text.Regex.TDFA.IntArrTrieSet as Trie(lookupAsc,fromSinglesMerge)
import Text.Regex.TDFA.Pattern(Pattern)
import Text.Regex.TDFA.TNFA(patternToNFA)
err :: String -> a
err :: String -> a
err s :: String
s = String -> String -> a
forall a. String -> String -> a
common_error "Text.Regex.TDFA.TDFA" String
s
dlose :: DFA
dlose :: DFA
dlose = DFA :: SetIndex -> DT -> DFA
DFA { d_id :: SetIndex
d_id = SetIndex
ISet.empty
, d_dt :: DT
d_dt = Simple' :: IntMap Instructions -> CharMap Transition -> Transition -> DT
Simple' { dt_win :: IntMap Instructions
dt_win = IntMap Instructions
forall a. IntMap a
IMap.empty
, dt_trans :: CharMap Transition
dt_trans = CharMap Transition
forall a. CharMap a
Map.empty
, dt_other :: Transition
dt_other = DFA -> DFA -> DTrans -> Transition
Transition DFA
dlose DFA
dlose DTrans
forall a. Monoid a => a
mempty } }
{-# INLINE makeDFA #-}
makeDFA :: SetIndex -> DT -> DFA
makeDFA :: SetIndex -> DT -> DFA
makeDFA i :: SetIndex
i dt :: DT
dt = SetIndex -> DT -> DFA
DFA SetIndex
i DT
dt
nfaToDFA :: ((Index,Array Index QNFA),Array Tag OP,Array GroupIndex [GroupInfo])
-> CompOption -> ExecOption
-> Regex
nfaToDFA :: ((Index, Array Index QNFA), Array Index OP,
Array Index [GroupInfo])
-> CompOption -> ExecOption -> Regex
nfaToDFA ((startIndex :: Index
startIndex,aQNFA :: Array Index QNFA
aQNFA),aTagOp :: Array Index OP
aTagOp,aGroupInfo :: Array Index [GroupInfo]
aGroupInfo) co :: CompOption
co eo :: ExecOption
eo = DFA
-> Index
-> (Index, Index)
-> (Index, Index)
-> TrieSet DFA
-> Array Index OP
-> Array Index [GroupInfo]
-> Bool
-> CompOption
-> ExecOption
-> Regex
Regex DFA
dfa Index
startIndex (Index, Index)
indexBounds (Index, Index)
tagBounds TrieSet DFA
trie Array Index OP
aTagOp Array Index [GroupInfo]
aGroupInfo Bool
ifa CompOption
co ExecOption
eo where
dfa :: DFA
dfa = [Index] -> DFA
indexesToDFA [Index
startIndex]
indexBounds :: (Index, Index)
indexBounds = Array Index QNFA -> (Index, Index)
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> (i, i)
bounds Array Index QNFA
aQNFA
tagBounds :: (Index, Index)
tagBounds = Array Index OP -> (Index, Index)
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> (i, i)
bounds Array Index OP
aTagOp
ifa :: Bool
ifa = (Bool -> Bool
not (CompOption -> Bool
multiline CompOption
co)) Bool -> Bool -> Bool
&& DFA -> Bool
isDFAFrontAnchored DFA
dfa
indexesToDFA :: [Index] -> DFA
indexesToDFA = {-# SCC "nfaToDFA.indexesToDFA" #-} TrieSet DFA -> [Index] -> DFA
forall v. TrieSet v -> [Index] -> v
Trie.lookupAsc TrieSet DFA
trie
trie :: TrieSet DFA
trie :: TrieSet DFA
trie = DFA
-> (DFA -> DFA -> DFA)
-> (Index, Index)
-> (Index -> DFA)
-> TrieSet DFA
forall v.
v -> (v -> v -> v) -> (Index, Index) -> (Index -> v) -> TrieSet v
Trie.fromSinglesMerge DFA
dlose DFA -> DFA -> DFA
mergeDFA (Array Index QNFA -> (Index, Index)
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> (i, i)
bounds Array Index QNFA
aQNFA) Index -> DFA
indexToDFA
newTransition :: DTrans -> Transition
newTransition :: DTrans -> Transition
newTransition dtrans :: DTrans
dtrans = Transition :: DFA -> DFA -> DTrans -> Transition
Transition { trans_many :: DFA
trans_many = [Index] -> DFA
indexesToDFA (DTrans -> [Index]
forall a. IntMap a -> [Index]
IMap.keys DTrans
dtransWithSpawn)
, trans_single :: DFA
trans_single = [Index] -> DFA
indexesToDFA (DTrans -> [Index]
forall a. IntMap a -> [Index]
IMap.keys DTrans
dtrans)
, trans_how :: DTrans
trans_how = DTrans
dtransWithSpawn }
where dtransWithSpawn :: DTrans
dtransWithSpawn = DTrans -> DTrans
addSpawn DTrans
dtrans
makeTransition :: DTrans -> Transition
makeTransition :: DTrans -> Transition
makeTransition dtrans :: DTrans
dtrans | Bool
hasSpawn = Transition :: DFA -> DFA -> DTrans -> Transition
Transition { trans_many :: DFA
trans_many = [Index] -> DFA
indexesToDFA (DTrans -> [Index]
forall a. IntMap a -> [Index]
IMap.keys DTrans
dtrans)
, trans_single :: DFA
trans_single = [Index] -> DFA
indexesToDFA (DTrans -> [Index]
forall a. IntMap a -> [Index]
IMap.keys (Index -> DTrans -> DTrans
forall a. Index -> IntMap a -> IntMap a
IMap.delete Index
startIndex DTrans
dtrans))
, trans_how :: DTrans
trans_how = DTrans
dtrans }
| Bool
otherwise = Transition :: DFA -> DFA -> DTrans -> Transition
Transition { trans_many :: DFA
trans_many = [Index] -> DFA
indexesToDFA (DTrans -> [Index]
forall a. IntMap a -> [Index]
IMap.keys DTrans
dtrans)
, trans_single :: DFA
trans_single = [Index] -> DFA
indexesToDFA (DTrans -> [Index]
forall a. IntMap a -> [Index]
IMap.keys DTrans
dtrans)
, trans_how :: DTrans
trans_how = DTrans
dtrans }
where hasSpawn :: Bool
hasSpawn = Bool
-> (IntMap (DoPa, Instructions) -> Bool)
-> Maybe (IntMap (DoPa, Instructions))
-> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False IntMap (DoPa, Instructions) -> Bool
forall a. IntMap a -> Bool
IMap.null (Index -> DTrans -> Maybe (IntMap (DoPa, Instructions))
forall a. Index -> IntMap a -> Maybe a
IMap.lookup Index
startIndex DTrans
dtrans)
addSpawn :: DTrans -> DTrans
addSpawn :: DTrans -> DTrans
addSpawn dtrans :: DTrans
dtrans | Index -> DTrans -> Bool
forall a. Index -> IntMap a -> Bool
IMap.member Index
startIndex DTrans
dtrans = DTrans
dtrans
| Bool
otherwise = Index -> IntMap (DoPa, Instructions) -> DTrans -> DTrans
forall a. Index -> a -> IntMap a -> IntMap a
IMap.insert Index
startIndex IntMap (DoPa, Instructions)
forall a. Monoid a => a
mempty DTrans
dtrans
indexToDFA :: Index -> DFA
indexToDFA :: Index -> DFA
indexToDFA i :: Index
i = {-# SCC "nfaToDFA.indexToDFA" #-} SetIndex -> DT -> DFA
makeDFA (Index -> SetIndex
ISet.singleton Index
source) (QT -> DT
qtToDT QT
qtIn)
where
(QNFA {q_id :: QNFA -> Index
q_id = Index
source,q_qt :: QNFA -> QT
q_qt = QT
qtIn}) = Array Index QNFA
aQNFAArray Index QNFA -> Index -> QNFA
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Index
i
qtToDT :: QT -> DT
qtToDT :: QT -> DT
qtToDT (Testing {qt_test :: QT -> WhichTest
qt_test=WhichTest
wt, qt_dopas :: QT -> EnumSet DoPa
qt_dopas=EnumSet DoPa
dopas, qt_a :: QT -> QT
qt_a=QT
a, qt_b :: QT -> QT
qt_b=QT
b}) =
Testing' :: WhichTest -> EnumSet DoPa -> DT -> DT -> DT
Testing' { dt_test :: WhichTest
dt_test = WhichTest
wt
, dt_dopas :: EnumSet DoPa
dt_dopas = EnumSet DoPa
dopas
, dt_a :: DT
dt_a = QT -> DT
qtToDT QT
a
, dt_b :: DT
dt_b = QT -> DT
qtToDT QT
b }
qtToDT (Simple {qt_win :: QT -> WinTags
qt_win=WinTags
w, qt_trans :: QT -> CharMap QTrans
qt_trans=CharMap QTrans
t, qt_other :: QT -> QTrans
qt_other=QTrans
o}) =
Simple' :: IntMap Instructions -> CharMap Transition -> Transition -> DT
Simple' { dt_win :: IntMap Instructions
dt_win = IntMap Instructions
makeWinner
, dt_trans :: CharMap Transition
dt_trans = (QTrans -> Transition) -> CharMap QTrans -> CharMap Transition
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap QTrans -> Transition
qtransToDFA CharMap QTrans
t
, dt_other :: Transition
dt_other = QTrans -> Transition
qtransToDFA QTrans
o}
where
makeWinner :: IntMap Instructions
makeWinner :: IntMap Instructions
makeWinner | WinTags -> Bool
noWin WinTags
w = IntMap Instructions
forall a. IntMap a
IMap.empty
| Bool
otherwise = Index -> Instructions -> IntMap Instructions
forall a. Index -> a -> IntMap a
IMap.singleton Index
source (WinTags -> Instructions
cleanWin WinTags
w)
qtransToDFA :: QTrans -> Transition
qtransToDFA :: QTrans -> Transition
qtransToDFA qtrans :: QTrans
qtrans = {-# SCC "nfaToDFA.indexToDFA.qtransToDFA" #-}
DTrans -> Transition
newTransition DTrans
dtrans
where
dtrans :: DTrans
dtrans :: DTrans
dtrans =[(Index, IntMap (DoPa, Instructions))] -> DTrans
forall a. [(Index, a)] -> IntMap a
IMap.fromDistinctAscList ([(Index, IntMap (DoPa, Instructions))] -> DTrans)
-> ([(Index, (DoPa, Instructions))]
-> [(Index, IntMap (DoPa, Instructions))])
-> [(Index, (DoPa, Instructions))]
-> DTrans
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((DoPa, Instructions) -> IntMap (DoPa, Instructions))
-> [(Index, (DoPa, Instructions))]
-> [(Index, IntMap (DoPa, Instructions))]
forall (f :: * -> *) t1 t2 t.
Functor f =>
(t1 -> t2) -> f (t, t1) -> f (t, t2)
mapSnd (Index -> (DoPa, Instructions) -> IntMap (DoPa, Instructions)
forall a. Index -> a -> IntMap a
IMap.singleton Index
source) ([(Index, (DoPa, Instructions))] -> DTrans)
-> [(Index, (DoPa, Instructions))] -> DTrans
forall a b. (a -> b) -> a -> b
$ [(Index, (DoPa, Instructions))]
best
best :: [(Index ,(DoPa,Instructions))]
best :: [(Index, (DoPa, Instructions))]
best = Array Index OP -> QTrans -> [(Index, (DoPa, Instructions))]
pickQTrans Array Index OP
aTagOp (QTrans -> [(Index, (DoPa, Instructions))])
-> QTrans -> [(Index, (DoPa, Instructions))]
forall a b. (a -> b) -> a -> b
$ QTrans
qtrans
mergeDFA :: DFA -> DFA -> DFA
mergeDFA :: DFA -> DFA -> DFA
mergeDFA d1 :: DFA
d1 d2 :: DFA
d2 = {-# SCC "nfaToDFA.mergeDFA" #-} SetIndex -> DT -> DFA
makeDFA SetIndex
i DT
dt
where
i :: SetIndex
i = DFA -> SetIndex
d_id DFA
d1 SetIndex -> SetIndex -> SetIndex
forall a. Monoid a => a -> a -> a
`mappend` DFA -> SetIndex
d_id DFA
d2
dt :: DT
dt = DFA -> DT
d_dt DFA
d1 DT -> DT -> DT
`mergeDT` DFA -> DT
d_dt DFA
d2
mergeDT,nestDT :: DT -> DT -> DT
mergeDT :: DT -> DT -> DT
mergeDT (Simple' w1 :: IntMap Instructions
w1 t1 :: CharMap Transition
t1 o1 :: Transition
o1) (Simple' w2 :: IntMap Instructions
w2 t2 :: CharMap Transition
t2 o2 :: Transition
o2) = IntMap Instructions -> CharMap Transition -> Transition -> DT
Simple' IntMap Instructions
w CharMap Transition
t Transition
o
where
w :: IntMap Instructions
w = IntMap Instructions
w1 IntMap Instructions -> IntMap Instructions -> IntMap Instructions
forall a. Monoid a => a -> a -> a
`mappend` IntMap Instructions
w2
t :: CharMap Transition
t = CharMap Transition
fuseDTrans
o :: Transition
o = Transition -> Transition -> Transition
mergeDTrans Transition
o1 Transition
o2
mergeDTrans :: Transition -> Transition -> Transition
mergeDTrans :: Transition -> Transition -> Transition
mergeDTrans (Transition {trans_how :: Transition -> DTrans
trans_how=DTrans
dt1}) (Transition {trans_how :: Transition -> DTrans
trans_how=DTrans
dt2}) = DTrans -> Transition
makeTransition DTrans
dtrans
where dtrans :: DTrans
dtrans = (IntMap (DoPa, Instructions)
-> IntMap (DoPa, Instructions) -> IntMap (DoPa, Instructions))
-> DTrans -> DTrans -> DTrans
forall a. (a -> a -> a) -> IntMap a -> IntMap a -> IntMap a
IMap.unionWith IntMap (DoPa, Instructions)
-> IntMap (DoPa, Instructions) -> IntMap (DoPa, Instructions)
forall a. IntMap a -> IntMap a -> IntMap a
IMap.union DTrans
dt1 DTrans
dt2
fuseDTrans :: CharMap Transition
fuseDTrans :: CharMap Transition
fuseDTrans = IntMap Transition -> CharMap Transition
forall a. IntMap a -> CharMap a
CharMap ([(Index, Transition)] -> IntMap Transition
forall a. [(Index, a)] -> IntMap a
IMap.fromDistinctAscList ([(Index, Transition)]
-> [(Index, Transition)] -> [(Index, Transition)]
fuse [(Index, Transition)]
l1 [(Index, Transition)]
l2))
where
l1 :: [(Index, Transition)]
l1 = IntMap Transition -> [(Index, Transition)]
forall a. IntMap a -> [(Index, a)]
IMap.toAscList (CharMap Transition -> IntMap Transition
forall a. CharMap a -> IntMap a
unCharMap CharMap Transition
t1)
l2 :: [(Index, Transition)]
l2 = IntMap Transition -> [(Index, Transition)]
forall a. IntMap a -> [(Index, a)]
IMap.toAscList (CharMap Transition -> IntMap Transition
forall a. CharMap a -> IntMap a
unCharMap CharMap Transition
t2)
fuse :: [(IMap.Key, Transition)]
-> [(IMap.Key, Transition)]
-> [(IMap.Key, Transition)]
fuse :: [(Index, Transition)]
-> [(Index, Transition)] -> [(Index, Transition)]
fuse [] y :: [(Index, Transition)]
y = ((Index, Transition) -> (Index, Transition))
-> [(Index, Transition)] -> [(Index, Transition)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Transition -> Transition)
-> (Index, Transition) -> (Index, Transition)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Transition -> Transition -> Transition
mergeDTrans Transition
o1)) [(Index, Transition)]
y
fuse x :: [(Index, Transition)]
x [] = ((Index, Transition) -> (Index, Transition))
-> [(Index, Transition)] -> [(Index, Transition)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Transition -> Transition)
-> (Index, Transition) -> (Index, Transition)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Transition -> Transition -> Transition
mergeDTrans Transition
o2)) [(Index, Transition)]
x
fuse x :: [(Index, Transition)]
x@((xc :: Index
xc,xa :: Transition
xa):xs :: [(Index, Transition)]
xs) y :: [(Index, Transition)]
y@((yc :: Index
yc,ya :: Transition
ya):ys :: [(Index, Transition)]
ys) =
case Index -> Index -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Index
xc Index
yc of
LT -> (Index
xc,Transition -> Transition -> Transition
mergeDTrans Transition
o2 Transition
xa) (Index, Transition)
-> [(Index, Transition)] -> [(Index, Transition)]
forall a. a -> [a] -> [a]
: [(Index, Transition)]
-> [(Index, Transition)] -> [(Index, Transition)]
fuse [(Index, Transition)]
xs [(Index, Transition)]
y
EQ -> (Index
xc,Transition -> Transition -> Transition
mergeDTrans Transition
xa Transition
ya) (Index, Transition)
-> [(Index, Transition)] -> [(Index, Transition)]
forall a. a -> [a] -> [a]
: [(Index, Transition)]
-> [(Index, Transition)] -> [(Index, Transition)]
fuse [(Index, Transition)]
xs [(Index, Transition)]
ys
GT -> (Index
yc,Transition -> Transition -> Transition
mergeDTrans Transition
o1 Transition
ya) (Index, Transition)
-> [(Index, Transition)] -> [(Index, Transition)]
forall a. a -> [a] -> [a]
: [(Index, Transition)]
-> [(Index, Transition)] -> [(Index, Transition)]
fuse [(Index, Transition)]
x [(Index, Transition)]
ys
mergeDT dt1 :: DT
dt1@(Testing' wt1 :: WhichTest
wt1 dopas1 :: EnumSet DoPa
dopas1 a1 :: DT
a1 b1 :: DT
b1) dt2 :: DT
dt2@(Testing' wt2 :: WhichTest
wt2 dopas2 :: EnumSet DoPa
dopas2 a2 :: DT
a2 b2 :: DT
b2) =
case WhichTest -> WhichTest -> Ordering
forall a. Ord a => a -> a -> Ordering
compare WhichTest
wt1 WhichTest
wt2 of
LT -> DT -> DT -> DT
nestDT DT
dt1 DT
dt2
EQ -> Testing' :: WhichTest -> EnumSet DoPa -> DT -> DT -> DT
Testing' { dt_test :: WhichTest
dt_test = WhichTest
wt1
, dt_dopas :: EnumSet DoPa
dt_dopas = EnumSet DoPa
dopas1 EnumSet DoPa -> EnumSet DoPa -> EnumSet DoPa
forall a. Monoid a => a -> a -> a
`mappend` EnumSet DoPa
dopas2
, dt_a :: DT
dt_a = DT -> DT -> DT
mergeDT DT
a1 DT
a2
, dt_b :: DT
dt_b = DT -> DT -> DT
mergeDT DT
b1 DT
b2 }
GT -> DT -> DT -> DT
nestDT DT
dt2 DT
dt1
mergeDT dt1 :: DT
dt1@(Testing' {}) dt2 :: DT
dt2 = DT -> DT -> DT
nestDT DT
dt1 DT
dt2
mergeDT dt1 :: DT
dt1 dt2 :: DT
dt2@(Testing' {}) = DT -> DT -> DT
nestDT DT
dt2 DT
dt1
nestDT :: DT -> DT -> DT
nestDT dt1 :: DT
dt1@(Testing' {dt_a :: DT -> DT
dt_a=DT
a,dt_b :: DT -> DT
dt_b=DT
b}) dt2 :: DT
dt2 = DT
dt1 { dt_a :: DT
dt_a = DT -> DT -> DT
mergeDT DT
a DT
dt2, dt_b :: DT
dt_b = DT -> DT -> DT
mergeDT DT
b DT
dt2 }
nestDT _ _ = String -> DT
forall a. String -> a
err "nestDT called on Simple -- cannot happen"
patternToRegex :: (Pattern,(GroupIndex, DoPa)) -> CompOption -> ExecOption -> Regex
patternToRegex :: (Pattern, (Index, DoPa)) -> CompOption -> ExecOption -> Regex
patternToRegex pattern :: (Pattern, (Index, DoPa))
pattern compOpt :: CompOption
compOpt execOpt :: ExecOption
execOpt = ((Index, Array Index QNFA), Array Index OP,
Array Index [GroupInfo])
-> CompOption -> ExecOption -> Regex
nfaToDFA (CompOption
-> (Pattern, (Index, DoPa))
-> ((Index, Array Index QNFA), Array Index OP,
Array Index [GroupInfo])
patternToNFA CompOption
compOpt (Pattern, (Index, DoPa))
pattern) CompOption
compOpt ExecOption
execOpt
dfaMap :: DFA -> Data.Map.Map SetIndex DFA
dfaMap :: DFA -> Map SetIndex DFA
dfaMap = Map SetIndex DFA -> DFA -> Map SetIndex DFA
seen (Map SetIndex DFA
forall k a. Map k a
Data.Map.empty) where
seen :: Map SetIndex DFA -> DFA -> Map SetIndex DFA
seen old :: Map SetIndex DFA
old d :: DFA
d@(DFA {d_id :: DFA -> SetIndex
d_id=SetIndex
i,d_dt :: DFA -> DT
d_dt=DT
dt}) =
if SetIndex
i SetIndex -> Map SetIndex DFA -> Bool
forall k a. Ord k => k -> Map k a -> Bool
`Data.Map.member` Map SetIndex DFA
old
then Map SetIndex DFA
old
else let new :: Map SetIndex DFA
new = SetIndex -> DFA -> Map SetIndex DFA -> Map SetIndex DFA
forall k a. Ord k => k -> a -> Map k a -> Map k a
Data.Map.insert SetIndex
i DFA
d Map SetIndex DFA
old
in (Map SetIndex DFA -> DFA -> Map SetIndex DFA)
-> Map SetIndex DFA -> [DFA] -> Map SetIndex DFA
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Map SetIndex DFA -> DFA -> Map SetIndex DFA
seen Map SetIndex DFA
new (DT -> [DFA]
flattenDT DT
dt)
flattenDT :: DT -> [DFA]
flattenDT :: DT -> [DFA]
flattenDT (Simple' {dt_trans :: DT -> CharMap Transition
dt_trans=(CharMap mt :: IntMap Transition
mt),dt_other :: DT -> Transition
dt_other=Transition
o}) = (Transition -> [DFA]) -> [Transition] -> [DFA]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\d :: Transition
d -> [Transition -> DFA
trans_many Transition
d ]) ([Transition] -> [DFA])
-> (IntMap Transition -> [Transition])
-> IntMap Transition
-> [DFA]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:) Transition
o ([Transition] -> [Transition])
-> (IntMap Transition -> [Transition])
-> IntMap Transition
-> [Transition]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IntMap Transition -> [Transition]
forall a. IntMap a -> [a]
IMap.elems (IntMap Transition -> [DFA]) -> IntMap Transition -> [DFA]
forall a b. (a -> b) -> a -> b
$ IntMap Transition
mt
flattenDT (Testing' {dt_a :: DT -> DT
dt_a=DT
a,dt_b :: DT -> DT
dt_b=DT
b}) = DT -> [DFA]
flattenDT DT
a [DFA] -> [DFA] -> [DFA]
forall a. [a] -> [a] -> [a]
++ DT -> [DFA]
flattenDT DT
b
examineDFA :: Regex -> String
examineDFA :: Regex -> String
examineDFA (Regex {regex_dfa :: Regex -> DFA
regex_dfa=DFA
dfa}) = [String] -> String
unlines ([String] -> String) -> ([DFA] -> [String]) -> [DFA] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (:) ("Number of reachable DFA states: "String -> String -> String
forall a. [a] -> [a] -> [a]
++Index -> String
forall a. Show a => a -> String
show ([DFA] -> Index
forall (t :: * -> *) a. Foldable t => t a -> Index
length [DFA]
dfas)) ([String] -> [String]) -> ([DFA] -> [String]) -> [DFA] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DFA -> String) -> [DFA] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map DFA -> String
forall a. Show a => a -> String
show ([DFA] -> String) -> [DFA] -> String
forall a b. (a -> b) -> a -> b
$ [DFA]
dfas
where dfas :: [DFA]
dfas = Map SetIndex DFA -> [DFA]
forall k a. Map k a -> [a]
Data.Map.elems (Map SetIndex DFA -> [DFA]) -> Map SetIndex DFA -> [DFA]
forall a b. (a -> b) -> a -> b
$ DFA -> Map SetIndex DFA
dfaMap DFA
dfa
pickQTrans :: Array Tag OP -> QTrans -> [(Index,(DoPa,Instructions))]
pickQTrans :: Array Index OP -> QTrans -> [(Index, (DoPa, Instructions))]
pickQTrans op :: Array Index OP
op tr :: QTrans
tr = ([TagCommand] -> (DoPa, Instructions))
-> [(Index, [TagCommand])] -> [(Index, (DoPa, Instructions))]
forall (f :: * -> *) t1 t2 t.
Functor f =>
(t1 -> t2) -> f (t, t1) -> f (t, t2)
mapSnd (Array Index OP -> [TagCommand] -> (DoPa, Instructions)
bestTrans Array Index OP
op) ([(Index, [TagCommand])] -> [(Index, (DoPa, Instructions))])
-> (QTrans -> [(Index, [TagCommand])])
-> QTrans
-> [(Index, (DoPa, Instructions))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. QTrans -> [(Index, [TagCommand])]
forall a. IntMap a -> [(Index, a)]
IMap.toList (QTrans -> [(Index, (DoPa, Instructions))])
-> QTrans -> [(Index, (DoPa, Instructions))]
forall a b. (a -> b) -> a -> b
$ QTrans
tr
cleanWin :: WinTags -> Instructions
cleanWin :: WinTags -> Instructions
cleanWin = WinTags -> Instructions
toInstructions
bestTrans :: Array Tag OP -> [TagCommand] -> (DoPa,Instructions)
bestTrans :: Array Index OP -> [TagCommand] -> (DoPa, Instructions)
bestTrans _ [] = String -> (DoPa, Instructions)
forall a. String -> a
err "bestTrans : There were no transition choose from!"
bestTrans aTagOP :: Array Index OP
aTagOP (f :: TagCommand
f:fs :: [TagCommand]
fs) | [TagCommand] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [TagCommand]
fs = TagCommand -> (DoPa, Instructions)
canonical TagCommand
f
| Bool
otherwise = (DoPa, Instructions)
answer
where
answer :: (DoPa, Instructions)
answer = ((DoPa, Instructions) -> TagCommand -> (DoPa, Instructions))
-> (DoPa, Instructions) -> [TagCommand] -> (DoPa, Instructions)
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (DoPa, Instructions) -> TagCommand -> (DoPa, Instructions)
pick (TagCommand -> (DoPa, Instructions)
canonical TagCommand
f) [TagCommand]
fs
canonical :: TagCommand -> (DoPa,Instructions)
canonical :: TagCommand -> (DoPa, Instructions)
canonical (dopa :: DoPa
dopa,spec :: WinTags
spec) = (DoPa
dopa, WinTags -> Instructions
toInstructions WinTags
spec)
pick :: (DoPa,Instructions) -> TagCommand -> (DoPa,Instructions)
pick :: (DoPa, Instructions) -> TagCommand -> (DoPa, Instructions)
pick win :: (DoPa, Instructions)
win@(dopa1 :: DoPa
dopa1,winI :: Instructions
winI) (dopa2 :: DoPa
dopa2,spec :: WinTags
spec) =
let nextI :: Instructions
nextI = WinTags -> Instructions
toInstructions WinTags
spec
in case (Maybe (Index, Action) -> Maybe (Index, Action) -> Ordering)
-> [(Index, Action)] -> [(Index, Action)] -> Ordering
forall x a b c.
(Ord x, Monoid a) =>
(Maybe (x, b) -> Maybe (x, c) -> a) -> [(x, b)] -> [(x, c)] -> a
compareWith Maybe (Index, Action) -> Maybe (Index, Action) -> Ordering
choose (Instructions -> [(Index, Action)]
toListing Instructions
winI) (Instructions -> [(Index, Action)]
toListing Instructions
nextI) of
GT -> (DoPa, Instructions)
win
LT -> (DoPa
dopa2,Instructions
nextI)
EQ -> if DoPa
dopa1 DoPa -> DoPa -> Bool
forall a. Ord a => a -> a -> Bool
>= DoPa
dopa2 then (DoPa, Instructions)
win else (DoPa
dopa2,Instructions
nextI)
toListing :: Instructions -> [(Tag,Action)]
toListing :: Instructions -> [(Index, Action)]
toListing (Instructions {newPos :: Instructions -> [(Index, Action)]
newPos = [(Index, Action)]
nextPos}) = ((Index, Action) -> Bool) -> [(Index, Action)] -> [(Index, Action)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Index, Action) -> Bool
forall a. (a, Action) -> Bool
notReset [(Index, Action)]
nextPos
where notReset :: (a, Action) -> Bool
notReset (_,SetVal (-1)) = Bool
False
notReset _ = Bool
True
{-# INLINE choose #-}
choose :: Maybe (Tag,Action) -> Maybe (Tag,Action) -> Ordering
choose :: Maybe (Index, Action) -> Maybe (Index, Action) -> Ordering
choose Nothing Nothing = Ordering
EQ
choose Nothing x :: Maybe (Index, Action)
x = Ordering -> Ordering
flipOrder (Maybe (Index, Action) -> Maybe (Index, Action) -> Ordering
choose Maybe (Index, Action)
x Maybe (Index, Action)
forall a. Maybe a
Nothing)
choose (Just (tag :: Index
tag,_post :: Action
_post)) Nothing =
case Array Index OP
aTagOPArray Index OP -> Index -> OP
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Index
tag of
Maximize -> Ordering
GT
Minimize -> Ordering
LT
Ignore -> Ordering
GT
Orbit -> Ordering
LT
choose (Just (tag :: Index
tag,post1 :: Action
post1)) (Just (_,post2 :: Action
post2)) =
case Array Index OP
aTagOPArray Index OP -> Index -> OP
forall (a :: * -> * -> *) e i.
(IArray a e, Ix i) =>
a i e -> i -> e
!Index
tag of
Maximize -> Ordering
order
Minimize -> Ordering -> Ordering
flipOrder Ordering
order
Ignore -> Ordering
EQ
Orbit -> Ordering
EQ
where order :: Ordering
order = case (Action
post1,Action
post2) of
(SetPre,SetPre) -> Ordering
EQ
(SetPost,SetPost) -> Ordering
EQ
(SetPre,SetPost) -> Ordering
LT
(SetPost,SetPre) -> Ordering
GT
(SetVal v1 :: Index
v1,SetVal v2 :: Index
v2) -> Index -> Index -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Index
v1 Index
v2
_ -> String -> Ordering
forall a. String -> a
err (String -> Ordering) -> String -> Ordering
forall a b. (a -> b) -> a -> b
$ "bestTrans.compareWith.choose sees incomparable "String -> String -> String
forall a. [a] -> [a] -> [a]
++(Index, Action, Action) -> String
forall a. Show a => a -> String
show (Index
tag,Action
post1,Action
post2)
{-# INLINE compareWith #-}
compareWith :: (Ord x,Monoid a) => (Maybe (x,b) -> Maybe (x,c) -> a) -> [(x,b)] -> [(x,c)] -> a
compareWith :: (Maybe (x, b) -> Maybe (x, c) -> a) -> [(x, b)] -> [(x, c)] -> a
compareWith comp :: Maybe (x, b) -> Maybe (x, c) -> a
comp = [(x, b)] -> [(x, c)] -> a
cw where
cw :: [(x, b)] -> [(x, c)] -> a
cw [] [] = Maybe (x, b) -> Maybe (x, c) -> a
comp Maybe (x, b)
forall a. Maybe a
Nothing Maybe (x, c)
forall a. Maybe a
Nothing
cw xx :: [(x, b)]
xx@(x :: (x, b)
x:xs :: [(x, b)]
xs) yy :: [(x, c)]
yy@(y :: (x, c)
y:ys :: [(x, c)]
ys) =
case x -> x -> Ordering
forall a. Ord a => a -> a -> Ordering
compare ((x, b) -> x
forall a b. (a, b) -> a
fst (x, b)
x) ((x, c) -> x
forall a b. (a, b) -> a
fst (x, c)
y) of
GT -> Maybe (x, b) -> Maybe (x, c) -> a
comp Maybe (x, b)
forall a. Maybe a
Nothing ((x, c) -> Maybe (x, c)
forall a. a -> Maybe a
Just (x, c)
y) a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` [(x, b)] -> [(x, c)] -> a
cw [(x, b)]
xx [(x, c)]
ys
EQ -> Maybe (x, b) -> Maybe (x, c) -> a
comp ((x, b) -> Maybe (x, b)
forall a. a -> Maybe a
Just (x, b)
x) ((x, c) -> Maybe (x, c)
forall a. a -> Maybe a
Just (x, c)
y) a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` [(x, b)] -> [(x, c)] -> a
cw [(x, b)]
xs [(x, c)]
ys
LT -> Maybe (x, b) -> Maybe (x, c) -> a
comp ((x, b) -> Maybe (x, b)
forall a. a -> Maybe a
Just (x, b)
x) Maybe (x, c)
forall a. Maybe a
Nothing a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` [(x, b)] -> [(x, c)] -> a
cw [(x, b)]
xs [(x, c)]
yy
cw xx :: [(x, b)]
xx [] = ((x, b) -> a -> a) -> a -> [(x, b)] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\x :: (x, b)
x rest :: a
rest -> Maybe (x, b) -> Maybe (x, c) -> a
comp ((x, b) -> Maybe (x, b)
forall a. a -> Maybe a
Just (x, b)
x) Maybe (x, c)
forall a. Maybe a
Nothing a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
rest) a
forall a. Monoid a => a
mempty [(x, b)]
xx
cw [] yy :: [(x, c)]
yy = ((x, c) -> a -> a) -> a -> [(x, c)] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\y :: (x, c)
y rest :: a
rest -> Maybe (x, b) -> Maybe (x, c) -> a
comp Maybe (x, b)
forall a. Maybe a
Nothing ((x, c) -> Maybe (x, c)
forall a. a -> Maybe a
Just (x, c)
y) a -> a -> a
forall a. Monoid a => a -> a -> a
`mappend` a
rest) a
forall a. Monoid a => a
mempty [(x, c)]
yy
isDFAFrontAnchored :: DFA -> Bool
isDFAFrontAnchored :: DFA -> Bool
isDFAFrontAnchored = DT -> Bool
isDTFrontAnchored (DT -> Bool) -> (DFA -> DT) -> DFA -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DFA -> DT
d_dt
where
isDTFrontAnchored :: DT -> Bool
isDTFrontAnchored :: DT -> Bool
isDTFrontAnchored (Simple' {}) = Bool
False
isDTFrontAnchored (Testing' {dt_test :: DT -> WhichTest
dt_test=WhichTest
wt,dt_a :: DT -> DT
dt_a=DT
a,dt_b :: DT -> DT
dt_b=DT
b}) | WhichTest
wt WhichTest -> WhichTest -> Bool
forall a. Eq a => a -> a -> Bool
== WhichTest
Test_BOL = DT -> Bool
isDTLosing DT
b
| Bool
otherwise = DT -> Bool
isDTFrontAnchored DT
a Bool -> Bool -> Bool
&& DT -> Bool
isDTFrontAnchored DT
b
where
isDTLosing :: DT -> Bool
isDTLosing :: DT -> Bool
isDTLosing (Testing' {dt_a :: DT -> DT
dt_a=DT
a',dt_b :: DT -> DT
dt_b=DT
b'}) = DT -> Bool
isDTLosing DT
a' Bool -> Bool -> Bool
&& DT -> Bool
isDTLosing DT
b'
isDTLosing (Simple' {dt_win :: DT -> IntMap Instructions
dt_win=IntMap Instructions
w}) | Bool -> Bool
not (IntMap Instructions -> Bool
forall a. IntMap a -> Bool
IMap.null IntMap Instructions
w) = Bool
False
isDTLosing (Simple' {dt_trans :: DT -> CharMap Transition
dt_trans=CharMap mt :: IntMap Transition
mt,dt_other :: DT -> Transition
dt_other=Transition
o}) =
let ts :: [Transition]
ts = Transition
o Transition -> [Transition] -> [Transition]
forall a. a -> [a] -> [a]
: IntMap Transition -> [Transition]
forall a. IntMap a -> [a]
IMap.elems IntMap Transition
mt
in (Transition -> Bool) -> [Transition] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Transition -> Bool
transLoses [Transition]
ts
where
transLoses :: Transition -> Bool
transLoses :: Transition -> Bool
transLoses (Transition {trans_single :: Transition -> DFA
trans_single=DFA
dfa,trans_how :: Transition -> DTrans
trans_how=DTrans
dtrans}) = DFA -> Bool
isDTLose DFA
dfa Bool -> Bool -> Bool
|| DTrans -> Bool
onlySpawns DTrans
dtrans
where
isDTLose :: DFA -> Bool
isDTLose :: DFA -> Bool
isDTLose dfa' :: DFA
dfa' = SetIndex -> Bool
ISet.null (DFA -> SetIndex
d_id DFA
dfa')
onlySpawns :: DTrans -> Bool
onlySpawns :: DTrans -> Bool
onlySpawns t :: DTrans
t = case DTrans -> [IntMap (DoPa, Instructions)]
forall a. IntMap a -> [a]
IMap.elems DTrans
t of
[m :: IntMap (DoPa, Instructions)
m] -> IntMap (DoPa, Instructions) -> Bool
forall a. IntMap a -> Bool
IMap.null IntMap (DoPa, Instructions)
m
_ -> Bool
False
toInstructions :: TagList -> Instructions
toInstructions :: WinTags -> Instructions
toInstructions spec :: WinTags
spec =
let (p :: IntMap Action
p,o :: IntMap AlterOrbit
o) = State (IntMap Action, IntMap AlterOrbit) ()
-> (IntMap Action, IntMap AlterOrbit)
-> (IntMap Action, IntMap AlterOrbit)
forall s a. State s a -> s -> s
execState (WinTags -> State (IntMap Action, IntMap AlterOrbit) ()
assemble WinTags
spec) (IntMap Action
forall a. Monoid a => a
mempty,IntMap AlterOrbit
forall a. Monoid a => a
mempty)
in $WInstructions :: [(Index, Action)]
-> Maybe (Index -> OrbitTransformer) -> Instructions
Instructions { newPos :: [(Index, Action)]
newPos = IntMap Action -> [(Index, Action)]
forall a. IntMap a -> [(Index, a)]
IMap.toList IntMap Action
p
, newOrbits :: Maybe (Index -> OrbitTransformer)
newOrbits = if IntMap AlterOrbit -> Bool
forall a. IntMap a -> Bool
IMap.null IntMap AlterOrbit
o then Maybe (Index -> OrbitTransformer)
forall a. Maybe a
Nothing
else (Index -> OrbitTransformer) -> Maybe (Index -> OrbitTransformer)
forall a. a -> Maybe a
Just ((Index -> OrbitTransformer) -> Maybe (Index -> OrbitTransformer))
-> (Index -> OrbitTransformer) -> Maybe (Index -> OrbitTransformer)
forall a b. (a -> b) -> a -> b
$ [(Index, AlterOrbit)] -> Index -> OrbitTransformer
alterOrbits (IntMap AlterOrbit -> [(Index, AlterOrbit)]
forall a. IntMap a -> [(Index, a)]
IMap.toList IntMap AlterOrbit
o)
}
type CompileInstructions a = State
( IntMap Action
, IntMap AlterOrbit
) a
data AlterOrbit = AlterReset
| AlterLeave
| AlterModify { AlterOrbit -> Bool
newInOrbit :: Bool
, AlterOrbit -> Bool
freshOrbit :: Bool}
deriving (Index -> AlterOrbit -> String -> String
[AlterOrbit] -> String -> String
AlterOrbit -> String
(Index -> AlterOrbit -> String -> String)
-> (AlterOrbit -> String)
-> ([AlterOrbit] -> String -> String)
-> Show AlterOrbit
forall a.
(Index -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [AlterOrbit] -> String -> String
$cshowList :: [AlterOrbit] -> String -> String
show :: AlterOrbit -> String
$cshow :: AlterOrbit -> String
showsPrec :: Index -> AlterOrbit -> String -> String
$cshowsPrec :: Index -> AlterOrbit -> String -> String
Show)
assemble :: TagList -> CompileInstructions ()
assemble :: WinTags -> State (IntMap Action, IntMap AlterOrbit) ()
assemble = ((Index, TagUpdate) -> State (IntMap Action, IntMap AlterOrbit) ())
-> WinTags -> State (IntMap Action, IntMap AlterOrbit) ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (Index, TagUpdate) -> State (IntMap Action, IntMap AlterOrbit) ()
oneInstruction where
oneInstruction :: (Index, TagUpdate) -> State (IntMap Action, IntMap AlterOrbit) ()
oneInstruction (tag :: Index
tag,command :: TagUpdate
command) =
case TagUpdate
command of
PreUpdate TagTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
setPreTag Index
tag
PreUpdate ResetGroupStopTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
resetGroupTag Index
tag
PreUpdate SetGroupStopTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
setGroupTag Index
tag
PreUpdate ResetOrbitTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
resetOrbit Index
tag
PreUpdate EnterOrbitTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
enterOrbit Index
tag
PreUpdate LeaveOrbitTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
leaveOrbit Index
tag
PostUpdate TagTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
setPostTag Index
tag
PostUpdate ResetGroupStopTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
resetGroupTag Index
tag
PostUpdate SetGroupStopTask -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
setGroupTag Index
tag
_ -> String -> State (IntMap Action, IntMap AlterOrbit) ()
forall a. String -> a
err ("assemble : Weird orbit command: "String -> String -> String
forall a. [a] -> [a] -> [a]
++(Index, TagUpdate) -> String
forall a. Show a => a -> String
show (Index
tag,TagUpdate
command))
setPreTag :: Tag -> CompileInstructions ()
setPreTag :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
setPreTag = Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos Action
SetPre
setPostTag :: Tag -> CompileInstructions ()
setPostTag :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
setPostTag = Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos Action
SetPost
resetGroupTag :: Tag -> CompileInstructions ()
resetGroupTag :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
resetGroupTag = Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos (Index -> Action
SetVal (-1))
setGroupTag :: Tag -> CompileInstructions ()
setGroupTag :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
setGroupTag = Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos (Index -> Action
SetVal 0)
resetOrbit :: Tag -> CompileInstructions ()
resetOrbit :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
resetOrbit tag :: Index
tag = Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos (Index -> Action
SetVal (-1)) Index
tag State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (IntMap AlterOrbit -> IntMap AlterOrbit)
-> State (IntMap Action, IntMap AlterOrbit) ()
modifyOrbit (Index -> AlterOrbit -> IntMap AlterOrbit -> IntMap AlterOrbit
forall a. Index -> a -> IntMap a -> IntMap a
IMap.insert Index
tag AlterOrbit
AlterReset)
enterOrbit :: Tag -> CompileInstructions ()
enterOrbit :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
enterOrbit tag :: Index
tag = Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos (Index -> Action
SetVal 0) Index
tag State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (IntMap AlterOrbit -> IntMap AlterOrbit)
-> State (IntMap Action, IntMap AlterOrbit) ()
modifyOrbit IntMap AlterOrbit -> IntMap AlterOrbit
changeOrbit where
changeOrbit :: IntMap AlterOrbit -> IntMap AlterOrbit
changeOrbit = (AlterOrbit -> AlterOrbit -> AlterOrbit)
-> Index -> AlterOrbit -> IntMap AlterOrbit -> IntMap AlterOrbit
forall a. (a -> a -> a) -> Index -> a -> IntMap a -> IntMap a
IMap.insertWith AlterOrbit -> AlterOrbit -> AlterOrbit
forall p. p -> AlterOrbit -> AlterOrbit
overwriteOrbit Index
tag AlterOrbit
appendNewOrbit
appendNewOrbit :: AlterOrbit
appendNewOrbit = AlterModify :: Bool -> Bool -> AlterOrbit
AlterModify {newInOrbit :: Bool
newInOrbit = Bool
True, freshOrbit :: Bool
freshOrbit = Bool
False}
startNewOrbit :: AlterOrbit
startNewOrbit = AlterModify :: Bool -> Bool -> AlterOrbit
AlterModify {newInOrbit :: Bool
newInOrbit = Bool
True, freshOrbit :: Bool
freshOrbit = Bool
True}
overwriteOrbit :: p -> AlterOrbit -> AlterOrbit
overwriteOrbit _ AlterReset = AlterOrbit
startNewOrbit
overwriteOrbit _ AlterLeave = AlterOrbit
startNewOrbit
overwriteOrbit _ (AlterModify {newInOrbit :: AlterOrbit -> Bool
newInOrbit = Bool
False}) = AlterOrbit
startNewOrbit
overwriteOrbit _ (AlterModify {newInOrbit :: AlterOrbit -> Bool
newInOrbit = Bool
True}) =
String -> AlterOrbit
forall a. String -> a
err (String -> AlterOrbit) -> String -> AlterOrbit
forall a b. (a -> b) -> a -> b
$ "enterOrbit: Cannot enterOrbit twice in a row: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Index -> String
forall a. Show a => a -> String
show Index
tag
leaveOrbit :: Tag -> CompileInstructions ()
leaveOrbit :: Index -> State (IntMap Action, IntMap AlterOrbit) ()
leaveOrbit tag :: Index
tag = (IntMap AlterOrbit -> IntMap AlterOrbit)
-> State (IntMap Action, IntMap AlterOrbit) ()
modifyOrbit IntMap AlterOrbit -> IntMap AlterOrbit
escapeOrbit where
escapeOrbit :: IntMap AlterOrbit -> IntMap AlterOrbit
escapeOrbit = (AlterOrbit -> AlterOrbit -> AlterOrbit)
-> Index -> AlterOrbit -> IntMap AlterOrbit -> IntMap AlterOrbit
forall a. (a -> a -> a) -> Index -> a -> IntMap a -> IntMap a
IMap.insertWith AlterOrbit -> AlterOrbit -> AlterOrbit
forall p. p -> AlterOrbit -> AlterOrbit
setInOrbitFalse Index
tag AlterOrbit
AlterLeave where
setInOrbitFalse :: p -> AlterOrbit -> AlterOrbit
setInOrbitFalse _ x :: AlterOrbit
x@(AlterModify {}) = AlterOrbit
x {newInOrbit :: Bool
newInOrbit = Bool
False}
setInOrbitFalse _ x :: AlterOrbit
x = AlterOrbit
x
modifyPos :: Action -> Tag -> CompileInstructions ()
modifyPos :: Action -> Index -> State (IntMap Action, IntMap AlterOrbit) ()
modifyPos todo :: Action
todo tag :: Index
tag = do
(a :: IntMap Action
a,c :: IntMap AlterOrbit
c) <- StateT
(IntMap Action, IntMap AlterOrbit)
Identity
(IntMap Action, IntMap AlterOrbit)
forall s (m :: * -> *). MonadState s m => m s
get
let a' :: IntMap Action
a' = Index -> Action -> IntMap Action -> IntMap Action
forall a. Index -> a -> IntMap a -> IntMap a
IMap.insert Index
tag Action
todo IntMap Action
a
IntMap Action
-> State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
forall a b. a -> b -> b
seq IntMap Action
a' (State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ())
-> State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
forall a b. (a -> b) -> a -> b
$ (IntMap Action, IntMap AlterOrbit)
-> State (IntMap Action, IntMap AlterOrbit) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (IntMap Action
a',IntMap AlterOrbit
c)
modifyOrbit :: (IntMap AlterOrbit -> IntMap AlterOrbit) -> CompileInstructions ()
modifyOrbit :: (IntMap AlterOrbit -> IntMap AlterOrbit)
-> State (IntMap Action, IntMap AlterOrbit) ()
modifyOrbit f :: IntMap AlterOrbit -> IntMap AlterOrbit
f = do
(a :: IntMap Action
a,c :: IntMap AlterOrbit
c) <- StateT
(IntMap Action, IntMap AlterOrbit)
Identity
(IntMap Action, IntMap AlterOrbit)
forall s (m :: * -> *). MonadState s m => m s
get
let c' :: IntMap AlterOrbit
c' = IntMap AlterOrbit -> IntMap AlterOrbit
f IntMap AlterOrbit
c
IntMap AlterOrbit
-> State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
forall a b. a -> b -> b
seq IntMap AlterOrbit
c' (State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ())
-> State (IntMap Action, IntMap AlterOrbit) ()
-> State (IntMap Action, IntMap AlterOrbit) ()
forall a b. (a -> b) -> a -> b
$ (IntMap Action, IntMap AlterOrbit)
-> State (IntMap Action, IntMap AlterOrbit) ()
forall s (m :: * -> *). MonadState s m => s -> m ()
put (IntMap Action
a,IntMap AlterOrbit
c')
alterOrbits :: [(Tag,AlterOrbit)] -> (Position -> OrbitTransformer)
alterOrbits :: [(Index, AlterOrbit)] -> Index -> OrbitTransformer
alterOrbits x :: [(Index, AlterOrbit)]
x = let items :: [Index -> OrbitTransformer]
items = ((Index, AlterOrbit) -> Index -> OrbitTransformer)
-> [(Index, AlterOrbit)] -> [Index -> OrbitTransformer]
forall a b. (a -> b) -> [a] -> [b]
map (Index, AlterOrbit) -> Index -> OrbitTransformer
alterOrbit [(Index, AlterOrbit)]
x
in (\ pos :: Index
pos m :: OrbitLog
m -> (OrbitLog -> OrbitTransformer -> OrbitLog)
-> OrbitLog -> [OrbitTransformer] -> OrbitLog
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl ((OrbitTransformer -> OrbitTransformer)
-> OrbitLog -> OrbitTransformer -> OrbitLog
forall a b c. (a -> b -> c) -> b -> a -> c
flip OrbitTransformer -> OrbitTransformer
forall a b. (a -> b) -> a -> b
($)) OrbitLog
m (((Index -> OrbitTransformer) -> OrbitTransformer)
-> [Index -> OrbitTransformer] -> [OrbitTransformer]
forall a b. (a -> b) -> [a] -> [b]
map ((Index -> OrbitTransformer) -> Index -> OrbitTransformer
forall a b. (a -> b) -> a -> b
$ Index
pos) [Index -> OrbitTransformer]
items))
alterOrbit :: (Tag,AlterOrbit) -> (Position -> OrbitTransformer)
alterOrbit :: (Index, AlterOrbit) -> Index -> OrbitTransformer
alterOrbit (tag :: Index
tag,AlterModify {newInOrbit :: AlterOrbit -> Bool
newInOrbit = Bool
inOrbit',freshOrbit :: AlterOrbit -> Bool
freshOrbit = Bool
True}) =
(\ pos :: Index
pos m :: OrbitLog
m -> Index -> Orbits -> OrbitTransformer
forall a. Index -> a -> IntMap a -> IntMap a
IMap.insert Index
tag ($WOrbits :: Bool -> Index -> Maybe Index -> Seq Index -> Orbits
Orbits { inOrbit :: Bool
inOrbit = Bool
inOrbit'
, basePos :: Index
basePos = Index
pos
, ordinal :: Maybe Index
ordinal = Maybe Index
forall a. Maybe a
Nothing
, getOrbits :: Seq Index
getOrbits = Seq Index
forall a. Monoid a => a
mempty}) OrbitLog
m)
alterOrbit (tag :: Index
tag,AlterModify {newInOrbit :: AlterOrbit -> Bool
newInOrbit = Bool
inOrbit',freshOrbit :: AlterOrbit -> Bool
freshOrbit = Bool
False}) =
(\ pos :: Index
pos m :: OrbitLog
m -> (Index -> Orbits -> Orbits -> Orbits)
-> Index -> Orbits -> OrbitTransformer
forall a.
(Index -> a -> a -> a) -> Index -> a -> IntMap a -> IntMap a
IMap.insertWithKey (Index -> Index -> Orbits -> Orbits -> Orbits
forall p. Index -> p -> Orbits -> Orbits -> Orbits
updateOrbit Index
pos) Index
tag (Index -> Orbits
newOrbit Index
pos) OrbitLog
m) where
newOrbit :: Index -> Orbits
newOrbit pos :: Index
pos = $WOrbits :: Bool -> Index -> Maybe Index -> Seq Index -> Orbits
Orbits { inOrbit :: Bool
inOrbit = Bool
inOrbit'
, basePos :: Index
basePos = Index
pos
, ordinal :: Maybe Index
ordinal = Maybe Index
forall a. Maybe a
Nothing
, getOrbits :: Seq Index
getOrbits = Seq Index
forall a. Monoid a => a
Mon.mempty}
updateOrbit :: Index -> p -> Orbits -> Orbits -> Orbits
updateOrbit pos :: Index
pos _tag :: p
_tag new :: Orbits
new old :: Orbits
old | Orbits -> Bool
inOrbit Orbits
old = Orbits
old { inOrbit :: Bool
inOrbit = Bool
inOrbit'
, getOrbits :: Seq Index
getOrbits = Orbits -> Seq Index
getOrbits Orbits
old Seq Index -> Index -> Seq Index
forall a. Seq a -> a -> Seq a
|> Index
pos }
| Bool
otherwise = Orbits
new
alterOrbit (tag :: Index
tag,AlterReset) = (\ _ m :: OrbitLog
m -> Index -> OrbitTransformer
forall a. Index -> IntMap a -> IntMap a
IMap.delete Index
tag OrbitLog
m)
alterOrbit (tag :: Index
tag,AlterLeave) = (\ _ m :: OrbitLog
m -> case Index -> OrbitLog -> Maybe Orbits
forall a. Index -> IntMap a -> Maybe a
IMap.lookup Index
tag OrbitLog
m of
Nothing -> OrbitLog
m
Just x :: Orbits
x -> Index -> Orbits -> OrbitTransformer
forall a. Index -> a -> IntMap a -> IntMap a
IMap.insert Index
tag (Orbits
x {inOrbit :: Bool
inOrbit=Bool
False}) OrbitLog
m)