module AlgebraicPrelude
(module AlgebraicPrelude,
P.Num(abs,signum),P.Integral(),P.toInteger, P.Real(..), P.Fractional (),
P.Floating(..), P.RealFrac(..), P.RealFloat(..),
) where
import BasicPrelude as AlgebraicPrelude hiding
(Floating (..),
Fractional (..),
Integral (..),
Num (..),
Rational,
Real (..),
RealFloat (..),
RealFrac (..),
fromShow,
gcd,
getArgs,
getContents,
getLine,
id,
interact,
lcm,
lines,
product,
putStr,
putStrLn,
read,
readFile,
show,
subtract,
sum,
unlines,
unwords,
words,
writeFile,
(.),
(\\),
(^),
(^^))
import qualified Control.Lens.TH as L
import qualified Data.Ratio as P
import qualified Data.Semigroup as Semi
import GHC.OverloadedLabels as AlgebraicPrelude
import Numeric.Algebra as AlgebraicPrelude hiding
(Order (..),
fromInteger,
(^))
import qualified Numeric.Algebra as NA
import Numeric.Algebra.Unital.UnitNormalForm as AlgebraicPrelude hiding
(normalize)
import qualified Numeric.Algebra.Unital.UnitNormalForm as NA
import Numeric.Decidable.Associates as AlgebraicPrelude
import Numeric.Decidable.Units as AlgebraicPrelude
import Numeric.Decidable.Zero as AlgebraicPrelude
import Numeric.Domain.Class as AlgebraicPrelude
import Numeric.Domain.Euclidean as AlgebraicPrelude
import Numeric.Domain.GCD as AlgebraicPrelude
import Numeric.Domain.Integral as AlgebraicPrelude
import Numeric.Domain.PID as AlgebraicPrelude
import Numeric.Domain.UFD as AlgebraicPrelude
import Numeric.Field.Fraction as AlgebraicPrelude
import Numeric.Semiring.ZeroProduct as AlgebraicPrelude
import Prelude as AlgebraicPrelude (Show (..),
ceiling,
div,
floor,
getContents,
getLine,
id,
interact,
lines,
mod,
putStr,
putStrLn,
readFile,
show,
unlines,
unwords,
words,
writeFile,
(.))
import qualified Prelude as P
type Rational = Fraction Integer
infixr 8 ^, ^^
fromInteger :: P.Num r => Integer -> r
fromInteger = P.fromInteger
fromInteger' :: Ring r => Integer -> r
fromInteger' = NA.fromInteger
fromRational :: DivisionRing r => P.Rational -> r
fromRational r = NA.fromInteger (P.numerator r) / NA.fromInteger (P.denominator r)
normaliseUnit :: UnitNormalForm r => r -> r
normaliseUnit = NA.normalize
(^) :: Unital r => r -> Natural -> r
(^) = pow
(^^) :: Division r => r -> Integer -> r
(^^) = (NA.^)
ifThenElse :: Bool -> a -> a -> a
ifThenElse p t f = if p then t else f
newtype WrapNum a = WrapNum { unwrapNum :: a }
deriving (Read, Show, Eq, Ord)
instance (P.Num a) => Additive (WrapNum a) where
WrapNum a + WrapNum b = WrapNum (a P.+ b)
sinnum1p n (WrapNum a) = WrapNum ((1 P.+ fromIntegral n) P.* a)
instance (P.Num a) => LeftModule Natural (WrapNum a) where
n .* WrapNum r = WrapNum (P.fromIntegral n P.* r)
instance (P.Num a) => RightModule Natural (WrapNum a) where
WrapNum r *. n = WrapNum (r P.* P.fromIntegral n)
instance (P.Num a) => Monoidal (WrapNum a) where
zero = WrapNum (P.fromInteger 0)
sinnum n (WrapNum a) = WrapNum ((fromIntegral n) P.* a)
instance (P.Num a) => LeftModule Integer (WrapNum a) where
n .* WrapNum r = WrapNum (P.fromIntegral n P.* r)
instance (P.Num a) => RightModule Integer (WrapNum a) where
WrapNum r *. n = WrapNum (r P.* P.fromIntegral n)
instance (P.Num a) => Group (WrapNum a) where
negate (WrapNum a) = WrapNum $ P.negate a
WrapNum a WrapNum b = WrapNum (a P.- b)
subtract (WrapNum a) (WrapNum b) = WrapNum (P.subtract a b)
times n (WrapNum a) = WrapNum $ fromIntegral n P.* a
instance (P.Num a) => Multiplicative (WrapNum a) where
WrapNum p * WrapNum q = WrapNum (p P.* q)
pow1p (WrapNum p) n = WrapNum (p P.^ (n + 1))
instance (P.Num a) => Unital (WrapNum a) where
one = WrapNum $ P.fromInteger 1
pow (WrapNum a) n = WrapNum $ a P.^ n
instance P.Num a => Abelian (WrapNum a)
instance P.Num a => Semiring (WrapNum a)
instance P.Num a => Rig (WrapNum a) where
fromNatural = WrapNum . P.fromIntegral
instance P.Num a => Ring (WrapNum a) where
fromInteger = WrapNum . P.fromInteger
instance P.Num a => Commutative (WrapNum a)
instance (P.Num a, Eq a) => DecidableZero (WrapNum a) where
isZero (WrapNum a) = a == 0
newtype WrapFractional a = WrapFractional { unwrapFractional :: a }
instance (P.Num a) => Additive (WrapFractional a) where
WrapFractional a + WrapFractional b = WrapFractional (a P.+ b)
sinnum1p n (WrapFractional a) = WrapFractional ((1 P.+ fromIntegral n) P.* a)
instance (P.Num a) => LeftModule Natural (WrapFractional a) where
n .* WrapFractional r = WrapFractional (P.fromIntegral n P.* r)
instance (P.Num a) => RightModule Natural (WrapFractional a) where
WrapFractional r *. n = WrapFractional (r P.* P.fromIntegral n)
instance (P.Num a) => Monoidal (WrapFractional a) where
zero = WrapFractional (P.fromInteger 0)
sinnum n (WrapFractional a) = WrapFractional ((fromIntegral n) P.* a)
instance (P.Num a) => LeftModule Integer (WrapFractional a) where
n .* WrapFractional r = WrapFractional (P.fromIntegral n P.* r)
instance (P.Num a) => RightModule Integer (WrapFractional a) where
WrapFractional r *. n = WrapFractional (r P.* P.fromIntegral n)
instance (P.Num a) => Group (WrapFractional a) where
negate (WrapFractional a) = WrapFractional $ P.negate a
WrapFractional a WrapFractional b = WrapFractional (a P.- b)
subtract (WrapFractional a) (WrapFractional b) = WrapFractional (P.subtract a b)
times n (WrapFractional a) = WrapFractional $ fromIntegral n P.* a
instance (P.Num a) => Multiplicative (WrapFractional a) where
WrapFractional p * WrapFractional q = WrapFractional (p P.* q)
pow1p (WrapFractional p) n = WrapFractional (p P.^ (n + 1))
instance (P.Num a) => Unital (WrapFractional a) where
one = WrapFractional $ P.fromInteger 1
pow (WrapFractional a) n = WrapFractional $ a P.^ n
instance P.Num a => Abelian (WrapFractional a)
instance P.Num a => Semiring (WrapFractional a)
instance P.Num a => Rig (WrapFractional a) where
fromNatural = WrapFractional . P.fromIntegral
instance P.Num a => Ring (WrapFractional a) where
fromInteger = WrapFractional . P.fromInteger
instance P.Num a => Commutative (WrapFractional a)
instance (P.Num a, Eq a) => DecidableZero (WrapFractional a) where
isZero (WrapFractional a) = a == 0
instance P.Fractional a => Division (WrapFractional a) where
recip = WrapFractional . P.recip . unwrapFractional
WrapFractional a / WrapFractional b = WrapFractional $ a P./ b
WrapFractional a \\ WrapFractional b = WrapFractional $ P.recip a P.* b
WrapFractional a ^ n = WrapFractional (a P.^^ n)
instance (Eq a, P.Fractional a) => ZeroProductSemiring (WrapFractional a)
instance (Eq a, P.Fractional a) => DecidableUnits (WrapFractional a) where
isUnit (WrapFractional r) = r /= 0
recipUnit (WrapFractional r) =
if r == 0
then Nothing
else Just (WrapFractional $ P.recip r)
instance (Eq a, P.Fractional a) => DecidableAssociates (WrapFractional a) where
isAssociate (WrapFractional a) (WrapFractional b) =
(a == 0 && b == 0) || (a /= 0 && b /= 0)
instance (Eq a, P.Fractional a) => UnitNormalForm (WrapFractional a)
instance (Eq a, P.Fractional a) => IntegralDomain (WrapFractional a)
instance (Eq a, P.Fractional a) => GCDDomain (WrapFractional a)
instance (Eq a, P.Fractional a) => Euclidean (WrapFractional a)
instance (Eq a, P.Fractional a) => PID (WrapFractional a)
instance (Eq a, P.Fractional a) => UFD (WrapFractional a)
newtype WrapIntegral a = WrapIntegral { unwrapIntegral :: a }
instance (P.Num a) => Additive (WrapIntegral a) where
WrapIntegral a + WrapIntegral b = WrapIntegral (a P.+ b)
sinnum1p n (WrapIntegral a) = WrapIntegral ((1 P.+ fromIntegral n) P.* a)
instance (P.Num a) => LeftModule Natural (WrapIntegral a) where
n .* WrapIntegral r = WrapIntegral (P.fromIntegral n P.* r)
instance (P.Num a) => RightModule Natural (WrapIntegral a) where
WrapIntegral r *. n = WrapIntegral (r P.* P.fromIntegral n)
instance (P.Num a) => Monoidal (WrapIntegral a) where
zero = WrapIntegral (P.fromInteger 0)
sinnum n (WrapIntegral a) = WrapIntegral ((fromIntegral n) P.* a)
instance (P.Num a) => LeftModule Integer (WrapIntegral a) where
n .* WrapIntegral r = WrapIntegral (P.fromIntegral n P.* r)
instance (P.Num a) => RightModule Integer (WrapIntegral a) where
WrapIntegral r *. n = WrapIntegral (r P.* P.fromIntegral n)
instance (P.Num a) => Group (WrapIntegral a) where
negate (WrapIntegral a) = WrapIntegral $ P.negate a
WrapIntegral a WrapIntegral b = WrapIntegral (a P.- b)
subtract (WrapIntegral a) (WrapIntegral b) = WrapIntegral (P.subtract a b)
times n (WrapIntegral a) = WrapIntegral $ fromIntegral n P.* a
instance (P.Num a) => Multiplicative (WrapIntegral a) where
WrapIntegral p * WrapIntegral q = WrapIntegral (p P.* q)
pow1p (WrapIntegral p) n = WrapIntegral (p P.^ (n + 1))
instance (P.Num a) => Unital (WrapIntegral a) where
one = WrapIntegral $ P.fromInteger 1
pow (WrapIntegral a) n = WrapIntegral $ a P.^ n
instance P.Num a => Abelian (WrapIntegral a)
instance P.Num a => Semiring (WrapIntegral a)
instance P.Num a => Rig (WrapIntegral a) where
fromNatural = WrapIntegral . P.fromIntegral
instance P.Num a => Ring (WrapIntegral a) where
fromInteger = WrapIntegral . P.fromInteger
instance P.Num a => Commutative (WrapIntegral a)
instance (P.Num a, Eq a) => DecidableZero (WrapIntegral a) where
isZero (WrapIntegral a) = a == 0
instance (Eq a, P.Integral a) => ZeroProductSemiring (WrapIntegral a)
instance (Eq a, P.Integral a) => DecidableUnits (WrapIntegral a) where
isUnit (WrapIntegral r) = r == 1 || r == P.negate 1
recipUnit (WrapIntegral r) =
if isUnit (WrapIntegral r)
then Nothing
else Just (WrapIntegral r)
instance (Eq a, P.Integral a) => DecidableAssociates (WrapIntegral a) where
isAssociate (WrapIntegral a) (WrapIntegral b) = P.abs a == P.abs b
instance (Eq a, P.Integral a) => UnitNormalForm (WrapIntegral a) where
splitUnit (WrapIntegral 0) = (WrapIntegral 1, WrapIntegral 0)
splitUnit (WrapIntegral a) = (WrapIntegral $ P.signum a, WrapIntegral $ P.abs a)
instance (Eq a, P.Integral a) => IntegralDomain (WrapIntegral a)
instance (Eq a, P.Integral a) => GCDDomain (WrapIntegral a) where
gcd (WrapIntegral a) (WrapIntegral b) = WrapIntegral (P.gcd a b)
lcm (WrapIntegral a) (WrapIntegral b) = WrapIntegral (P.lcm a b)
instance (Eq a, P.Integral a) => Euclidean (WrapIntegral a) where
divide (WrapIntegral f) (WrapIntegral g) =
let (q, r) = P.divMod f g
in (WrapIntegral q, WrapIntegral r)
degree (WrapIntegral 0) = Nothing
degree (WrapIntegral a) = Just $ P.fromIntegral (P.abs a)
quot (WrapIntegral a) (WrapIntegral b) = WrapIntegral $ P.div a b
rem (WrapIntegral a) (WrapIntegral b) = WrapIntegral $ P.mod a b
instance (Eq a, P.Integral a) => PID (WrapIntegral a)
instance (Eq a, P.Integral a) => UFD (WrapIntegral a)
newtype WrapAlgebra a = WrapAlgebra { unwrapAlgebra :: a }
deriving (Read, Show, Eq, Ord)
instance (Ring a, UnitNormalForm a) => P.Num (WrapAlgebra a) where
WrapAlgebra a + WrapAlgebra b = WrapAlgebra $ a NA.+ b
WrapAlgebra a WrapAlgebra b = WrapAlgebra $ a NA.- b
WrapAlgebra a * WrapAlgebra b = WrapAlgebra $ a NA.* b
fromInteger = WrapAlgebra . NA.fromInteger
signum = WrapAlgebra . leadingUnit . unwrapAlgebra
abs = WrapAlgebra . normaliseUnit . unwrapAlgebra
negate = WrapAlgebra . negate . unwrapAlgebra
instance (DivisionRing a, UnitNormalForm a) => P.Fractional (WrapAlgebra a) where
WrapAlgebra a / WrapAlgebra b = WrapAlgebra (a / b)
recip (WrapAlgebra a) = WrapAlgebra (recip a)
fromRational = WrapAlgebra . fromRational
instance Euclidean a => P.Num (Fraction a) where
(+) = (NA.+)
() = (NA.-)
negate = NA.negate
(*) = (NA.*)
fromInteger = NA.fromInteger
abs = normaliseUnit
signum = leadingUnit
instance Euclidean d => P.Fractional (Fraction d) where
fromRational r = fromInteger' (P.numerator r) % fromInteger' (P.denominator r)
recip = NA.recip
(/) = (NA./)
newtype Add a = Add { runAdd :: a }
deriving (Read, Show, Eq, Ord, P.Num)
instance Additive a => Semi.Semigroup (Add a) where
Add a <> Add b = Add (a NA.+ b)
sconcat = Add . sum1 . map runAdd
stimes n = Add . sinnum1p (P.fromIntegral n P.- 1) . runAdd
instance Monoidal a => Monoid (Add a) where
mappend = (Semi.<>)
mempty = Add zero
mconcat = Add . sum . map runAdd
newtype Mult a = Mult { runMult :: a }
deriving (Read, Show, Eq, Ord, P.Num)
instance Multiplicative a => Semi.Semigroup (Mult a) where
Mult a <> Mult b = Mult (a NA.* b)
sconcat = Mult . product1 . map runMult
stimes n = Mult . flip pow1p (P.fromIntegral n P.- 1) . runMult
instance Unital a => Monoid (Mult a) where
mappend = (Semi.<>)
mempty = Mult one
mconcat = Mult . product . map runMult
L.makeWrapped ''WrapNum
L.makeWrapped ''WrapIntegral
L.makeWrapped ''WrapFractional
L.makeWrapped ''WrapAlgebra
L.makeWrapped ''Add
L.makeWrapped ''Mult