packages feed

constructive-algebra 0.1 → 0.1.1

raw patch · 15 files changed

+632/−19 lines, 15 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Algebra.Ideal: fromId :: (CommutativeRing a) => Ideal a -> [a]
+ Algebra.Ideal: isSameIdeal :: (CommutativeRing a, Eq a) => (Ideal a -> Ideal a -> (Ideal a, [[a]], [[a]])) -> Ideal a -> Ideal a -> Bool
+ Algebra.Ideal: zeroIdealWitnesses :: (CommutativeRing a) => [a] -> [a] -> (Ideal a, [[a]], [[a]])
+ Algebra.Q: instance Fractional Q
+ Algebra.Q: instance Num Q
+ Algebra.Q: toQ :: Z -> Q
+ Algebra.Q: toZ :: Q -> Z
+ Algebra.Q: type Q = FieldOfFractions Z
+ Algebra.Structures.BezoutDomain: class (IntegralDomain a) => BezoutDomain a
+ Algebra.Structures.BezoutDomain: instance (BezoutDomain a, Eq a) => StronglyDiscrete a
+ Algebra.Structures.BezoutDomain: instance (EuclideanDomain a, Eq a) => BezoutDomain a
+ Algebra.Structures.BezoutDomain: intersectionB :: (BezoutDomain a, Eq a) => Ideal a -> Ideal a -> Ideal a
+ Algebra.Structures.BezoutDomain: intersectionBWitness :: (BezoutDomain a, Eq a) => Ideal a -> Ideal a -> (Ideal a, [[a]], [[a]])
+ Algebra.Structures.BezoutDomain: propBezoutDomain :: (BezoutDomain a, Eq a) => Ideal a -> a -> a -> a -> Property
+ Algebra.Structures.BezoutDomain: toPrincipal :: (BezoutDomain a) => Ideal a -> (Ideal a, [a], [a])
+ Algebra.Structures.EuclideanDomain: class (IntegralDomain a) => EuclideanDomain a
+ Algebra.Structures.EuclideanDomain: d :: (EuclideanDomain a) => a -> Integer
+ Algebra.Structures.EuclideanDomain: divides :: (EuclideanDomain a, Eq a) => a -> a -> Bool
+ Algebra.Structures.EuclideanDomain: euclidAlg :: (EuclideanDomain a, Eq a) => a -> a -> a
+ Algebra.Structures.EuclideanDomain: extendedEuclidAlg :: (EuclideanDomain a, Eq a) => a -> a -> (a, a)
+ Algebra.Structures.EuclideanDomain: genEuclidAlg :: (EuclideanDomain a, Eq a) => [a] -> a
+ Algebra.Structures.EuclideanDomain: genExtendedEuclidAlg :: (EuclideanDomain a, Eq a) => [a] -> [a]
+ Algebra.Structures.EuclideanDomain: genLcmE :: (EuclideanDomain a, Eq a) => [a] -> a
+ Algebra.Structures.EuclideanDomain: lcmE :: (EuclideanDomain a, Eq a) => a -> a -> a
+ Algebra.Structures.EuclideanDomain: modulo :: (EuclideanDomain a) => a -> a -> a
+ Algebra.Structures.EuclideanDomain: propEuclideanDomain :: (EuclideanDomain a, Eq a) => a -> a -> a -> Property
+ Algebra.Structures.EuclideanDomain: quotient :: (EuclideanDomain a) => a -> a -> a
+ Algebra.Structures.EuclideanDomain: quotientRemainder :: (EuclideanDomain a) => a -> a -> (a, a)
+ Algebra.Structures.FieldOfFractions: F :: (a, a) -> FieldOfFractions a
+ Algebra.Structures.FieldOfFractions: fromFieldOfFractions :: (GCDDomain a, Eq a) => FieldOfFractions a -> a
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Eq a) => CommutativeRing (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Eq a) => Eq (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Eq a) => Field (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Eq a) => IntegralDomain (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Eq a) => Ring (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Eq a, Arbitrary a) => Arbitrary (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: instance (GCDDomain a, Show a, Eq a) => Show (FieldOfFractions a)
+ Algebra.Structures.FieldOfFractions: newtype (GCDDomain a) => FieldOfFractions a
+ Algebra.Structures.FieldOfFractions: reduce :: (GCDDomain a, Eq a) => FieldOfFractions a -> FieldOfFractions a
+ Algebra.Structures.FieldOfFractions: toFieldOfFractions :: (GCDDomain a) => a -> FieldOfFractions a
+ Algebra.Structures.GCDDomain: class (IntegralDomain a) => GCDDomain a
+ Algebra.Structures.GCDDomain: gcd' :: (GCDDomain a) => a -> a -> (a, a, a)
+ Algebra.Structures.GCDDomain: instance (BezoutDomain a) => GCDDomain a
+ Algebra.Structures.GCDDomain: propGCDDomain :: (Eq a, GCDDomain a, Arbitrary a, Show a) => a -> a -> a -> Property
+ Algebra.Z: (<*>) :: (Ring a) => a -> a -> a
+ Algebra.Z: (<+>) :: (Ring a) => a -> a -> a
+ Algebra.Z: class Ring a
+ Algebra.Z: instance EuclideanDomain Z
+ Algebra.Z: neg :: (Ring a) => a -> a
+ Algebra.Z: one :: (Ring a) => a
+ Algebra.Z: zero :: (Ring a) => a

Files

+ README.hs view
@@ -0,0 +1,70 @@+-------------------------------------------------------------------------------+-- | Constructive Algebra Library +-- +-- Anders Mortberg    <mortberg@student.chalmers.se>+-- Bassel Mannaa      <mannaa@student.chalmers.se>+--+-- Abstract:+-- This is a library written as part of our master theses. It focuses mainly+-- on the theory of commutative rings from a constructive point of view. +--+-------------------------------------------------------------------------------++module README where+++--------------------------------------------------------------------------------+-- Structures++-- Rings with basic operations. +import Algebra.Structures.Ring++-- Commutative rings.+import Algebra.Structures.CommutativeRing++-- Integral domains.+import Algebra.Structures.IntegralDomain++-- Fields.+import Algebra.Structures.Field++-- Strongly discrete rings - Rings with decidable ideal membership.+import Algebra.Structures.StronglyDiscrete++-- EuclideanDomains - Integral domains with decidable division and and Euclidean+-- function. Contains lots of functions that are possible at the level of +-- Euclidean domain like the Euclidean algorithm and extended Euclidean +-- algorithm.+import Algebra.Structures.EuclideanDomain++-- Bezout domains - Non-Noetherian analogues of principal ideal domains. All +-- finitely generated ideals are principal.+import Algebra.Structures.BezoutDomain++-- GCD domains - Non-Noetherian analogues of unique factorization domains. +-- All pairs of nonzero elements have a greatest common divisor.+import Algebra.Structures.GCDDomain++-- Field of fractions of a GCD domain.+import Algebra.Structures.FieldOfFractions+++-------------------------------------------------------------------------------+-- Special constructions.++-- Finitely generated ideals over commutative rings. +import Algebra.Ideal+++-------------------------------------------------------------------------------+-- Instances.++-- The integers.+import Algebra.Z++-- The rational numbers as the field of fractions of Z. +import Algebra.Q+++-------------------------------------------------------------------------------+-- The end.
constructive-algebra.cabal view
@@ -7,10 +7,19 @@ -- 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+Version:             0.1.1  Synopsis:            A library of constructive algebra.-Description:         A library of constructive algebra.+Description:         +        A library of algebra focusing mainly on commutative ring theory from a +        constructive point of view. +        .+        Classical structures are implemented without Noetherian assumptions. +        This means that it is not assumed that all ideals are finitely +        generated. For example, instead of principal ideal domains one get +        Bezout domains which are integral domains in which all finitely +        generated ideals are principal (and not necessarily that all ideals are+        principal).  License:             BSD3 License-file:        LICENSE@@ -31,7 +40,7 @@  -- Extra files to be distributed with the package, such as examples or -- a README.--- Extra-source-files:  +Extra-source-files:  README.hs, examples/Z_Examples.hs  -- Constraint on the version of Cabal needed to build this package. Cabal-version:       >=1.2@@ -43,11 +52,16 @@                        Algebra.Structures.CommutativeRing,                        Algebra.Structures.IntegralDomain,                         Algebra.Structures.Field,+                       Algebra.Structures.BezoutDomain,+                       Algebra.Structures.EuclideanDomain,                        Algebra.Structures.StronglyDiscrete,+                       Algebra.Structures.FieldOfFractions,+                       Algebra.Structures.GCDDomain,                                 Algebra.Ideal,-                       Algebra.Z+                       Algebra.Z,+                       Algebra.Q+                        -     -- Packages needed in order to build this package.   Build-depends:       base >= 3 && <= 4, QuickCheck >= 2    
+ examples/Z_Examples.hs view
@@ -0,0 +1,27 @@+module Z_Examples where++import Test.QuickCheck++import Algebra.Structures.BezoutDomain+import Algebra.Structures.StronglyDiscrete+import Algebra.Ideal+import Algebra.Z+++-------------------------------------------------------------------------------+-- Bezout domain examples++ex1, ex2 :: (Ideal Z, [Z], [Z])+ex1 = toPrincipal (Id [4,6])+ex2 = toPrincipal (Id [2,3])++ex3, ex4 :: Ideal Z+ex3 = Id [2] `intersectionB` Id [3]+ex4 = Id [2,3] `intersectionB` Id [3]+++-------------------------------------------------------------------------------+-- Strong discreteness++ex5 :: Maybe [Z]+ex5 = member 2 ex3
src/Algebra/Ideal.hs view
@@ -1,7 +1,9 @@ -- | Finitely generated ideals in commutative rings. module Algebra.Ideal   ( Ideal(Id)-  , zeroIdeal, isPrincipal, eval, addId, mulId +  , zeroIdeal, isPrincipal, fromId+  , eval, addId, mulId+  , isSameIdeal, zeroIdealWitnesses   ) where  import Data.List (intersperse,nub)@@ -47,15 +49,18 @@ mulId (Id xs) (Id ys) = if zs == [] then zeroIdeal else Id zs   where zs = nub [ f <*> g | f <- xs, g <- ys, f <*> g /= zero ] -{-| Test if an operations compute the correct ideal. +{- | Test if an operations compute the correct ideal.  The operation should give a witness that the comuted ideal contains the same elements. -I `op` J = K-[ x_1, ..., x_n ] `op` [ y_1, ..., y_m ] = [ z_1, ..., z_l ]+If \[ x_1, ..., x_n \] \`op\` \[ y_1, ..., y_m \] = \[ z_1, ..., z_l \] +Then the witness should give that+ z_k = a_k1 * x_1 + ... + a_kn * x_n     = b_k1 * y_1 + ... + b_km * y_m++This is used to check that the intersection computed is correct.  -} isSameIdeal :: (CommutativeRing a, Eq a) 
+ src/Algebra/Q.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE TypeSynonymInstances #-}+-- | Representation of rational numbers as the field of fractions of Z.+module Algebra.Q +  ( Q+  , toQ, toZ+  ) where++import Test.QuickCheck+-- import qualified Math.Algebra.Field.Base as A (Q(..)) +-- import Data.Ratio ++import Algebra.Structures.Field+import Algebra.Structures.FieldOfFractions+import Algebra.Z++-------------------------------------------------------------------------------+-- | Q is the field of fractions of Z.++type Q = FieldOfFractions Z++instance Num Q where+  (+)              = (<+>)+  (*)              = (<*>)+  abs (F (a,b))    = F (abs a, b) +  signum (F (a,_)) = F (signum a,one)+  fromInteger      = toQ++instance Fractional Q where+  (/) = (</>)+  fromRational = undefined+--   fromRational (a :% b) = reduce $ F (a,b)++toQ :: Z -> Q+toQ = toFieldOfFractions++toZ :: Q -> Z+toZ = fromFieldOfFractions   
+ src/Algebra/Structures/BezoutDomain.hs view
@@ -0,0 +1,200 @@+-- | Representation of Bezout domains. That is non-Noetherian analogues of +-- principal ideal domains. This means that all finitely generated ideals are+-- principal.+--+{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}+module Algebra.Structures.BezoutDomain+  ( BezoutDomain(..)+  , propBezoutDomain+  , intersectionB, intersectionBWitness+  ) where++import Test.QuickCheck ++import Algebra.Structures.IntegralDomain+-- import Algebra.Structures.Coherent+import Algebra.Structures.EuclideanDomain+-- import Algebra.Structures.PruferDomain+import Algebra.Structures.StronglyDiscrete+-- import Algebra.PLM+-- import Algebra.Matrix+import Algebra.Ideal+++-------------------------------------------------------------------------------+-- | Bezout domains+-- +-- Compute a principal ideal from another ideal. Also give witness that the+-- principal ideal is equal to the first ideal.+--+-- toPrincipal \<a_1,...,a_n> = (\<a>,u_i,v_i)+--   where+--+--   sum (u_i * a_i) = a+--+--   a_i = v_i * a+--+class IntegralDomain a => BezoutDomain a where+  toPrincipal :: Ideal a -> (Ideal a,[a],[a])++propToPrincipal :: (BezoutDomain a, Eq a) => Ideal a -> Bool+propToPrincipal = isPrincipal . (\(a,_,_) -> a) . toPrincipal++propIsSameIdeal :: (BezoutDomain a, Eq a) => Ideal a -> Bool+propIsSameIdeal (Id as) =+  let (Id [a], us, vs) = toPrincipal (Id as) +  in a == foldr1 (<+>) (zipWith (<*>) as us) +  && and [ ai == a <*> vi | (ai,vi) <- zip as vs ]+  && length us == l_as && length vs == l_as+  where l_as = length as++propBezoutDomain :: (BezoutDomain a, Eq a) => Ideal a -> a -> a -> a -> Property+propBezoutDomain id@(Id xs) a b c = zero `notElem` xs ==> +  if propToPrincipal id+     then if propIsSameIdeal id+             then propIntegralDomain a b c +             else whenFail (print "propIsSameIdeal") False+     else whenFail (print "propToPrincipal") False+++-------------------------------------------------------------------------------+-- Euclidean domain -> Bezout domain++instance (EuclideanDomain a, Eq a) => BezoutDomain a where+  toPrincipal (Id [x]) = (Id [x], [one], [one])+  toPrincipal (Id xs)  = (Id [a], as, [ quotient ai a | ai <- xs ])+    where+    a  = genEuclidAlg xs+    as = genExtendedEuclidAlg xs+++-------------------------------------------------------------------------------+-- | Intersection of ideals with witness.+-- +-- If one of the ideals is the zero ideal then the intersection is the zero +-- ideal.+-- +intersectionBWitness :: (BezoutDomain a, Eq a) +              => Ideal a +              -> Ideal a +              -> (Ideal a, [[a]], [[a]])+intersectionBWitness (Id xs) (Id ys) +  | xs' == [] = zeroIdealWitnesses xs ys+  | ys' == [] = zeroIdealWitnesses xs ys+  | otherwise = (Id [l], [handleZero xs as], [handleZero ys bs])+  where+  xs'            = filter (/= zero) xs+  ys'            = filter (/= zero) ys++  (Id [a],us1,vs1) = toPrincipal (Id xs') +  (Id [b],us2,vs2) = toPrincipal (Id ys')++  (Id [g],[u1,u2],[v1,v2]) = toPrincipal (Id [a,b])++  l  = g <*> v1 <*> v2+  as = map (v2 <*>) us1+  bs = map (v1 <*>) us2+  +  -- 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 xs [] +    | all (==zero) xs = xs+    | otherwise       = error "intersectionB: This should be impossible"+  handleZero (x:xs) (a:as) +    | x == zero = zero : handleZero xs (a:as)+    | otherwise = a    : handleZero xs as+  handleZero [] _  = error "intersectionB: This should be impossible"+++-- | Intersection without witness.+intersectionB :: (BezoutDomain a, Eq a) => Ideal a -> Ideal a -> Ideal a+intersectionB a b = (\(x,_,_) -> x) $ intersectionBWitness a b+++-------------------------------------------------------------------------------+-- Coherence+-- +-- solveB :: (BezoutDomain a, Eq a) => Vector a -> Matrix a+-- solveB x = solveWithIntersection x intersectionB++-- instance (BezoutDomain r, Eq r) => Coherent r where+--   solve x = solveWithIntersection x intersectionB+++-------------------------------------------------------------------------------+-- Principal localization matrix+--+-- computePLM_B :: (BezoutDomain a, Eq a) => Ideal a -> Matrix a+-- computePLM_B (Id xs) = +--  let (Id [g],us,ys) = toPrincipal (Id xs)+--      n              = length xs - 1+--  in M [ Vec [ us !! i <*> ys !! j | j <- [0..n] ] | i <- [0..n] ]+++-------------------------------------------------------------------------------+-- | Strongly discreteness for Bezout domains+-- +-- Given x, compute as such that x = sum (a_i * x_i)+--+instance (BezoutDomain a, Eq a) => StronglyDiscrete a where+  member x (Id xs) | x == zero = Just (replicate (length xs) zero)+                   | otherwise = if a == g +                                    then Just witness +                                    else Nothing+    where+    -- (<g>, as, bs)   = <x1,...,xn>+    -- sum (a_i * x_i) = g+    -- x_i             = b_i * g+    (Id [g], as, bs) = toPrincipal (Id xs)+    (Id [a], _,[q1,q2]) = toPrincipal (Id [x,g])+    +    -- x = qg = q (sum (ai * xi)) = sum (q * ai * xi)+    witness = map (q1 <*>) as++--------------------------------------------------------------------------------+-- | Bezout domain -> Prüfer domain+--+{-+Prufer: forall a b exists u v w t.  u+t = 1 &  ua = vb & wa = tb++We consider only domain.+We assume we have the Bezout condition: given a, b we can find g,a1,b1,c,d s.t.++a = g a1+b = g b1+1 = c a1 + d b1++We try then ++u = d b1+t = c a1++We should find v such that+a d b1 = b v+this simplifies to +g a1 d b1 = g b1 v+and we can take +v = a1 d+Similarly we can take +w = b1 c++We have shown that Bezout domain -> Prufer domain.+instance (BezoutDomain a, Eq a) => PruferDomain a where+  calcUVW a b | a == zero = (one,zero,zero)+              | b == zero = (zero,zero,zero)+              | otherwise = fromUVWTtoUVW (u,v,w,t)+    where+    -- Compute g, a1 and b1 such that:+    -- a = g*a1+    -- b = g*b1+    (g,[_,_],[a1,b1])  = toPrincipal (Id [a,b])+    +    -- Compute c and d such that:+    -- 1 = a1*c + a2*d+    (_,[c,d],_) = toPrincipal (Id [a1,b1])++    u = d <*> b1+    t = c <*> a1+    v = d <*> a1+    w = c <*> b1+-}
src/Algebra/Structures/CommutativeRing.hs view
@@ -10,7 +10,7 @@   ---------------------------------------------------------------------------------- | Definition of commutative rings+-- | Definition of commutative rings.  class Ring a => CommutativeRing a 
+ src/Algebra/Structures/EuclideanDomain.hs view
@@ -0,0 +1,105 @@+-- | Representation of Euclidean domains. That is integral domains with an +-- Euclidean functions and decidable division.+--+module Algebra.Structures.EuclideanDomain +  ( EuclideanDomain(..)+  , propEuclideanDomain+  , modulo, quotient, divides +  , euclidAlg, genEuclidAlg+  , lcmE, genLcmE+  , extendedEuclidAlg, genExtendedEuclidAlg+  ) where++import Test.QuickCheck++import Algebra.Structures.IntegralDomain+-- import Algebra.Structures.Coherent+import Algebra.Ideal+++-------------------------------------------------------------------------------+-- | Euclidean domains+--+-- Given a and b compute (q,r) such that a = bq + r and r = 0 || d r < d b. +-- Where d is the Euclidean function.++class IntegralDomain a => EuclideanDomain a where+  d :: a -> Integer+  quotientRemainder :: a -> a -> (a,a)++-- Check both that |a| <= |ab| and |a| >= 0 for all a,b+propD :: (EuclideanDomain a, Eq a) => a -> a -> Bool+propD a b = +  a == zero || b == zero || (d a <= d (a <*> b) && d a >= 0 && d b >= 0)++propQuotRem :: (EuclideanDomain a, Eq a) => a -> a -> Bool+propQuotRem a b = b == zero || (a == b <*> q <+> r && (r == zero || d r < d b))+  where (q,r) = quotientRemainder a b ++propEuclideanDomain :: (EuclideanDomain a, Eq a) => a -> a -> a -> Property+propEuclideanDomain a b c =+  if propD a b +     then if propQuotRem a b+             then propIntegralDomain a b c+             else whenFail (print "propQuotRem") False+     else whenFail (print "propD") False+++-------------------------------------------------------------------------------+-- Operations++modulo :: EuclideanDomain a => a -> a -> a+modulo a b = snd (quotientRemainder a b)++quotient :: EuclideanDomain a => a -> a -> a+quotient a b = fst (quotientRemainder a b)++divides :: (EuclideanDomain a, Eq a) => a -> a -> Bool+divides a b = modulo b a == zero++-- | The Euclidean algorithm for calculating the GCD of a and b.+euclidAlg :: (EuclideanDomain a, Eq a) => a -> a -> a+euclidAlg a b | a == zero && b == zero = error "GCD of 0 and 0 is undefined"+              | b == zero = a+              | otherwise = euclidAlg b (a `modulo` b)++-- | Generalized Euclidean algorithm to compute GCD of a list of elements.+genEuclidAlg :: (EuclideanDomain a, Eq a) => [a] -> a+genEuclidAlg = foldl euclidAlg zero++-- | Lowest common multiple, (a*b)/gcd(a,b).+lcmE :: (EuclideanDomain a, Eq a) => a -> a -> a+lcmE a b = quotient (a <*> b) (euclidAlg a b)++-- | Generalized lowest common multiple to compute lcm of a list of elements.+genLcmE :: (EuclideanDomain a, Eq a) => [a] -> a+genLcmE xs = quotient (foldr1 (<*>) xs) (genEuclidAlg xs)++-- | The extended Euclidean algorithm. +-- +-- Computes x and y in ax + by = gcd(a,b).+-- +extendedEuclidAlg :: (EuclideanDomain a, Eq a) => a -> a -> (a,a)+extendedEuclidAlg a b | modulo a b == zero = (zero,one)+                      | otherwise          = (y, x <-> y <*> (a `quotient` b))+  where (x,y) = extendedEuclidAlg b (a `modulo` b)++-- Specification of extended Euclidean algorithm.+propExtendedEuclidAlg :: (EuclideanDomain a, Eq a) => a -> a -> Property+propExtendedEuclidAlg a b = a /= zero && b /= zero ==> +  let (x,y) = extendedEuclidAlg a b in a <*> x <+> b <*> y == euclidAlg a b++-- | Generalized extended Euclidean algorithm.+--+-- Solves a_1 x_1 + ... + a_n x_n = gcd (a_1,...,a_n)+--+genExtendedEuclidAlg :: (EuclideanDomain a, Eq a) => [a] -> [a]+genExtendedEuclidAlg [x,y] = let (a,b) = extendedEuclidAlg x y in [a,b]+genExtendedEuclidAlg xs    =+  let (x,y) = extendedEuclidAlg (genEuclidAlg (init xs)) (last xs)+  in map (x<*>) (genExtendedEuclidAlg (init xs)) ++ [y]++-- Specification of generalized extended Euclidean algorithm. +propGenExtEuclidAlg :: (EuclideanDomain a, Eq a) => [a] -> Property+propGenExtEuclidAlg xs = all (/= zero) xs && length xs >= 2 ==> +  foldr (<+>) zero (zipWith (<*>) (genExtendedEuclidAlg xs) xs) == genEuclidAlg xs
src/Algebra/Structures/Field.hs view
@@ -14,7 +14,7 @@ infixl 7 </>  ---------------------------------------------------------------------------------- | Definition of fields+-- | Definition of fields.  class IntegralDomain a => Field a where   inv :: a -> a
+ src/Algebra/Structures/FieldOfFractions.hs view
@@ -0,0 +1,88 @@+-- | The field of fractions over a GCD domain. The reason that it is an GCD +-- domain is that we only want to work over reduced quotients.+module Algebra.Structures.FieldOfFractions+  ( FieldOfFractions(..)+  , toFieldOfFractions, fromFieldOfFractions+  , reduce+  ) where++import Test.QuickCheck++import Algebra.Structures.Field+import Algebra.Structures.GCDDomain+++-------------------------------------------------------------------------------+-- | Field of fractions++newtype GCDDomain a => FieldOfFractions a = F (a,a)+++--------------------------------------------------------------------------------+-- Instances++instance (GCDDomain a, Show a, Eq a) => Show (FieldOfFractions a) where+  show (F (a,b)) | b == one  = show a+                 | otherwise = case show b of+                    ('-':xs) -> "-" ++ show a ++ "/" ++ xs+                    xs -> show a ++ "/" ++ xs++instance (GCDDomain a, Eq a, Arbitrary a) => Arbitrary (FieldOfFractions a) where+  arbitrary = do+    a <- arbitrary+    b <- arbitrary+    if b == zero +       then return $ F (a,one)+       else return $ F (a,b)++instance (GCDDomain a, Eq a) => Eq (FieldOfFractions a) where+  f == g = a <*> d == b <*> c+    where+    F (a,b) = reduce f+    F (c,d) = reduce g++instance (GCDDomain a, Eq a) => Ring (FieldOfFractions a) where+  (F (a,b)) <+> (F (c,d)) = reduce (F (a <*> d <+> c <*> b,b <*> d))+  (F (a,b)) <*> (F (c,d)) = reduce (F (a <*> c,b <*> d))+  neg (F (a,b))           = reduce (F (neg a,b))+  one                     = toFieldOfFractions one+  zero                    = toFieldOfFractions zero++instance (GCDDomain a, Eq a) => CommutativeRing (FieldOfFractions a)+instance (GCDDomain a, Eq a) => IntegralDomain (FieldOfFractions a)++instance (GCDDomain a, Eq a) => Field (FieldOfFractions a) where+  inv (F (a,b)) | b /= zero && a /= zero = reduce $ F (b,a)+                | otherwise = error "FieldOfFraction: Division by zero"+++--------------------------------------------------------------------------------+-- Operations++-- | Embed a value in the field of fractions.+toFieldOfFractions :: GCDDomain a => a -> FieldOfFractions a+toFieldOfFractions a = F (a,one)++-- | Extract a value from the field of fractions. This is only possible if the+-- divisor is one.+fromFieldOfFractions :: (GCDDomain a, Eq a) => FieldOfFractions a -> a+fromFieldOfFractions (F (a,b)) +  | b == one  = a+  | otherwise = error "FieldOfFractions: Can't extract value"++-- | Reduce an element.+reduce :: (GCDDomain a, Eq a) => FieldOfFractions a -> FieldOfFractions a+reduce (F (a,b)) | b == zero = error "FieldOfFractions: Division by zero"+                 | a == zero = F (zero,one)+                 | otherwise = if g == one+                                  then F (a,b)+                                  else F (x,y)+  where+  (g,x,y) = gcd' a b++-- Specification of reduce.+propReduce :: (GCDDomain a, Eq a) => FieldOfFractions a -> Property+propReduce f@(F (a,b)) = a /= zero && b /= zero ==> g == one+  where+  F (c,d) = reduce f+  (g,_,_) = gcd' c d
+ src/Algebra/Structures/GCDDomain.hs view
@@ -0,0 +1,50 @@+-- | Greatest common divisor (GCD) domains. +--+-- GCD domains are integral domains in which every pair of nonzero elements +-- have a greatest common divisor. They can also be characterized as +-- non-Noetherian analogues of unique factorization domains.+--+{-# LANGUAGE FlexibleInstances, UndecidableInstances #-}+module Algebra.Structures.GCDDomain +  ( GCDDomain(gcd')+  , propGCDDomain+  ) where++import Test.QuickCheck++import Algebra.Structures.IntegralDomain+import Algebra.Structures.BezoutDomain+import Algebra.Ideal+++-------------------------------------------------------------------------------+-- | GCD domains++class IntegralDomain a => GCDDomain a where+  -- | Compute gcd(a,b) = (g,x,y) such that g = gcd(a,b) and+  --   a = gx+  --   b = gy+  -- and a, b /= 0+  gcd' :: a -> a -> (a,a,a)+++propGCD :: (GCDDomain a, Eq a) => a -> a -> Bool+propGCD a b = a == zero || b == zero || a == g <*> x && b == g <*> y+  where+  (g,x,y) = gcd' a b+++-- | Specification of GCD domains. They are integral domains in which every +-- pair of nonzero elements have a greatest common divisor.+propGCDDomain :: (Eq a, GCDDomain a, Arbitrary a, Show a) => a -> a -> a -> Property+propGCDDomain a b c = if propGCD a b +                         then propIntegralDomain a b c+                         else whenFail (print "propGCD") False++-- This can be used to compute gcd of a list of non-zero elements+-- genGCD :: ?+-- genGCD = ?++instance BezoutDomain a => GCDDomain a where+  gcd' a b = (g,x,y)+    where (Id [g],_,[x,y]) = toPrincipal (Id [a,b])
src/Algebra/Structures/IntegralDomain.hs view
@@ -11,7 +11,7 @@   ---------------------------------------------------------------------------------- | Definition of integral domains+-- | Definition of integral domains.  class CommutativeRing a => IntegralDomain a @@ -20,8 +20,8 @@ propZeroDivisors a b = if a <*> b == zero then a == zero || b == zero else True  --- | Specification of commutative rings. Test that there are no zero-divisors--- commutative and that it satisfies the axioms of commutative rings.+-- | Specification of integral domains. Test that there are no zero-divisors+-- and that it satisfies the axioms of commutative rings. propIntegralDomain :: (IntegralDomain a, Eq a) => a -> a -> a -> Property propIntegralDomain a b c = if propZeroDivisors a b                               then propCommutativeRing a b c 
src/Algebra/Structures/Ring.hs view
@@ -16,7 +16,7 @@   ---------------------------------------------------------------------------------- | Definition of rings+-- | Definition of rings.  class Ring a where   -- | Addition@@ -72,8 +72,7 @@ propMulIdentity :: (Ring a, Eq a) => a -> (Bool,String) propMulIdentity a = (one <*> a == a && a <*> one == a, "propMulIdentity") --- | Specification of rings.--- Test that the arguments satisfy the ring axioms.+-- | Specification of rings. Test that the arguments satisfy the ring axioms. propRing :: (Ring a, Eq a) => a -> a -> a -> Property propRing a b c = whenFail (print errorMsg) cond   where
src/Algebra/Structures/StronglyDiscrete.hs view
@@ -12,7 +12,7 @@ -- -- A ring is called strongly discrete if ideal membership is decidable. -- Nothing correspond to that x is not in the ideal and Just is the witness.--- Examples include all euclidean domains and the polynomial ring.+-- Examples include all Bezout domains and polynomial rings. -- class Ring a => StronglyDiscrete a where   member :: a -> Ideal a -> Maybe [a]
src/Algebra/Z.hs view
@@ -1,12 +1,16 @@ {-# LANGUAGE TypeSynonymInstances #-} module Algebra.Z    ( Z-  , module Algebra.Structures.IntegralDomain+  , Ring(..)   ) where  import Test.QuickCheck  import Algebra.Structures.IntegralDomain+import Algebra.Structures.EuclideanDomain+import Algebra.Structures.BezoutDomain+import Algebra.Structures.StronglyDiscrete+import Algebra.Ideal   -- | Type synonym for integers.@@ -25,3 +29,17 @@  propIntegralDomainZ :: Z -> Z -> Z -> Property propIntegralDomainZ = propIntegralDomain++instance EuclideanDomain Z where+  d = abs+  quotientRemainder = quotRem+++propEuclideanDomainZ :: Z -> Z -> Z -> Property+propEuclideanDomainZ = propEuclideanDomain++propBezoutDomainZ :: Ideal Z -> Z -> Z -> Z -> Property+propBezoutDomainZ = propBezoutDomain++propStronglyDiscreteZ :: Z -> Ideal Z -> Bool+propStronglyDiscreteZ = propStronglyDiscrete