import System.Environment import System.TimeIt import Options.Applicative import Control.Monad import Control.Monad.State import Text.Read (readMaybe) import Foreign.C.Types import Foreign.Ptr import Data.Number.Flint main = do prog <- getProgName args <- getArgs case args of [arg0] -> case readMaybe arg0 :: Maybe Fmpz of Just x-> run x _ -> putStrLn $ "usage: " ++ prog ++ " ." _ -> putStrLn $ "usage: " ++ prog ++ " ." run x = do print x withFmpz x $ \x -> do bits <- fmpz_bits x withNewFmpz $ \y -> do fmpz_zero y withNewFmpz $ \prod -> do fmpz_one prod _ <- runStateT (next x (bits + 2)) (0, y, prod, 0) return () return () next :: Ptr CFmpz -> CFBitCnt -> StateT (Int, Ptr CFmpz, Ptr CFmpz, CULong) IO () next x bit_bound = do (i, y, prod, prime) <- get (prod', y', prime', bits) <- liftIO $ do prime' <- n_nextprime prime 0 res <- fmpz_fdiv_ui x prime' fmpz_CRT_ui y y prod res prime' 1 putStr $ "residue mod " ++ show prime' ++ " = " ++ show res putStr $ "; reconstruction = " fmpz_print y putStr "\n" fmpz_mul_ui prod prod prime' bits <- fmpz_bits prod return (prod, y, prime', bits) put (succ i, y', prod', prime') when (bits < bit_bound) $ next x bit_bound