module Data.Number.Flint.Fmpq.Poly.Instances ( FmpqPoly (..) ) where import GHC.Exts import System.IO.Unsafe import Control.Monad import Foreign.C.String import Foreign.Marshal.Alloc import Text.ParserCombinators.ReadP import Data.Ratio hiding (numerator, denominator) import Data.Char import Data.Number.Flint.Fmpz import Data.Number.Flint.Fmpz.Instances import Data.Number.Flint.Fmpq import Data.Number.Flint.Fmpq.Instances import Data.Number.Flint.Fmpq.Poly instance IsList FmpqPoly where type Item FmpqPoly = Fmpq fromList c = unsafePerformIO $ do p <- newFmpqPoly withFmpqPoly p $ \p -> do forM_ [0..length c-1] $ \j -> do withFmpq (c!!j) $ \a -> fmpq_poly_set_coeff_fmpq p (fromIntegral j) a return p toList p = snd $ unsafePerformIO $ do withFmpqPoly p $ \p -> do d <- fmpq_poly_degree p forM [0..d] $ \j -> do c <- newFmpq withFmpq c $ \c -> fmpq_poly_get_coeff_fmpq c p j return c instance Show FmpqPoly where show p = snd $ unsafePerformIO $ do withFmpqPoly p $ \p -> do withCString "x" $ \x -> do cs <- fmpq_poly_get_str_pretty p x s <- peekCString cs free cs return s instance Read FmpqPoly where readsPrec _ = readP_to_S parseFmpqPoly instance Num FmpqPoly where (*) = lift2 fmpq_poly_mul (+) = lift2 fmpq_poly_add (-) = lift2 fmpq_poly_sub abs = undefined signum = undefined fromInteger x = fst $ unsafePerformIO $ do let t = fromInteger x :: Fmpz withNewFmpqPoly $ \poly -> do withFmpz t $ \x -> do fmpq_poly_set_fmpz poly x lift2 f x y = unsafePerformIO $ do result <- newFmpqPoly withFmpqPoly result $ \result -> do withFmpqPoly x $ \x -> do withFmpqPoly y $ \y -> do f result x y return result parseFmpqPoly :: ReadP FmpqPoly parseFmpqPoly = do n <- parseItemNumber v <- count n parseItem return $ fromList v where parseItemNumber = read <$> munch1 isNumber <* char ' ' parseItem = read <$> (char ' ' *> parseFrac) parseFrac = parseFraction <++ parseNumber parseFraction = fst <$> gather (parseNumber *> char '/' *> parsePositive) parseNumber = parseNegative <++ parsePositive parseNegative = fst <$> gather (char '-' *> munch1 isNumber) parsePositive = munch1 isNumber