packages feed

constructive-algebra 0.1.5 → 0.1.6

raw patch · 7 files changed

+315/−22 lines, 7 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Algebra.Structures.BezoutDomain: instance (BezoutDomain a, Eq a) => PruferDomain a
- Algebra.Structures.BezoutDomain: instance (BezoutDomain a, Eq a) => StronglyDiscrete a
- Algebra.Structures.BezoutDomain: instance (EuclideanDomain a, Eq a) => BezoutDomain a
+ Algebra.EllipticCurve: C :: (Qx, Qx) -> EllipticCurve
+ Algebra.EllipticCurve: instance Arbitrary EllipticCurve
+ Algebra.EllipticCurve: instance Coherent EllipticCurve
+ Algebra.EllipticCurve: instance CommutativeRing EllipticCurve
+ Algebra.EllipticCurve: instance Eq EllipticCurve
+ Algebra.EllipticCurve: instance IntegralDomain EllipticCurve
+ Algebra.EllipticCurve: instance PruferDomain EllipticCurve
+ Algebra.EllipticCurve: instance Ring EllipticCurve
+ Algebra.EllipticCurve: instance Show EllipticCurve
+ Algebra.EllipticCurve: newtype EllipticCurve
+ Algebra.Structures.BezoutDomain: instance [overlap ok] (BezoutDomain a, Eq a) => PruferDomain a
+ Algebra.Structures.BezoutDomain: instance [overlap ok] (BezoutDomain a, Eq a) => StronglyDiscrete a
+ Algebra.Structures.BezoutDomain: instance [overlap ok] (EuclideanDomain a, Eq a) => BezoutDomain a
+ Algebra.Structures.PruferDomain: intersectionPD :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> Ideal a
+ Algebra.Structures.PruferDomain: intersectionPDWitness :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> (Ideal a, [[a]], [[a]])
+ Algebra.Structures.PruferDomain: solvePD :: (PruferDomain a, Eq a) => Vector a -> Matrix a
+ Algebra.Structures.Ring: (<*) :: (Ring a) => a -> Integer -> a
+ Algebra.ZSqrt5: ZSqrt5 :: (Z, Z) -> ZSqrt5
+ Algebra.ZSqrt5: instance Arbitrary ZSqrt5
+ Algebra.ZSqrt5: instance Coherent ZSqrt5
+ Algebra.ZSqrt5: instance CommutativeRing ZSqrt5
+ Algebra.ZSqrt5: instance Eq ZSqrt5
+ Algebra.ZSqrt5: instance IntegralDomain ZSqrt5
+ Algebra.ZSqrt5: instance Ord ZSqrt5
+ Algebra.ZSqrt5: instance PruferDomain ZSqrt5
+ Algebra.ZSqrt5: instance Ring ZSqrt5
+ Algebra.ZSqrt5: instance Show ZSqrt5
+ Algebra.ZSqrt5: newtype ZSqrt5
- Algebra.Structures.Ring: (*>) :: (Ring a) => Int -> a -> a
+ Algebra.Structures.Ring: (*>) :: (Ring a) => Integer -> a -> a

Files

