module Simulation.Aivika.Trans.Vector
(Vector,
newVector,
copyVector,
vectorCount,
appendVector,
readVector,
writeVector,
vectorBinarySearch,
vectorInsert,
vectorDeleteAt,
vectorDeleteRange,
vectorDelete,
vectorDeleteBy,
vectorIndex,
vectorIndexBy,
vectorContains,
vectorContainsBy,
freezeVector) where
import Data.Array
import Control.Monad
import Simulation.Aivika.Trans.Simulation
import Simulation.Aivika.Trans.Event
import Simulation.Aivika.Trans.Ref.Base.Lazy
data Vector m a = Vector { vectorArrayRef :: Ref m (Array Int (Ref m a)),
vectorCountRef :: Ref m Int,
vectorCapacityRef :: Ref m Int }
newVector :: MonadRef m => Simulation m (Vector m a)
newVector =
do xs <- forM [0 .. 4 1] $ \i -> newRef undefined
let arr = array (0, 4 1) $ zip [0..] xs
arrRef <- newRef $! arr
countRef <- newRef $! 0
capacityRef <- newRef $! 4
return Vector { vectorArrayRef = arrRef,
vectorCountRef = countRef,
vectorCapacityRef = capacityRef }
copyVector :: MonadRef m => Vector m a -> Event m (Vector m a)
copyVector vector =
do arr <- readRef (vectorArrayRef vector)
count <- readRef (vectorCountRef vector)
xs' <-
forM [0 .. count 1] $ \i ->
do x <- readRef (arr ! i)
liftSimulation $ newRef x
let arr' = array (0, count 1) $ zip [0..] xs'
arrRef' <- liftSimulation $ newRef $! arr'
countRef' <- liftSimulation $ newRef $! count
capacityRef' <- liftSimulation $ newRef $! count
return Vector { vectorArrayRef = arrRef',
vectorCountRef = countRef',
vectorCapacityRef = capacityRef' }
vectorEnsureCapacity :: MonadRef m => Vector m a -> Int -> Event m ()
vectorEnsureCapacity vector capacity =
do capacity' <- readRef (vectorCapacityRef vector)
when (capacity' < capacity) $
do arr' <- readRef (vectorArrayRef vector)
count' <- readRef (vectorCountRef vector)
let capacity'' = max (2 * capacity') capacity
xs'' <-
forM [0 .. capacity'' 1] $ \i ->
liftSimulation $ newRef undefined
let arr'' = array (0, capacity'' 1) $ zip [0..] xs''
forM_ [0 .. count' 1] $ \i ->
do x <- readRef (arr' ! i)
writeRef (arr'' ! i) x
writeRef (vectorArrayRef vector) $! arr''
writeRef (vectorCapacityRef vector) $! capacity''
vectorCount :: MonadRef m => Vector m a -> Event m Int
vectorCount vector = readRef (vectorCountRef vector)
appendVector :: MonadRef m => Vector m a -> a -> Event m ()
appendVector vector item =
do count <- readRef (vectorCountRef vector)
vectorEnsureCapacity vector (count + 1)
arr <- readRef (vectorArrayRef vector)
writeRef (arr ! count) $! item
writeRef (vectorCountRef vector) $! (count + 1)
readVector :: MonadRef m => Vector m a -> Int -> Event m a
readVector vector index =
do arr <- readRef (vectorArrayRef vector)
readRef (arr ! index)
writeVector :: MonadRef m => Vector m a -> Int -> a -> Event m ()
writeVector vector index item =
do arr <- readRef (vectorArrayRef vector)
writeRef (arr ! index) $! item
vectorBinarySearch' :: (MonadRef m, Ord a) => Array Int (Ref m a) -> a -> Int -> Int -> Event m Int
vectorBinarySearch' arr item left right =
if left > right
then return $ (right + 1) 1
else
do let index = (left + right) `div` 2
curr <- readRef (arr ! index)
if item < curr
then vectorBinarySearch' arr item left (index 1)
else if item == curr
then return index
else vectorBinarySearch' arr item (index + 1) right
vectorBinarySearch :: (MonadRef m, Ord a) => Vector m a -> a -> Event m Int
vectorBinarySearch vector item =
do arr <- readRef (vectorArrayRef vector)
count <- readRef (vectorCountRef vector)
vectorBinarySearch' arr item 0 (count 1)
freezeVector :: MonadRef m => Vector m a -> Event m (Array Int a)
freezeVector vector =
do arr <- readRef (vectorArrayRef vector)
count <- readRef (vectorCountRef vector)
xs' <-
forM [0 .. count 1] $ \i ->
readRef (arr ! i)
let arr' = array (0, count 1) $ zip [0..] xs'
return arr'
vectorInsert :: MonadRef m => Vector m a -> Int -> a -> Event m ()
vectorInsert vector index item =
do count <- readRef (vectorCountRef vector)
when (index < 0) $
error $
"Index cannot be " ++
"negative: vectorInsert."
when (index > count) $
error $
"Index cannot be greater " ++
"than the count: vectorInsert."
vectorEnsureCapacity vector (count + 1)
arr <- readRef (vectorArrayRef vector)
forM_ [count, count 1 .. index + 1] $ \i ->
do x <- readRef (arr ! (i 1))
writeRef (arr ! i) x
writeRef (arr ! index) $! item
writeRef (vectorCountRef vector) $! (count + 1)
vectorDeleteAt :: MonadRef m => Vector m a -> Int -> Event m ()
vectorDeleteAt vector index =
do count <- readRef (vectorCountRef vector)
when (index < 0) $
error $
"Index cannot be " ++
"negative: vectorDeleteAt."
when (index >= count) $
error $
"Index must be less " ++
"than the count: vectorDeleteAt."
arr <- readRef (vectorArrayRef vector)
forM_ [index, index + 1 .. count 2] $ \i ->
do x <- readRef (arr ! (i + 1))
writeRef (arr ! i) x
writeRef (arr ! (count 1)) undefined
writeRef (vectorCountRef vector) $! (count 1)
vectorDeleteRange :: MonadRef m
=> Vector m a
-> Int
-> Int
-> Event m ()
vectorDeleteRange vector index len =
do count <- readRef (vectorCountRef vector)
when (index < 0) $
error $
"The first index cannot be " ++
"negative: vectorDeleteRange."
when (index + len 1 >= count) $
error $
"The last index must be less " ++
"than the count: vectorDeleteRange."
when (len < 0) $
error "Negative range length: vectorDeleteRange."
arr <- readRef (vectorArrayRef vector)
forM_ [index, index + 1 .. (count len) 1] $ \i ->
do x <- readRef (arr ! (i + len))
writeRef (arr ! i) x
forM_ [(count len) .. count 1] $ \i ->
writeRef (arr ! i) undefined
writeRef (vectorCountRef vector) $! (count len)
vectorIndex :: (MonadRef m, Eq a) => Vector m a -> a -> Event m Int
vectorIndex vector item =
do count <- readRef (vectorCountRef vector)
arr <- readRef (vectorArrayRef vector)
let loop index =
if index >= count
then return $ 1
else do x <- readRef (arr ! index)
if item == x
then return index
else loop $ index + 1
loop 0
vectorIndexBy :: MonadRef m => Vector m a -> (a -> Bool) -> Event m Int
vectorIndexBy vector pred =
do count <- readRef (vectorCountRef vector)
arr <- readRef (vectorArrayRef vector)
let loop index =
if index >= count
then return $ 1
else do x <- readRef (arr ! index)
if pred x
then return index
else loop $ index + 1
loop 0
vectorDelete :: (MonadRef m, Eq a) => Vector m a -> a -> Event m Bool
vectorDelete vector item =
do index <- vectorIndex vector item
if index >= 0
then do vectorDeleteAt vector index
return True
else return False
vectorDeleteBy :: MonadRef m => Vector m a -> (a -> Bool) -> Event m (Maybe a)
vectorDeleteBy vector pred =
do index <- vectorIndexBy vector pred
if index >= 0
then do a <- readVector vector index
vectorDeleteAt vector index
return (Just a)
else return Nothing
vectorContains :: (MonadRef m, Eq a) => Vector m a -> a -> Event m Bool
vectorContains vector item =
do index <- vectorIndex vector item
return (index >= 0)
vectorContainsBy :: MonadRef m => Vector m a -> (a -> Bool) -> Event m (Maybe a)
vectorContainsBy vector pred =
do index <- vectorIndexBy vector pred
if index >= 0
then do a <- readVector vector index
return (Just a)
else return Nothing