{-# LANGUAGE NoImplicitPrelude #-} module Number.ResidueClass where import qualified Algebra.PrincipalIdealDomain as PID import qualified Algebra.IntegralDomain as Integral -- import qualified Algebra.Additive as Additive -- import qualified Algebra.ZeroTestable as ZeroTestable import NumericPrelude.Base import NumericPrelude.Numeric hiding (recip) import Data.Maybe.HT (toMaybe) import Data.Maybe (fromMaybe) add, sub :: (Integral.C a) => a -> a -> a -> a add m x y = mod (x+y) m sub m x y = mod (x-y) m neg :: (Integral.C a) => a -> a -> a neg m x = mod (-x) m mul :: (Integral.C a) => a -> a -> a -> a mul m x y = mod (x*y) m {- | The division may be ambiguous. In this case an arbitrary quotient is returned. @ 0/:4 * 2/:4 == 0/:4 2/:4 * 2/:4 == 0/:4 @ -} divideMaybe :: (PID.C a) => a -> a -> a -> Maybe a divideMaybe m x y = let (d,(_,z)) = extendedGCD m y (q,r) = divMod x d in toMaybe (isZero r) (mod (q*z) m) divide :: (PID.C a) => a -> a -> a -> a divide m x y = fromMaybe (error "ResidueClass.divide: indivisible") (divideMaybe m x y) recip :: (PID.C a) => a -> a -> a recip m = divide m one