constructive-algebra.cabal view
@@ -7,7 +7,7 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version:             0.1.5+Version:             0.1.6  Synopsis:            A library of constructive algebra. Description:         @@ -65,6 +65,8 @@                        Algebra.Matrix,                        Algebra.PLM,                        Algebra.UPoly,+                       Algebra.EllipticCurve,+                       Algebra.ZSqrt5,                        Algebra.Zn,                        Algebra.Z,                        Algebra.Q
+ src/Algebra/EllipticCurve.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+-- | The elliptic curve y^2 = 1 - x^4 in Q[x,y].+module Algebra.EllipticCurve (EllipticCurve(..)) where++import Test.QuickCheck++import Algebra.Structures.Field hiding ((<*), (*>))+import Algebra.Structures.EuclideanDomain (quotient, genEuclidAlg)+import Algebra.Structures.BezoutDomain (toPrincipal)+import Algebra.Structures.PruferDomain+import Algebra.Structures.Coherent+import Algebra.FieldOfRationalFunctions+import Algebra.Ideal+import Algebra.UPoly++-- | The elliptic curve y^2=1-x^4 over Q[x,y].+newtype EllipticCurve = C (Qx,Qx)+  deriving (Eq,Arbitrary)++instance Show EllipticCurve where+  show (C (a,b)) | a == zero && b == zero = "0"+                 | a == zero              = show b ++ "*y"+                 | b == zero              = show a+                 | otherwise = case show b of +                   ['-','1'] -> show a ++ "-y"+                   ('-':xs)  -> show a ++ "-" ++ xs ++ "*y"+                   xs        -> show a ++ "+" ++ xs ++ "*y" ++-- Arithmetical properties+instance Ring EllipticCurve where+  (C (a,b)) <+> (C (c,d)) = C (a + c, b + d)+  (C (a,b)) <*> (C (c,d)) = C (a*c + b*d*(1-x^4), a*d + b*c)+  neg (C (a,b))           = C (neg a, neg b)+  zero                    = C (zero,zero)+  one                     = C (one,zero)+  +instance CommutativeRing EllipticCurve where++instance IntegralDomain EllipticCurve where++propIntDomEC :: EllipticCurve -> EllipticCurve-> EllipticCurve -> Property+propIntDomEC = propIntegralDomain++--------------------------------------------------------------------------------+-- Useful auxiliary functions:++(*>), (+>) :: Qx -> EllipticCurve -> EllipticCurve+r *> (C (a,b)) = C (r*a,r*b)+r +> (C (a,b)) = C (r+a,b)++(<*), (<+) :: EllipticCurve -> Qx -> EllipticCurve+(C (a,b)) <* r = C (a*r,b*r)+(C (a,b)) <+ r = C (a+r,b)++infixl 7 *>, <*+infixl 6 +>, <+++--------------------------------------------------------------------------------++instance PruferDomain EllipticCurve where+  calcUVW (C (a,b)) (C (c,d)) = (u,v,w)+    where+    p = toQX (a * c - b * d * (1 - x^4)) </> toQX (c^2 - d^2 * (1 - x^4))+    q = toQX (b * c - a * d) </> toQX (c^2 - d^2 * (1 - x^4))++    s :: (QX,QX) +    s = (p,q)++    -- a0's^2 + a1's + a2' = 0+    a0' = (c^2 - d^2 * (1 - x^4))^2+    a1' = -2 * (a * c - b * d * (1 - x^4)) * (c^2 - d^2 * (1 - x^4))+    a2' = (a * c - b * d * (1 - x^4))^2 - ((b * c - a * d)^2 * (1-x^4))++    -- Make <a0,a1,a2> = 1+    g  = genEuclidAlg [a0',a1',a2']+    a0 = a0' `quotient` g+    a1 = a1' `quotient` g+    a2 = a2' `quotient` g++    -- n0 * a0 + n1 * a1 + n2 * a2 = 1+    (Id [g'],[n0,n1,n2],_) = toPrincipal (Id [a0,a1,a2])++    a0s    = case s of+      (p,q) -> C (toQx (a0' <*> p), toQx (a0' <*> q))+      where a0' = toQX a0+    a0sa1  = a0s <+ a1+    a0sa1s = C (neg a2,zero)++    alpha = a0s +    beta  = a0sa1s++    m0 = n0+    m1 = -n1+    m2 = n1+    m3 = -n2++    u = m0 * a0 +> m2 *> a0sa1+    v = m0 *> alpha <+> m2 *> beta+    w = m1 * a0 +> m3 *> a0sa1++instance Coherent EllipticCurve where+  solve = solvePD++-- Properties:+propPruferDomEC :: EllipticCurve -> EllipticCurve -> EllipticCurve -> Property+propPruferDomEC x@(C (a,b)) y@(C (c,d)) z@(C (e,f)) = +  a /= zero && b /= zero && c /= zero && d /= zero && e /= zero && f /= zero +  ==> propPruferDomain x y z++propIntersectionPEC :: Ideal EllipticCurve -> Ideal EllipticCurve -> Property+propIntersectionPEC i@(Id is) j@(Id js) = +  length is <= 5 && length js <= 5 ==> isSameIdeal intersectionPDWitness i j
src/Algebra/Structures/BezoutDomain.hs view
@@ -2,7 +2,7 @@ -- principal ideal domains. This means that all finitely generated ideals are -- principal. ---{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}+{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-} module Algebra.Structures.BezoutDomain   ( BezoutDomain(..)   , propBezoutDomain
src/Algebra/Structures/PruferDomain.hs view
@@ -9,10 +9,11 @@   , calcUVWT, propCalcUVWT, fromUVWTtoUVW   , computePLM_PD   , invertIdeal+  , intersectionPD, intersectionPDWitness, solvePD   ) where  import Test.QuickCheck-import Data.List (nub)+import Data.List (nub, (\\))  import Algebra.Structures.IntegralDomain import Algebra.Structures.Coherent@@ -120,13 +121,65 @@       a_njs = [ head (a !! j) | j <- [0..length a - 1]]   in Id a_njs --- XXX: This is buggy at the moment... Witnesses is not correctly computed! -- | Compute the intersection of I and J by: --        --       (I ∩ J)(I + J) = IJ  => (I ∩ J)(I + J)(I + J)' = IJ(I + J)' ---intersectionP :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> (Ideal a,[[a]],[[a]])-intersectionP (Id is) (Id js) = case foldr combine ([],[],[]) int of+intersectionPDWitness :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> (Ideal a,[[a]],[[a]])+intersectionPDWitness (Id is) (Id js) = (int,wis,wjs)+  where+  lj  = length js +  li  = length is++  ij  = Id (is ++ js)++  plm = computePLM_PD ij++  as  = take li $ unMVec $ transpose plm+  as' = drop li $ unMVec $ transpose plm++  int = Id $ concat [ map (j <*>) a | j <- js , a <- as ]++  wis = concat [ [ addZ i li a | a <- as ] | as <- as', i <- [0..li-1] ]+  wjs = [ addZ i lj a | i <- [0..lj-1], a <- concat as ]++  addZ n l x = replicate n zero ++ x : replicate (l-n-1) zero++{-+intersectionPD :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> (Ideal a,[[a]],[[a]])+intersectionPD (Id xs) (Id ys) +  | xs' == [] || ys' == [] = zeroIdealWitnesses xs ys +  | otherwise              = (Id k, [handleZero xs as], [handleZero ys bs])+  where+  -- Compute <x1,...,xn> and <y1,...,ym>+  xs' = filter (/= zero) xs+  ys' = filter (/= zero) ys++  -- Compute <z_1...z_k>, k = n+m+  ij  = Id xs' `addId` Id ys'++  -- Compute <a_11,...,a_k1>+  inv = fromId $ invertIdeal ij+++  k  = undefined+  as = undefined+  bs = undefined++-- Handle the zeroes specially. If the first element in xs is a zero+-- then the witness should be zero otherwise use the computed witness. +handleZero :: (Ring a, Eq a) => [a] -> [a] -> [a]+handleZero xs [] +  | all (==zero) xs = xs+  | otherwise       = error "intersectionPD: This should be impossible"+handleZero (x:xs) (a:as) +  | x == zero = zero : handleZero xs (a:as)+  | otherwise = a    : handleZero xs as+handleZero [] _  = error "intersectionPD: This should be impossible"+-}+{-+intersectionPDWitness :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> (Ideal a,[[a]],[[a]])+intersectionPDWitness (Id is) (Id js) = case foldr combine ([],[],[]) int of   ([],_,_)   -> zeroIdealWitnesses is js   (xs,ys,zs) -> (Id xs,ys,zs)   where@@ -151,20 +204,29 @@    combine (x,y,z) (xs,ys,zs) = (x:xs,y:ys,z:zs) --- intersectionPD :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> Ideal a-intersectionPD i@(Id is) j@(Id js) = i `mulId` k-  where-  plm = unMVec $ computePLM_PD (i `addId` j)--  n = length is - 1 -  m = n + length js+  as = filter (/= zero) $ concat +     $ drop (length (is \\ js)) +     $ unMVec +     $ transpose +     $ computePLM_PD +     $ Id is `addId` Id js -  k = Id [ plm !! i !! j | j <- [n+1..m], i <- [0..m]]---  k = [ "a" ++ show i  ++ show j | j <- [n+1..m], i <- [0..m]]+  -- concatMap (replicate (length ys)) as of+  +  asdf ys = [ addZ i li a | (i,_) <- zip [0..] is, a <- as ] +  -- case  of +  -- case [ concatMap (addZ i (length is)) a | (i,a) <- zip [0..] (replicate (length ys) as) ] of+--    [[]] -> [ is ]+--    x    -> x -- map (filter (/= zero)) x+-}+intersectionPD :: (PruferDomain a, Eq a) => Ideal a -> Ideal a -> Ideal a+intersectionPD i j = fst3 (intersectionPDWitness i j)+  where fst3 (x,_,_) = x +-- | Coherence of Prufer domains. solvePD :: (PruferDomain a, Eq a) => Vector a -> Matrix a-solvePD x = solveWithIntersection x intersectionP+solvePD x = solveWithIntersection x intersectionPDWitness  -- instance (PruferDomain a, Eq a) => Coherent a where --   solve x = solveWithIntersection x intersectIdeals
src/Algebra/Structures/Ring.hs view
@@ -2,7 +2,7 @@ module Algebra.Structures.Ring    ( Ring(..)   , propRing-  , (<->), (<^>), (*>)+  , (<->), (<^>), (*>), (<*)   , sumRing, productRing   ) where @@ -12,6 +12,7 @@ infixl 8 <^> infixl 7 <*> infixl 7 *>+infixl 7 <* infixl 6 <+> infixl 6 <-> @@ -110,9 +111,13 @@              else x <*> x <^> (y-1)  -- | Multiply from left with an integer; n *> x means x + x + ... + x, n times.-(*>) :: Ring a => Int -> a -> a-n *> x = sumRing $ replicate n x+(*>) :: Ring a => Integer -> a -> a+0 *> _ = zero+n *> x | n > 0     = x <+> x <* (n-1)+       | otherwise = neg (abs n *> x) -- error "<*: Negative input"  -- Multiply from right with an integer.--- (<*) :: Ring a => a -> Integer -> a--- x <* n = sumRing $ replicate n x+(<*) :: Ring a => a -> Integer -> a+_ <* 0 = zero+x <* n | n > 0     = x <+> x <* (n-1)+       | otherwise = neg (x <* abs n) -- error "<*: Negative input"
src/Algebra/Z.hs view
@@ -8,8 +8,9 @@  import Algebra.Structures.IntegralDomain import Algebra.Structures.EuclideanDomain-import Algebra.Structures.BezoutDomain import Algebra.Structures.StronglyDiscrete+import Algebra.Structures.BezoutDomain+import Algebra.Structures.PruferDomain import Algebra.Structures.Coherent import Algebra.Ideal import Algebra.Matrix@@ -68,3 +69,10 @@ -- PLM propPLMZ :: Ideal Z -> Bool propPLMZ id = propPLM id (computePLM_B id)++-- Prufer domain+propPruferDomainZ :: Z -> Z -> Z -> Property+propPruferDomainZ = propPruferDomain++propIsSameIdealPruferDomain :: Ideal Z -> Ideal Z -> Bool+propIsSameIdealPruferDomain = isSameIdeal intersectionPDWitness
+ src/Algebra/ZSqrt5.hs view
@@ -0,0 +1,104 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+-- | Proof that Z[sqrt(-5)] is a Prufer domain. This implies that it is +-- possible to solve systems of equations over Z[sqrt(-5)].+module Algebra.ZSqrt5 (ZSqrt5(..)) where++import Test.QuickCheck++import Algebra.Structures.IntegralDomain+import Algebra.Structures.EuclideanDomain (quotient, genEuclidAlg)+import Algebra.Structures.BezoutDomain (toPrincipal)+import Algebra.Structures.PruferDomain+import Algebra.Structures.Coherent+import Algebra.Ideal+import Algebra.Z+import Algebra.Q++-- | Z[sqrt(-5)] is a pair such that (a,b) = a + b*sqrt(-5)+newtype ZSqrt5 = ZSqrt5 (Z,Z)+  deriving (Eq,Ord,Arbitrary)++instance Show ZSqrt5 where+  show (ZSqrt5 (a,b)) = show a ++ " + " ++ show b ++ " * sqrt(-5)"++-- Arithmetical properties+instance Ring ZSqrt5 where+  (ZSqrt5 (a,b)) <+> (ZSqrt5 (c,d)) = ZSqrt5 (a + c, b + d)+  (ZSqrt5 (a,b)) <*> (ZSqrt5 (c,d)) = ZSqrt5 (a*c - 5*b*d, a*d + b*c)+  neg (ZSqrt5 (a,b))                = ZSqrt5 (neg a, neg b)+  zero                              = ZSqrt5 (0,0)+  one                               = ZSqrt5 (1,0)+  +instance CommutativeRing ZSqrt5 where++instance IntegralDomain ZSqrt5 where++propIntDomZSqrt5 :: ZSqrt5 -> ZSqrt5 -> ZSqrt5 -> Property+propIntDomZSqrt5 = propIntegralDomain++--------------------------------------------------------------------------------+-- Useful auxiliary functions:+++(+>) :: Z -> ZSqrt5 -> ZSqrt5+r +> (ZSqrt5 (a,b)) = ZSqrt5 (r+a,b)++(<+) :: ZSqrt5 -> Z -> ZSqrt5+(ZSqrt5 (a,b)) <+ r = ZSqrt5 (a+r,b)++infixl 6 +>, <+++--------------------------------------------------------------------------------++instance PruferDomain ZSqrt5 where+  -- Assume /= 0+  calcUVW (ZSqrt5 (a,b)) (ZSqrt5 (c,d)) = (u,v,w) +    where+    -- Let s = (a+b*sqrt(-5))/(c+d*sqrt(-5))+    -- Compute p and q such that: s = p + q*sqrt(-5)+    p = toQ (a*c+5*b*d) / n+    q = toQ (b*c-a*d)   / n+    n = toQ (c^2+5*d^2)++    s :: (Q,Q)+    s = (p,q)++    -- Rewrite: +    -- s = p + q*sqrt(-5)  <==>  s^2 - 2*sp + p^2 + 5*q^2 = 0+    --                     <==> a0*s^2 + a1*s + a2 = 0+    --+    -- Some computations give:+    a0' = toZ n+    a1' = -2 * toZ (p*n)+    a2' = a^2 + 5*b^2 +    +    -- Normalize:+    g  = genEuclidAlg [a0',a1',a2']+    a0 = a0' `quotient` g+    a1 = a1' `quotient` g+    a2 = a2' `quotient` g++    -- Compute m0, m1, m2, m3 such that:+    -- m0a0 + m1a0s + m2(a0s+a1) + m3(a0s+a1)s = 1+    a0s    = ZSqrt5 (toZ (a0 *> p), toZ (a0 *> q))+    a0sa1  = a0s <+ a1+    a0sa1s = ZSqrt5 (-a2,0)++    (Id [1],[n0,n1,n2],_) = toPrincipal (Id [a0,a1,a2]) ++    m0 = n0+    m1 = -n1+    m2 = n1+    m3 = -n2++    -- Finally we get u, v and w:+    u = m0 * a0 +> m2 *> a0sa1+    v = m0 *> a0s <+> m2 *> a0sa1s+    w = m1 * a0 +> m3 *> a0sa1++propPruferDomZSqrt5 :: ZSqrt5 -> ZSqrt5 -> ZSqrt5 -> Property+propPruferDomZSqrt5 x@(ZSqrt5 (a,b)) y@(ZSqrt5 (c,d)) z@(ZSqrt5 (e,f)) = +  a /= 0 && b /= 0 && c /= 0 && d /= 0 && e /= 0 && f /= 0 ==> propPruferDomain x y z++instance Coherent ZSqrt5 where+  solve = solvePD