module ADP.Fusion.SynVar.Indices.Set1 where
import Control.Exception (assert)
import Data.Proxy
import Data.Vector.Fusion.Stream.Monadic (map,Stream,head,mapM,Step(..))
import Data.Vector.Fusion.Util (delay_inline)
import Debug.Trace
import Prelude hiding (map,head,mapM)
import Data.Bits.Extras
import Data.Bits
import ADP.Fusion.Core
import ADP.Fusion.Core.Unit
import Data.Bits.Ordered
import Data.PrimitiveArray hiding (map)
import ADP.Fusion.Core.Boundary
import ADP.Fusion.Core.EdgeBoundary
import ADP.Fusion.Core.Set1
instance
( IndexHdr s x0 i0 us (BS1 k I) cs c is (BS1 k I)
) => AddIndexDense s (us:.BS1 k I) (cs:.c) (is:.BS1 k I) where
addIndexDenseGo (cs:.c) (vs:.IStatic rb) (lbs:._) (ubs:._) (us:.BS1 uSet uBnd) (is:.BS1 set bnd)
= map (\(SvS s t y') ->
let RiBs1I (BS1 cset (Boundary to)) = getIndex (getIdx s) (Proxy :: PRI is (BS1 k I))
in assert (cset == 0 && to == (1)) $ SvS s (t:.BS1 set bnd) (y' :.: RiBs1I (BS1 set bnd)))
. addIndexDenseGo cs vs lbs ubs us is
. assert (rb==0)
addIndexDenseGo (cs:.c) (vs:.IVariable rb) (lbs:._) (ubs:._) (us:.BS1 uSet uBnd) (is:.BS1 set bnd)
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is . assert (rb==1)
where mk (SvS s t y') =
let
in
#if ADPFUSION_DEBUGOUTPUT
traceShow (set,bnd,rb) $
#endif
return (SvS s t y', Just $ set `clearBit` getBoundary bnd)
step (_, Nothing) = return Done
step (SvS s t y', Just 0 ) = return $ Yield (SvS s (t:.BS1 0 0) (y':.:RiBs1I (BS1 0 0)))
(SvS s t y', Nothing)
step (SvS s t y', Just bits) =
let nbnd = lsbZ bits
nset = set `clearBit` getBoundary bnd
bs1 = BS1 nset (Boundary nbnd)
in
return $ Yield (SvS s (t:.bs1) (y':.:RiBs1I bs1))
(SvS s t y', Just $ bits `clearBit` nbnd)
instance
( IndexHdr s x0 i0 us (BS1 k O) cs c is (BS1 k O)
) => AddIndexDense s (us:.BS1 k O) (cs:.c) (is:.BS1 k O) where
addIndexDenseGo (cs:.c) (vs:.ORightOf rb) (lbs:._) (ubs:._) (us:.BS1 uSet uBnd) (is:.BS1 cSet cBnd)
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is . assert (rb==1)
where mk (SvS s t y') =
let possible = uSet .&. complement cSet
in
#if ADPFUSION_DEBUGOUTPUT
traceShow ("aIDG/BS1/O/mk",(BS1 uSet uBnd), (BS1 cSet cBnd), possible) $
#endif
return (SvS s t y', possible)
step (_, k) | popCount uSet == popCount cSet = return Done
step (_, 0) = return Done
step (SvS s t y', bits) =
let nbnd = lsbZ bits
nset = cSet `setBit` nbnd
bs1 = BS1 nset (Boundary nbnd)
in
#if ADPFUSION_DEBUGOUTPUT
traceShow ("aIDG/BS1/O/step",(BS1 nset (Boundary nbnd))) $
#endif
return $ Yield (SvS s (t:.bs1) (y':.:RiBs1O bs1))
(SvS s t y', bits `clearBit` nbnd)
instance
( IndexHdr s x0 i0 us (BS1 k I) cs c is (BS1 k O)
) => AddIndexDense s (us:.BS1 k I) (cs:.c) (is:.BS1 k O) where
instance
( IndexHdr s x0 i0 us (BS1 k I) cs c is (Unit I)
) => AddIndexDense s (us:.BS1 k I) (cs:.c) (is:.Unit I) where
addIndexDenseGo (cs:.c) (vs:.IStatic ()) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:._)
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is
where mk (SvS s t y') = return $ (SvS s t y', fullSet)
step (_, 0) = return Done
step (SvS s t y', bits)
| b <- lsb bits = return $ Yield (SvS s (t:.BS1 fullSet (Boundary b)) (y':.:RiU))
(SvS s t y', bits `clearBit` b)
instance
( IndexHdr s x0 i0 us (BS1 k I) cs c is (Boundary k I)
) => AddIndexDense s (us:.BS1 k I) (cs:.c) (is:.Boundary k I) where
addIndexDenseGo (cs:.c) (vs:.IStatic ()) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:.i)
= map (\(SvS s t y') -> SvS s (t:.BS1 fullSet i) (y':.:RiBI i))
. addIndexDenseGo cs vs lbs ubs us is
instance
( IndexHdr s x0 i0 us (BS1 First I) cs c is (EdgeBoundary I)
) => AddIndexDense s (us:.BS1 First I) (cs:.c) (is:.EdgeBoundary I) where
addIndexDenseGo (cs:.c) (vs:.IStatic k) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:.(from :-> to))
= map (\(SvS s t y') ->
let RiEBI usedSet (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary I))
hereBits = fullSet .&. complement usedSet
hereSet = hereBits `setBit` to
in SvS s (t:.BS1 hereSet (Boundary to)) (y':.:RiEBI fullSet (from :-> to)))
. addIndexDenseGo cs vs lbs ubs us is
instance
( IndexHdr s x0 i0 us (BS1 Last I) cs c is (EdgeBoundary I)
) => AddIndexDense s (us:.BS1 Last I) (cs:.c) (is:.EdgeBoundary I) where
addIndexDenseGo (cs:.c) (vs:.IVariable rb) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:.(from :-> to))
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is
where mk (SvS s t y') =
let RiEBI usedBits (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary I))
in assert (usedBits == 0) . return $ (SvS s t y', Just (zeroBits :: BitSet I))
step (_, (Nothing :: Maybe (BitSet I))) = return $ Done
step (SvS s t y', Just cbits)
| popCount cbits > maxCount = return $ Done
| otherwise =
let sbits = popShiftL shiftMask cbits
cset = sbits `setBit` from
in return $ Yield (SvS s (t:.BS1 cset (Boundary from)) (y':.:RiEBI cset (from :-> to)))
(SvS s t y', setSucc zeroBits (BitSet $ 2^maxCount1) cbits)
!maxCount = popCount fullSet rb 1
!shiftMask = fullSet `clearBit` from `clearBit` to
instance
( IndexHdr s x0 i0 us (BS1 First I) cs c is (EdgeBoundary C)
) => AddIndexDense s (us:.BS1 First I) (cs:.c) (is:.EdgeBoundary C) where
addIndexDenseGo (cs:.c) (vs:.CStatic()) (lbs:._) (ubs:.BS1 (BitSet fullSet) _) (us:._) (is:.(from :-> to))
= map (\(SvS s t y') ->
let RiEBC (BitSet usedSet) (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary C))
hereBits = fullSet .&. complement usedSet
hereSet = hereBits `setBit` to
in SvS s (t:.BS1 (BitSet hereSet) (Boundary to)) (y':.:RiEBC (BitSet fullSet) (from :-> to)))
. addIndexDenseGo cs vs lbs ubs us is
addIndexDenseGo (cs:.c) (vs:.CVariable ()) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:.(from :-> to))
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is
where mk (SvS s t y') =
let RiEBC usedBits (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary C))
in assert (usedBits == 0) . return $ (SvS s t y', Just (zeroBits :: BitSet I))
step (_, Nothing) = return $ Done
step (SvS s t y', Just cbits)
| popCount cbits > maxCount = return $ Done
| otherwise =
let sbits = popShiftL shiftMask cbits
cset = getBitSet $ sbits `setBit` from
in return $ Yield (SvS s (t:.BS1 (BitSet cset) (Boundary from)) (y':.:RiEBC (BitSet cset) (from :-> to)))
(SvS s t y', setSucc zeroBits (BitSet $ 2^maxCount1) cbits)
!maxCount = popCount fullSet 1
!shiftMask = fullSet `clearBit` from `clearBit` to
instance
( IndexHdr s x0 i0 us (BS1 First O) cs c is (EdgeBoundary C)
) => AddIndexDense s (us:.BS1 First O) (cs:.c) (is:.EdgeBoundary C) where
addIndexDenseGo (cs:.c) (vs:.CStatic()) (lbs:._) (ubs:.BS1 (BitSet fullSet) _) (us:._) (is:.(from :-> to))
= map (\(SvS s t y') ->
let RiEBC (BitSet usedSet) (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary C))
hereBits = fullSet .&. complement usedSet
hereSet = hereBits `setBit` to
in SvS s (t:.BS1 (BitSet hereSet) (Boundary to)) (y':.:RiEBC (BitSet fullSet) (from :-> to)))
. addIndexDenseGo cs vs lbs ubs us is
addIndexDenseGo (cs:.c) (vs:.CVariable ()) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:.(from :-> to))
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is
where mk (SvS s t y') =
let RiEBC usedBits (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary C))
in assert (usedBits == 0) . return $ (SvS s t y', Just (zeroBits :: BitSet O))
step (_, Nothing) = return $ Done
step (SvS s t y', Just cbits)
| popCount cbits > maxCount = return $ Done
| otherwise =
let sbits = popShiftL shiftMask cbits
cset = getBitSet $ sbits `setBit` from
in return $ Yield (SvS s (t:.BS1 (BitSet cset) (Boundary from)) (y':.:RiEBC (BitSet cset) (from :-> to)))
(SvS s t y', setSucc zeroBits (BitSet $ 2^maxCount1) cbits)
!maxCount = popCount fullSet 1
!shiftMask = fullSet `clearBit` from `clearBit` to
instance
( IndexHdr s x0 i0 us (BS1 Last I) cs c is (EdgeBoundary C)
) => AddIndexDense s (us:.BS1 Last I) (cs:.c) (is:.EdgeBoundary C) where
addIndexDenseGo (cs:.c) (vs:.CVariable ()) (lbs:._) (ubs:.BS1 fullSet _) (us:._) (is:.(from :-> to))
= flatten mk step . addIndexDenseGo cs vs lbs ubs us is
where mk (SvS s t y') =
let RiEBC usedBits (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary C))
in assert (usedBits == 0) . return $ (SvS s t y', Just (zeroBits :: BitSet I))
step (_, Nothing) = return $ Done
step (SvS s t y', Just cbits)
| popCount cbits > maxCount = return $ Done
| (zeroBits `setBit` from `setBit` to) .&. cbits > 0 =
return $ Skip (SvS s t y', setSucc zeroBits (BitSet $ 2^maxCount1) cbits)
| otherwise =
let sbits = cbits
cset = getBitSet $ sbits `setBit` from
in
#if ADPFUSION_DEBUGOUTPUT
traceShow ("EB/BS1-Last-I/C/step",(BS1 (BitSet cset) (Boundary from))) $
#endif
return $ Yield (SvS s (t:.BS1 (BitSet cset) (Boundary from)) (y':.:RiEBC (BitSet cset) (from :-> to)))
(SvS s t y', setSucc zeroBits (BitSet $ 2^maxCount1) cbits)
!maxCount = popCount fullSet 1
!shiftMask = fullSet `clearBit` from `clearBit` to
instance
( IndexHdr s x0 i0 us (BS1 Last O) cs c is (EdgeBoundary C)
) => AddIndexDense s (us:.BS1 Last O) (cs:.c) (is:.EdgeBoundary C) where
addIndexDenseGo (cs:.c) (vs:.CStatic()) (lbs:._) (ubs:.BS1 (BitSet fullSet) _) (us:._) (is:.(from :-> to))
= map (\(SvS s t y') ->
let RiEBC (BitSet usedSet) (_ :-> _) = getIndex (getIdx s) (Proxy :: PRI is (EdgeBoundary C))
hereBits = usedSet
hereSet = hereBits `setBit` to `setBit` from
in
#if ADPFUSION_DEBUGOUTPUT
traceShow ("EB/BS1-Last-O/C/step",(BS1 (BitSet hereSet) (Boundary to))) $
#endif
SvS s (t:.BS1 (BitSet hereSet) (Boundary to)) (y':.:RiEBC (BitSet fullSet) (from :-> to)))
. addIndexDenseGo cs vs lbs ubs us is