module ADP.Fusion.Term.Edge.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 ADP.Fusion.Core
import Data.Bits.Ordered
import Data.PrimitiveArray hiding (map)
import ADP.Fusion.Core.Set1
import ADP.Fusion.Term.Edge.Type
instance
( TmkCtx1 m ls Edge (BS1 k t)
) => MkStream m (ls :!: Edge) (BS1 k t) where
mkStream (ls :!: Edge) sv us is
= map (\(ss,ee,ii) -> ElmEdge ee ii ss)
. addTermStream1 Edge sv us is
$ mkStream ls (termStaticVar Edge sv is) us (termStreamIndex Edge sv is)
instance
( TstCtx m ts s x0 i0 is (BS1 k I)
, EdgeFromTo k
) => TermStream m (TermSymbol ts Edge) s (is:.BS1 k I) where
termStream (ts:|Edge) (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))
in TState s (ii:.:RiBs1I (BS1 i (Boundary newNode)))
(ee:.edgeFromTo (Proxy :: Proxy k) (SetNode setNode) (NewNode newNode)) )
. 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:|Edge) (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)
in return $ Yield (TState s (ii:.:ix) (ee:.edgeFromTo (Proxy :: Proxy k) (SetNode setNode) (NewNode newNode)))
(TState s ii ee,cset,setNode,xs)
class EdgeFromTo k where
edgeFromTo :: Proxy k -> SetNode -> NewNode -> (From:.To)
newtype SetNode = SetNode Int
newtype NewNode = NewNode Int
instance EdgeFromTo First where
edgeFromTo Proxy (SetNode to) (NewNode from) = From from :. To to
instance EdgeFromTo Last where
edgeFromTo Proxy (SetNode from) (NewNode to) = From from :. To to
instance TermStaticVar Edge (BS1 k I) where
termStaticVar _ (IStatic d) _ = IVariable $ d+1
termStaticVar _ (IVariable d) _ = IVariable $ d+1
termStreamIndex _ _ ix = ix