module ADP.Fusion.Term.Edge.Set where
import Data.Bits
import Data.Strict.Tuple
import Data.Vector.Fusion.Stream.Monadic
import Data.Vector.Fusion.Stream.Size
import Debug.Trace
import Prelude hiding (map)
import Data.PrimitiveArray hiding (map)
import Data.Bits.Ordered
import ADP.Fusion.Base
import ADP.Fusion.Term.Edge.Type
instance
( Monad m
, Element ls (BS2I First Last)
, MkStream m ls (BS2I First Last)
) => MkStream m (ls :!: Edge e) (BS2I First Last) where
mkStream (ls :!: Edge f) (IStatic rp) u sij@(s:>i:>j)
= flatten mk step Unknown $ mkStream ls (IStatic rpn) u tik
where rpn | j >= 0 = rp
| otherwise = rp+1
tik | j >= 0 = s `clearBit` (getIter j) :> i :> undefi
| otherwise = sij
mk z
| j >= 0 && popCount s >= 2 = return $ This z
| j < 0 && popCount s >= 2 = return $ That (z,bits,maybeLsb bits)
| popCount s <= max 1 rp = return $ Naught
| otherwise = error $ show ("Edge",s,i,j)
where (zs:>_:>zk) = getIdx z
bits = s `xor` zs
step Naught = return Done
step (This z)
| popCount zs == 0 = return $ Done
| otherwise = return $ Yield (ElmEdge (f (getIter zk) (getIter j)) sij undefbs2i z) Naught
where (zs:>_:>zk) = getIdx z
step (That (z,bits,Nothing)) = return $ Done
step (That (z,bits,Just j')) = let (zs:>_:>Iter zk) = getIdx z
tij' = (zs .|. bit j') :> Iter zk :> Iter j'
in return $ Yield (ElmEdge (f zk j') tij' undefbs2i z) (That (z,bits,maybeNextActive j' bits))
instance
( Monad m
, Element ls (Outside (BS2I First Last))
, MkStream m ls (Outside (BS2I First Last))
) => MkStream m (ls :!: Edge f) (Outside (BS2I First Last)) where
mkStream (ls :!: Edge f) (OStatic ()) u sij
= map undefined
$ mkStream ls (undefined) u sij
instance
( Monad m
, Element ls (Complement (BS2I First Last))
, MkStream m ls (Complement (BS2I First Last))
) => MkStream m (ls :!: Edge f) (Complement (BS2I First Last)) where
mkStream (ls :!: Edge f) Complemented u sij
= map undefined
$ mkStream ls Complemented u sij