module PureSAT.LCG (
LCG,
newLCG,
nextLCG,
) where
import Control.Monad.ST (ST)
import Data.Primitive.PrimVar
import Data.Word (Word64)
newtype LCG s = LCG (PrimVar s Word64)
newLCG :: Word64 -> ST s (LCG s)
newLCG :: forall s. Word64 -> ST s (LCG s)
newLCG Word64
seed = PrimVar s Word64 -> LCG s
forall s. PrimVar s Word64 -> LCG s
LCG (PrimVar s Word64 -> LCG s)
-> ST s (PrimVar s Word64) -> ST s (LCG s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Word64 -> ST s (PrimVar (PrimState (ST s)) Word64)
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
a -> m (PrimVar (PrimState m) a)
newPrimVar (Word64 -> Word64 -> Word64
forall a. Ord a => a -> a -> a
max Word64
1 (Word64 -> Word64 -> Word64
forall a. Ord a => a -> a -> a
min Word64
0x7fffffe Word64
seed))
nextLCG :: LCG s -> ST s Word64
nextLCG :: forall s. LCG s -> ST s Word64
nextLCG (LCG PrimVar s Word64
state) = do
s <- PrimVar (PrimState (ST s)) Word64 -> ST s Word64
forall (m :: * -> *) a.
(PrimMonad m, Prim a) =>
PrimVar (PrimState m) a -> m a
readPrimVar PrimVar s Word64
PrimVar (PrimState (ST s)) Word64
state
let !s' = Word64 -> Word64 -> Word64
forall a. Integral a => a -> a -> a
mod (Word64
s Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
* Word64
48271) Word64
0x7fffffff
writePrimVar state s'
return s'