{- | module: $Header$ description: Prime natural numbers license: MIT maintainer: Joe Leslie-Hurd stability: provisional portability: portable -} module OpenTheory.Natural.Prime.Sieve where import qualified OpenTheory.Primitive.Natural as Natural newtype Sieve = Sieve { unSieve :: (Natural.Natural, [(Natural.Natural, (Natural.Natural, Natural.Natural))]) } initial :: Sieve initial = Sieve (1, []) increment :: Sieve -> (Bool, Sieve) increment = \s -> let (n, ps) = unSieve s in let n' = n + 1 in let (b, ps') = inc n' 1 ps in (b, Sieve (n', ps')) where {-inc :: Natural.Natural -> Natural.Natural -> [(Natural.Natural, (Natural.Natural, Natural.Natural))] -> (Bool, [(Natural.Natural, (Natural.Natural, Natural.Natural))])-} inc n _ [] = (True, (n, (0, 0)) : []) inc n i ((p, (k, j)) : ps) = let k' = (k + i) `mod` p in let j' = j + i in if k' == 0 then (False, (p, (0, j')) : ps) else let (b, ps') = inc n j' ps in (b, (p, (k', 0)) : ps') perimeter :: Sieve -> Natural.Natural perimeter s = fst (unSieve s) next :: Sieve -> (Natural.Natural, Sieve) next s = let (b, s') = increment s in if b then (perimeter s', s') else next s'