module ADP.Fusion.Term.EdgeWithSet.Set1 where
import Data.Bits
import Data.Strict.Tuple
import Data.Vector.Fusion.Stream.Monadic hiding (flatten)
import Debug.Trace
import Prelude hiding (map,filter)
import Control.Exception (assert)
import ADP.Fusion.Core
import Data.Bits.Ordered
import Data.PrimitiveArray hiding (map)
import ADP.Fusion.Core.Set1
import ADP.Fusion.Term.EdgeWithSet.Type
import ADP.Fusion.Term.Edge.Set1 (EdgeFromTo(..), SetNode(..), NewNode(..))
instance
( TmkCtx1 m ls EdgeWithSet (BS1 k t)
) => MkStream m (ls :!: EdgeWithSet) (BS1 k t) where
mkStream (ls :!: EdgeWithSet) sv us is
= map (\(ss,ee,ii) -> ElmEdgeWithSet ee ii ss)
. addTermStream1 EdgeWithSet sv us is
$ mkStream ls (termStaticVar EdgeWithSet sv is) us (termStreamIndex EdgeWithSet sv is)
instance
( TstCtx m ts s x0 i0 is (BS1 k I)
, EdgeFromTo k
) => TermStream m (TermSymbol ts EdgeWithSet) s (is:.BS1 k I) where
termStream (ts:|EdgeWithSet) (cs:.IStatic r) (us:.u) (is:.BS1 i (Boundary newNode))
= map (\(TState s ii ee) ->
let RiBs1I (BS1 cset (Boundary setNode)) = getIndex (getIdx s) (Proxy :: PRI is (BS1 k I))
(ef:.et) = edgeFromTo (Proxy :: Proxy k) (SetNode setNode) (NewNode newNode)
in
#if ADPFUSION_DEBUGOUTPUT
traceShow ("EWSI",i,newNode,'>',cset,setNode,ef,et) $
#endif
TState s (ii:.:RiBs1I (BS1 i (Boundary newNode)))
(ee:.(getBitSet cset:.ef:.et) ) )
. filter (\(TState s ii ee) ->
let RiBs1I (BS1 cset (Boundary setNode)) = getIndex (getIdx s) (Proxy :: PRI is (BS1 k I))
in popCount cset >= 1)
. termStream ts cs us is
. staticCheck (popCount i >= 2)
termStream (ts:|EdgeWithSet) (cs:.IVariable r) (us:.u) (is:.BS1 i b)
= flatten mk step . termStream ts cs us is
where mk tstate@(TState s ii ee) =
let RiBs1I (BS1 cset (Boundary setNode)) = getIndex (getIdx s) (Proxy :: PRI is (BS1 k I))
avail = activeBitsL $ (i .&. complement cset) `clearBit` getBoundary b
in return $ (tstate,cset,setNode,avail)
step (_,_,_,[]) = return $ Done
step (TState s ii ee,cset,setNode,(newNode:xs))
| setNode < 0 = error "Edge/Set1: source boundary is '-1'. Move all terminals to the right of syntactic variables!"
| otherwise =
let ix = RiBs1I $ BS1 (cset `setBit` newNode) (Boundary newNode)
(ef:.et) = edgeFromTo (Proxy :: Proxy k) (SetNode setNode) (NewNode newNode)
in return $ Yield (TState s (ii:.:ix) (ee:.(getBitSet cset:.ef:.et)))
(TState s ii ee,cset,setNode,xs)
instance
( TstCtx m ts s x0 i0 is (BS1 k O)
, EdgeFromTo k
) => TermStream m (TermSymbol ts EdgeWithSet) s (is:.BS1 k O) where
termStream (ts:|EdgeWithSet) (cs:.OStatic r) (us:.u) (is:.BS1 gset (Boundary gbnd))
= map (\(TState s ii ee) ->
let RiBs1O (BS1 cset (Boundary cbnd)) = getIndex (getIdx s) (Proxy :: PRI is (BS1 k O))
(ef:.et) = edgeFromTo (Proxy :: Proxy k) (SetNode gbnd) (NewNode cbnd)
in
#if ADPFUSION_DEBUGOUTPUT
traceShow ("EWSO",gset,gbnd,' ',cset,cbnd,ef,et) $
#endif
TState s (ii:.:RiBs1O (BS1 gset (Boundary gbnd)))
(ee:.(getBitSet gset:.ef:.et) ) )
. termStream ts cs us is
. assert (r==0)
. staticCheck (popCount gset >= 1)
instance
( TstCtx m ts s x0 i0 is (BS1 k C)
, EdgeFromTo k
) => TermStream m (TermSymbol ts EdgeWithSet) s (is:.BS1 k C) where
instance TermStaticVar EdgeWithSet (BS1 k I) where
termStaticVar _ (IStatic d) _ = IVariable $ d+1
termStaticVar _ (IVariable d) _ = IVariable $ d+1
termStreamIndex _ _ ix = ix
instance TermStaticVar EdgeWithSet (BS1 k O) where
termStaticVar _ (OStatic d) _ = ORightOf $ d+1
termStaticVar _ (ORightOf d) _ = OFirstLeft $ d+1
termStreamIndex _ _ ix = ix