numhask-prelude 0.0.5.1 → 0.1.0.0
raw patch · 4 files changed
+6/−986 lines, 4 filesdep −QuickCheckdep −tastydep −tasty-quickcheckdep ~base
Dependencies removed: QuickCheck, tasty, tasty-quickcheck
Dependency ranges changed: base
Files
- numhask-prelude.cabal +3/−12
- src/NumHask/Laws.hs +0/−649
- src/NumHask/Prelude.hs +2/−0
- test/test.hs +1/−325
numhask-prelude.cabal view
@@ -1,5 +1,5 @@ name: numhask-prelude-version: 0.0.5.1+version: 0.1.0.0 synopsis: A numeric prelude description: A numeric prelude, combining protolude and numhask. category: mathematics@@ -31,17 +31,13 @@ -Wincomplete-uni-patterns -Wredundant-constraints build-depends:- QuickCheck >=2.8 && <3- , base >=4.7 && <4.12+ base >=4.7 && <4.12 , numhask >=0.2.2.0 && <0.3 , protolude >=0.1 && <0.3- , tasty >= 1.0.1.1 && <1.2- , tasty-quickcheck >= 0.9.2 && <1.0 exposed-modules: NumHask.Prelude NumHask.Error NumHask.Examples- NumHask.Laws other-modules: Paths_numhask_prelude default-language: Haskell2010@@ -53,11 +49,6 @@ test default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax build-depends:- base >=4.7 && <5- , QuickCheck >=2.8 && <3- , doctest+ doctest , numhask-prelude- , tasty- other-modules:- Paths_numhask_prelude default-language: Haskell2010
− src/NumHask/Laws.hs
@@ -1,649 +0,0 @@-{-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE RebindableSyntax #-}-{-# OPTIONS_GHC -fno-warn-type-defaults #-}--module NumHask.Laws- ( LawArity(..)- , LawArity2(..)- , Law- , Law2- , testLawOf- , testLawOf2- , idempotentLaws- , additiveLaws- , additiveLaws_- , additiveLawsFail- , additiveGroupLaws- , multiplicativeLaws- , multiplicativeLawsFail- , multiplicativeMonoidalLaws- , multiplicativeGroupLaws- , multiplicativeGroupLaws_- , distributionLaws- , distributionLawsFail- , integralLaws- , rationalLaws- , signedLaws- , normedLaws- , normedBoundedLaws- , metricIntegralLaws- , metricIntegralBoundedLaws- , metricRationalLaws- , upperBoundedFieldLaws- , lowerBoundedFieldLaws- , quotientFieldLaws - , expFieldLaws- , additiveBasisLaws- , additiveGroupBasisLaws- , multiplicativeBasisLaws- , multiplicativeGroupBasisLaws- , additiveModuleLaws- , additiveGroupModuleLaws- , multiplicativeModuleLaws- , multiplicativeGroupModuleLawsFail- , expFieldContainerLaws- , tensorProductLaws- , banachLaws- , hilbertLaws- , semiringLaws- , ringLaws- , starSemiringLaws- , involutiveRingLaws- , integralsLaws- ) where--import NumHask.Prelude-import Test.Tasty.QuickCheck hiding ((><))-import Test.Tasty (TestName, TestTree)--smallRational :: (FromRatio a) => a-smallRational = 10.0--smallRationalPower :: (FromRatio a) => a-smallRationalPower = 6.0--smallIntegralPower :: (FromInteger a) => a-smallIntegralPower = 6---- | unification of law equations-data LawArity a- = Nonary Bool- | Unary (a -> Bool)- | Binary (a -> a -> Bool)- | Ternary (a -> a -> a -> Bool)- | Ornary (a -> a -> a -> a -> Bool)- | Failiary (a -> Property)--type Law a = (TestName, LawArity a)---- | unification of law equations with 2 types-data LawArity2 a b- = Unary10 (a -> Bool)- | Unary01 (b -> Bool)- | Binary11 (a -> b -> Bool)- | Binary20 (a -> a -> Bool)- | Ternary21 (a -> a -> b -> Bool)- | Ternary12 (a -> b -> b -> Bool)- | Ternary30 (a -> a -> a -> Bool)- | Quad31 (a -> a -> a -> b -> Bool)- | Quad22 (a -> a -> b -> b -> Bool)- | Failiary2 (a -> Property)--type Law2 a b = (TestName, LawArity2 a b)--testLawOf :: (Arbitrary a, Show a) => [a] -> Law a -> TestTree-testLawOf _ (name, Nonary f) = testProperty name f-testLawOf _ (name, Unary f) = testProperty name f-testLawOf _ (name, Binary f) = testProperty name f-testLawOf _ (name, Ternary f) = testProperty name f-testLawOf _ (name, Ornary f) = testProperty name f-testLawOf _ (name, Failiary f) = testProperty name f--testLawOf2 ::- (Arbitrary a, Show a, Arbitrary b, Show b)- => [(a, b)]- -> Law2 a b- -> TestTree-testLawOf2 _ (name, Unary10 f) = testProperty name f-testLawOf2 _ (name, Unary01 f) = testProperty name f-testLawOf2 _ (name, Binary11 f) = testProperty name f-testLawOf2 _ (name, Binary20 f) = testProperty name f-testLawOf2 _ (name, Ternary21 f) = testProperty name f-testLawOf2 _ (name, Ternary12 f) = testProperty name f-testLawOf2 _ (name, Ternary30 f) = testProperty name f-testLawOf2 _ (name, Quad22 f) = testProperty name f-testLawOf2 _ (name, Quad31 f) = testProperty name f-testLawOf2 _ (name, Failiary2 f) = testProperty name f---- idempotent-idempotentLaws :: (Eq a, Additive a, Multiplicative a) => [Law a]-idempotentLaws =- [ ("idempotent: a + a == a", Unary (\a -> a + a == a))- , ("idempotent: a * a == a", Unary (\a -> a * a == a))- ]---- | additive-additiveLaws :: (Eq a, Additive a) => [Law a]-additiveLaws =- [ ( "associative: (a + b) + c = a + (b + c)"- , Ternary (\a b c -> (a + b) + c == a + (b + c)))- , ("left id: zero + a = a", Unary (\a -> zero + a == a))- , ("right id: a + zero = a", Unary (\a -> a + zero == a))- , ("commutative: a + b == b + a", Binary (\a b -> a + b == b + a))- ]---- | additive with approximate association equality-additiveLaws_ :: (Epsilon a) => [Law a]-additiveLaws_ =- [ ( "associative: (a + b) + c ≈ a + (b + c)"- , Ternary (\a b c -> (a + b) + c ≈ a + (b + c)))- , ("left id: zero + a = a", Unary (\a -> zero + a == a))- , ("right id: a + zero = a", Unary (\a -> a + zero == a))- , ("commutative: a + b == b + a", Binary (\a b -> a + b == b + a))- ]---- | additive laws with a failure on association-additiveLawsFail :: (Eq a, Additive a, Show a, Arbitrary a) => [Law a]-additiveLawsFail =- [ ( "associative: (a + b) + c = a + (b + c)"- , Failiary $ expectFailure . (\a b c -> (a + b) + c == a + (b + c)))- , ("left id: zero + a = a", Unary (\a -> zero + a == a))- , ("right id: a + zero = a", Unary (\a -> a + zero == a))- , ("commutative: a + b == b + a", Binary (\a b -> a + b == b + a))- ]--additiveGroupLaws :: (Eq a, AdditiveGroup a) => [Law a]-additiveGroupLaws =- [ ("minus: a - a = zero", Unary (\a -> (a - a) == zero))- , ("negate minus: negate a == zero - a", Unary (\a -> negate a == zero - a))- , ( "negate left cancel: negate a + a == zero"- , Unary (\a -> negate a + a == zero))- , ( "negate right cancel: negate a + a == zero"- , Unary (\a -> a + negate a == zero))- ]---- multiplicative-multiplicativeLaws :: (Eq a, Multiplicative a) => [Law a]-multiplicativeLaws =- [ ( "associative: (a * b) * c = a * (b * c)"- , Ternary (\a b c -> (a * b) * c == a * (b * c)))- , ("left id: one * a = a", Unary (\a -> one * a == a))- , ("right id: a * one = a", Unary (\a -> a * one == a))- , ("commutative: a * b == b * a", Binary (\a b -> a * b == b * a))- ]--multiplicativeMonoidalLaws ::- (Eq a, MultiplicativeUnital a) => [Law a]-multiplicativeMonoidalLaws =- [ ( "associative: (a * b) * c = a * (b * c)"- , Ternary (\a b c -> (a `times` b) `times` c == a `times` (b `times` c)))- , ("left id: one `times` a = a", Unary (\a -> one `times` a == a))- , ("right id: a `times` one = a", Unary (\a -> a `times` one == a))- ]--multiplicativeLawsFail ::- (Eq a, Show a, Arbitrary a, Multiplicative a) => [Law a]-multiplicativeLawsFail =- [ ( "associative: (a * b) * c = a * (b * c)"- , Failiary $ expectFailure . (\a b c -> (a * b) * c == a * (b * c)))- , ("left id: one * a = a", Unary (\a -> one * a == a))- , ("right id: a * one = a", Unary (\a -> a * one == a))- , ("commutative: a * b == b * a", Binary (\a b -> a * b == b * a))- ]--multiplicativeGroupLaws :: (Eq a, AdditiveUnital a, MultiplicativeGroup a) => [Law a]-multiplicativeGroupLaws =- [ ( "divide: a == zero || a / a == one"- , Unary (\a -> a == zero || (a / a) == one))- , ( "recip divide: recip a == one / a"- , Unary (\a -> a == zero || recip a == one / a))- , ( "recip left: a == zero || recip a * a == one"- , Unary (\a -> a == zero || recip a * a == one))- , ( "recip right: a == zero || a * recip a == one"- , Unary (\a -> a == zero || a * recip a == one))- ]- -multiplicativeGroupLaws_ :: (Epsilon a, MultiplicativeGroup a) => [Law a]-multiplicativeGroupLaws_ =- [ ( "divide: a == zero || a / a ≈ one"- , Unary (\a -> a == zero || (a / a) ≈ one))- , ( "recip divide: recip a == one / a"- , Unary (\a -> a == zero || recip a == one / a))- , ( "recip left: a == zero || recip a * a ≈ one"- , Unary (\a -> a == zero || recip a * a ≈ one))- , ( "recip right: a == zero || a * recip a ≈ one"- , Unary (\a -> a == zero || a * recip a ≈ one))- ]---- distribution-distributionLaws :: (Eq a, Distribution a) => [Law a]-distributionLaws =- [ ( "left annihilation: a * zero == zero"- , Unary (\a -> a `times` zero == zero))- , ( "right annihilation: zero * a == zero"- , Unary (\a -> zero `times` a == zero))- , ( "left distributivity: a * (b + c) == a * b + a * c"- , Ternary (\a b c -> a `times` (b + c) == a `times` b + a `times` c))- , ( "right distributivity: (a + b) * c == a * c + b * c"- , Ternary (\a b c -> (a + b) `times` c == a `times` c + b `times` c))- ]--distributionLawsFail ::- (Show a, Arbitrary a, Epsilon a, Distribution a) => [Law a]-distributionLawsFail =- [ ( "left annihilation: a * zero == zero"- , Unary (\a -> a `times` zero == zero))- , ( "right annihilation: a * zero == zero"- , Unary (\a -> zero `times` a == zero))- , ( "left distributivity: a * (b + c) = a * b + a * c"- , Failiary $- expectFailure . (\a b c -> a `times` (b + c) == a `times` b + a `times` c))- , ( "right distributivity: (a + b) * c = a * c + b * c"- , Failiary $- expectFailure . (\a b c -> (a + b) `times` c == a `times` c + b `times` c))- ]---- integral-integralLaws :: (Eq a, Integral a, FromInteger a, ToInteger a) => [Law a]-integralLaws =- [ ( "integral divmod: b == zero || b * (a `div` b) + (a `mod` b) == a"- , Binary (\a b -> b == zero || b `times` (a `div` b) + (a `mod` b) == a))- , ("fromIntegral a = a", Unary (\a -> fromIntegral a == a))- ]---- rational-rationalLaws :: (Eq a, FromRatio a, ToRatio a) => [Law a]-rationalLaws =- [ ("fromRational a = a", Unary (\a -> fromRational a == a))- ]---- metric-signedLaws :: (Eq a, Signed a) => [Law a]-signedLaws = [("sign a * abs a == a", Unary (\a -> sign a `times` abs a == a))]--normedLaws :: forall a b. (Ord b, AdditiveUnital a, AdditiveUnital b, MultiplicativeUnital b, Normed a b) =>- [Law2 a b]-normedLaws =- [ ("positive", Binary11 (\a p -> p < (one :: b) || (normLp p a :: b) >= (zero :: b)))- , ("preserves zero"- , Binary11 (\_ p -> p < (one :: b) || (normLp p (zero :: a) :: b) == (zero :: b)) )- ]--normedBoundedLaws :: forall a b. (Eq a, Bounded a, Ord b, AdditiveUnital a, AdditiveUnital b, MultiplicativeUnital b, Normed a b) =>- [Law2 a b]-normedBoundedLaws =- [ ("positive or non-minBound", Binary11 (\a p -> a == minBound || p < (one :: b) || (normLp p a :: b) >= (zero :: b)))- , ("preserves zero"- , Binary11 (\_ p -> p < (one :: b) || (normLp p (zero :: a) :: b) == (zero :: b)) )- ]--metricIntegralLaws :: forall a b. (FromInteger b, Ord b, Signed b, Epsilon b, Metric a b) =>- [Law2 a b]-metricIntegralLaws =- [ ("Lp: positive",- Ternary21 (\a b p -> p < one || distanceLp p a b >= zero))- , ("Lp: zero if equal"- , Binary11 (\a p -> p < one || distanceLp p a a == zero))- , ( "Lp: associative"- , Ternary21 (\a b p ->- p < one ||- p > (smallIntegralPower :: b) ||- distanceLp p a b ≈ distanceLp p b a))- , ( "Lp: triangle rule - sum of distances > distance"- , Quad31- (\a b c p ->- (p < one) ||- not- (veryNegative- (distanceLp p a c + distanceLp p b c - distanceLp p a b)) &&- not- (veryNegative- (distanceLp p a b + distanceLp p b c - distanceLp p a c)) &&- not- (veryNegative- (distanceLp p a b + distanceLp p a c - distanceLp p b c))))- ]---- triangle rule doesn't apply to bounded Integrals-metricIntegralBoundedLaws :: forall a b. (FromInteger b, Bounded b, Ord b, Signed b, Epsilon b, Metric a b) =>- [Law2 a b]-metricIntegralBoundedLaws =- [ ("Lp: positive",- Ternary21 (\a b p -> p < one || distanceLp p a b >= zero || distanceLp p a b == minBound))- , ("Lp: zero if equal"- , Binary11 (\a p -> p < one || distanceLp p a a == zero))- , ( "Lp: associative"- , Ternary21 (\a b p ->- p < one ||- p > (smallIntegralPower :: b) ||- distanceLp p a b ≈ distanceLp p b a))- ]---metricRationalLaws :: forall a b. (FromRatio b, Ord b, Signed b, Epsilon b, Metric a b, Normed a b) =>- [Law2 a b]-metricRationalLaws =- [ ("Lp: positive",- Ternary21 (\a b p -> p < one || distanceLp p a b >= zero))- , ("Lp: zero if equal"- , Binary11 (\a p -> p < one || distanceLp p a a == zero))- , ( "Lp: associative"- , Ternary21 (\a b p ->- p < one ||- p > (smallRationalPower :: b) ||- distanceLp p a b ≈ distanceLp p b a))- , ( "Lp: triangle rule - sum of distances > distance"- , Quad31- (\a b c p ->- (p < one) ||- (normL1 a > (smallRational :: b)) ||- (normL1 b > (smallRational :: b)) ||- (normL1 c > (smallRational :: b)) ||- not- (veryNegative- (distanceLp p a c + distanceLp p b c - distanceLp p a b)) &&- not- (veryNegative- (distanceLp p a b + distanceLp p b c - distanceLp p a c)) &&- not- (veryNegative- (distanceLp p a b + distanceLp p a c - distanceLp p b c))))- ]---- bounded fields-upperBoundedFieldLaws :: forall a. (Eq a, UpperBoundedField a) => [Law a]-upperBoundedFieldLaws =- [ ( "upper bounded field (infinity) laws"- , Unary- (\a ->- ((one ::a) / zero + infinity == infinity) &&- (infinity + a == infinity) &&- (zero :: a) / zero /= nan))- ]--lowerBoundedFieldLaws :: forall a. (Eq a, LowerBoundedField a) => [Law a]-lowerBoundedFieldLaws =- [ ( "lower bounded field (negative infinity) laws"- , Unary- (\a ->- (negate (one ::a) / zero == negInfinity) &&- ((negInfinity :: a) + negInfinity == negInfinity) &&- (negInfinity + a == negInfinity)))- ]--quotientFieldLaws :: (Field a, QuotientField a Integer, FromInteger a) => [Law2 a Integer]-quotientFieldLaws =- [ ( "a - one < floor a <= a <= ceiling a < a + one"- , Unary10- (\a ->- ((a - one) < (fromInteger (floor a))) &&- (fromInteger (floor a) <= a) &&- (a <= fromInteger (ceiling a)) &&- (fromInteger (ceiling a) < a + one)))- , ( "round a == floor (a + one/(one+one))"- , Unary10 (\a -> (round a :: Integer) == ((floor (a + one / (one + one))))))- ]--expFieldLaws :: forall a b.- (FromInteger b, AdditiveUnital b, ExpField a, Normed a b, Epsilon a, Ord a, Ord b) => [Law2 a b]-expFieldLaws =- [ ( "sqrt . (**(one+one)) ≈ id"- , Unary10- (\a ->- not (a > (zero :: a)) ||- (normL1 a > (10 :: b)) ||- (sqrt . (** (one + one)) $ a) ≈ a &&- ((** (one + one)) . sqrt $ a) ≈ a))- , ( "log . exp ≈ id"- , Unary10- (\a ->- not (a > (zero :: a)) ||- (normL1 a > (10 :: b)) || (log . exp $ a) ≈ a && (exp . log $ a) ≈ a))- , ( "for +ive b, a != 0,1: a ** logBase a b ≈ b"- , Binary20- (\a b ->- (not (normL1 b > (zero :: b)) ||- not (nearZero (a - zero)) ||- (a == one) ||- (a == zero && nearZero (logBase a b)) || (a ** logBase a b ≈ b))))- ]--expFieldContainerLaws ::- ( ExpField (r a)- , Foldable r- , ExpField a- , Epsilon a- , Signed a- , FromRatio a- , Epsilon (r a)- , Ord a- )- => [Law (r a)]-expFieldContainerLaws =- [ ( "sqrt . (**2) ≈ id"- , Unary- (\a ->- not (all veryPositive a) ||- any (> smallRational) a ||- (sqrt . (** (one + one)) $ a) ≈ a &&- ((** (one + one)) . sqrt $ a) ≈ a))- , ( "log . exp ≈ id"- , Unary- (\a ->- not (all veryPositive a) ||- any (> smallRational) a || (log . exp $ a) ≈ a && (exp . log $ a) ≈ a))- , ( "for +ive b, a != 0,1: a ** logBase a b ≈ b"- , Binary- (\a b ->- (not (all veryPositive b) ||- not (all nearZero a) ||- all (== one) a ||- (all (== zero) a && all nearZero (logBase a b)) ||- (a ** logBase a b ≈ b))))- ]---- module-additiveModuleLaws ::- (Epsilon a, Epsilon (r a), AdditiveModule r a) => [Law2 (r a) a]-additiveModuleLaws =- [ ( "additive module associative: (a + b) .+ c ≈ a + (b .+ c)"- , Ternary21 (\a b c -> (a + b) .+ c ≈ a + (b .+ c)))- , ( "additive module commutative: (a + b) .+ c ≈ (a .+ c) + b"- , Ternary21 (\a b c -> (a + b) .+ c ≈ (a .+ c) + b))- , ("additive module unital: a .+ zero == a", Unary10 (\a -> a .+ zero == a))- , ( "module additive equivalence: a .+ b ≈ b +. a"- , Binary11 (\a b -> a .+ b ≈ b +. a))- ]--additiveGroupModuleLaws ::- (Epsilon a, Epsilon (r a), AdditiveGroupModule r a)- => [Law2 (r a) a]-additiveGroupModuleLaws =- [ ( "additive group module associative: (a + b) .- c ≈ a + (b .- c)"- , Ternary21 (\a b c -> (a + b) .- c ≈ a + (b .- c)))- , ( "additive group module commutative: (a + b) .- c ≈ (a .- c) + b"- , Ternary21 (\a b c -> (a + b) .- c ≈ (a .- c) + b))- , ( "additive group module unital: a .- zero == a"- , Unary10 (\a -> a .- zero == a))- , ( "module additive group equivalence: a .- b ≈ negate b +. a"- , Binary11 (\a b -> a .- b ≈ negate b +. a))- ]--multiplicativeModuleLaws ::- (Epsilon a, Epsilon (r a), MultiplicativeModule r a)- => [Law2 (r a) a]-multiplicativeModuleLaws =- [ ( "multiplicative module unital: a .* one == a"- , Unary10 (\a -> a .* one == a))- , ( "module right distribution: (a + b) .* c ≈ (a .* c) + (b .* c)"- , Ternary21 (\a b c -> (a + b) .* c ≈ (a .* c) + (b .* c)))- , ( "module left distribution: c *. (a + b) ≈ (c *. a) + (c *. b)"- , Ternary21 (\a b c -> c *. (a + b) ≈ (c *. a) + (c *. b)))- , ("annihilation: a .* zero == zero", Unary10 (\a -> a .* zero == zero))- , ( "module multiplicative equivalence: a .* b ≈ b *. a"- , Binary11 (\a b -> a .* b ≈ b *. a))- ]--multiplicativeGroupModuleLawsFail ::- ( Epsilon a- , Epsilon (r a)- , MultiplicativeGroupModule r a- )- => [Law2 (r a) a]-multiplicativeGroupModuleLawsFail =- [ ( "multiplicative group module unital: a ./ one == a"- , Unary10 (\a -> nearZero a || a ./ one == a))- , ( "module multiplicative group equivalence: a ./ b ≈ recip b *. a"- , Binary11 (\a b -> b == zero || a ./ b ≈ recip b *. a))- ]--banachLaws ::- ( Foldable r- , Epsilon (r a)- , Banach r a- , Singleton r- , Signed a- , FromRatio a- , Ord a- )- => [Law2 (r a) a]-banachLaws =- [ ( "L1: normalize a .* norm a ≈ one"- , Unary10- (\a ->- a == singleton zero ||- (any ((> smallRational) . abs) a || (normalizeL1 a .* normL1 a) ≈ a)))- , ( "L2: normalize a .* norm a ≈ one"- , Unary10- (\a ->- a == singleton zero ||- (any ((> smallRational) . abs) a || (normalizeL2 a .* normL2 a) ≈ a)))-{-- , ( "Lp: normalizeLp a p .* normLp a p ≈ one"- , Binary11- (\a p ->- a == singleton zero ||- (any ((> smallRational) . normL1) a || (normalizeLp p a .* normLp p a) ≈ a)))--}- ]--hilbertLaws ::- ( MultiplicativeModule r a- , Epsilon a- , Epsilon (r a)- , Hilbert r a)- => [Law2 (r a) a]-hilbertLaws =- [ ("commutative a <.> b ≈ b <.> a", Ternary21 (\a b _ -> a <.> b ≈ b <.> a))- , ( "distributive over addition a <.> (b + c) == a <.> b + a <.> c"- , Ternary30 (\a b c -> a <.> (b + c) ≈ a <.> b + a <.> c))- , ( "bilinear a <.> (s *. b + c) == s * (a <.> b) + a <.> c"- , Quad31 (\a b c s -> a <.> (s *. b + c) == s * (a <.> b) + a <.> c))- , ( "scalar multiplication (s0 *. a) <.> (s1 *. b) == s0 * s1 * (a <.> b)"- , Quad22 (\a b s0 s1 -> (s0 *. a) <.> (s1 *. b) == s0 * s1 * (a <.> b)))- ]--tensorProductLaws ::- ( Eq (r (r a))- , Additive (r (r a))- , TensorProduct (r a)- , Epsilon (r a)- )- => [Law2 (r a) a]-tensorProductLaws =- [ ( "left distribution over addition a><b + c><b == (a+c) >< b"- , Ternary30 (\a b c -> a >< b + c >< b == (a + c) >< b))- , ( "right distribution over addition a><b + a><c == a >< (b+c)"- , Ternary30 (\a b c -> a >< b + a >< c == a >< (b + c)))- -- , ( "left module tensor correspondance a *. (b><c) == (a><b) .* c"- -- , Ternary30 (\a b c -> a *. (b><c) == (a><b) .* c))- -- , ( "right module tensor correspondance (a><b) .* c == a *. (b><c)"- -- , Ternary30 (\a b c -> (a><b) .* c == a *. (b><c)))- ]---- basis-additiveBasisLaws :: (Epsilon (r a), AdditiveBasis r a) => [Law (r a)]-additiveBasisLaws =- [ ( "associative: (a .+. b) .+. c ≈ a .+. (b .+. c)"- , Ternary (\a b c -> (a .+. b) .+. c ≈ a .+. (b .+. c)))- , ("left id: zero .+. a = a", Unary (\a -> zero .+. a == a))- , ("right id: a .+. zero = a", Unary (\a -> a .+. zero == a))- , ("commutative: a .+. b == b .+. a", Binary (\a b -> a .+. b == b .+. a))- ]--additiveGroupBasisLaws :: (Eq (r a), Singleton r, AdditiveGroupBasis r a) => [Law (r a)]-additiveGroupBasisLaws =- [ ( "minus: a .-. a = singleton zero"- , Unary (\a -> (a .-. a) == singleton zero))- ]--multiplicativeBasisLaws :: (Eq (r a), Singleton r, MultiplicativeBasis r a) => [Law (r a)]-multiplicativeBasisLaws =- [ ( "associative: (a .*. b) .*. c == a .*. (b .*. c)"- , Ternary (\a b c -> (a .*. b) .*. c == a .*. (b .*. c)))- , ("left id: singleton one .*. a = a", Unary (\a -> singleton one .*. a == a))- , ( "right id: a .*. singleton one = a"- , Unary (\a -> a .*. singleton one == a))- , ("commutative: a .*. b == b .*. a", Binary (\a b -> a .*. b == b .*. a))- ]--multiplicativeGroupBasisLaws ::- ( Epsilon a- , Epsilon (r a)- , Singleton r- , MultiplicativeGroupBasis r a- )- => [Law (r a)]-multiplicativeGroupBasisLaws =- [ ( "basis divide: a ./. a ≈ singleton one"- , Unary (\a -> a == singleton zero || (a ./. a) ≈ singleton one))- ]---- | semiring-semiringLaws :: (Epsilon a, Semiring a) => [Law a]-semiringLaws = additiveLaws <> distributionLaws <>- [ ( "associative: (a * b) * c = a * (b * c)"- , Ternary (\a b c -> (a `times` b) `times` c == a `times` (b `times` c)))- , ("left id: one * a = a", Unary (\a -> one `times` a == a))- , ("right id: a * one = a", Unary (\a -> a `times` one == a))- ]---- | ring-ringLaws :: (Epsilon a, Ring a) => [Law a]-ringLaws = semiringLaws <> additiveGroupLaws---- | starsemiring-starSemiringLaws :: (Epsilon a, StarSemiring a) => [Law a]-starSemiringLaws = semiringLaws <>- [ ( "star law: star a == one + a `times` star a"- , Unary (\a -> star a == one + a `times` star a))- ]---- | involutive ring-involutiveRingLaws :: forall a. (Eq a, MultiplicativeUnital a,InvolutiveRing a) => [Law a]-involutiveRingLaws =- [ ( "adjoint plus law: adj (a + b) ==> adj a + adj b"- , Binary (\a b -> adj (a `plus` b) == adj a `plus` adj b))- , ( "adjoint times law: adj (a * b) ==> adj b * adj a"- , Binary (\a b -> adj (a `times` b) == adj b `times` adj a))- , ( "adjoint multiplicative unit law: adj one ==> one"- , Nonary (adj (one :: a) == one))- , ( "adjoint own inverse law: adj (adj a) ==> a"- , Unary (\a -> adj (adj a) == a))- ]----- integrals are the law groups that apply to Integral-like numbers-integralsLaws :: (Eq a, AdditiveGroup a, Integral a, Signed a, ToInteger a, FromInteger a, Multiplicative a) => [Law a]-integralsLaws =- additiveLaws <>- additiveGroupLaws <>- multiplicativeLaws <>- distributionLaws <>- integralLaws <>- signedLaws--
src/NumHask/Prelude.hs view
@@ -14,6 +14,7 @@ , fromString , fail , Complex(..)+ , module NumHask.Data.LogField , Natural(..) -- * Algebraic Heirarchy -- $instances@@ -67,6 +68,7 @@ import NumHask.Algebra.Rational import NumHask.Algebra.Ring import NumHask.Algebra.Singleton+import NumHask.Data.LogField -- $backend -- NumHask imports Protolude as the prelude and replaces much of the 'Num' heirarchy in base.
test/test.hs view
@@ -1,336 +1,12 @@ {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -Wall #-}-{-# OPTIONS_GHC -fno-warn-orphans #-} --- | testing IEEE numbers is a special kind of hell, and one that I reserve for days when I can hardly think, so please forgive the horrible hackery contained within this file.------ This suite sometimes fails, having been hand-crafty towards balancing reasonably approximate equality versus unbounded failure (given enough trials). module Main where import NumHask.Prelude-import GHC.Natural (Natural(..))-import NumHask.Laws- import Test.DocTest-import Test.Tasty- (TestTree, defaultMain, testGroup) -import Test.QuickCheck.Arbitrary-import Test.QuickCheck.Gen--instance Arbitrary Natural where- arbitrary = fromInteger . abs <$> arbitrary--instance Arbitrary Rational where- arbitrary = reduce <$> (fromInteger <$> arbitrary) <*> (fromInteger <$> arbitrary `suchThat` (>zero))- main :: IO ()-main = do- doctest ["src/NumHask/Examples.hs"]- defaultMain tests--tests :: TestTree-tests =- testGroup- "NumHask"- [ testsInt- , testsInt8- , testsInt16- , testsInt32- , testsInt64- , testsWord- , testsWord8- , testsWord16- , testsWord32- , testsWord64- , testsNatural- , testsFloat- , testsDouble- , testsBool- , testsComplexFloat- , testsRational- ]--testsInt :: TestTree-testsInt =- testGroup- "Int"- [ testGroup "Additive" $ testLawOf ([] :: [Int]) <$> additiveLaws- , testGroup "Additive Group" $ testLawOf ([] :: [Int]) <$> additiveGroupLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Int]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Int]) <$> distributionLaws- , testGroup "Integral" $ testLawOf ([] :: [Int]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Int]) <$> signedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Int, Int)]) <$>- metricIntegralLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int, Int)]) <$> normedBoundedLaws- ]--testsInteger :: TestTree-testsInteger =- testGroup- "Integer"- [ testGroup "Integrals" $ testLawOf ([] :: [Integer]) <$> integralsLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Integer, Integer)]) <$>- metricIntegralLaws- , testGroup "Normed" $ testLawOf2 ([] :: [(Integer, Integer)]) <$> normedLaws- ]--testsInt8 :: TestTree-testsInt8 =- testGroup- "Int8"- [ testGroup "Integrals" $ testLawOf ([] :: [Int8]) <$> integralsLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Int8, Int8)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int8, Int8)]) <$>- normedBoundedLaws- ]--testsInt16 :: TestTree-testsInt16 =- testGroup- "Int16"- [ testGroup "Integrals" $ testLawOf ([] :: [Int16]) <$> integralsLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Int16, Int16)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int16, Int16)]) <$>- normedBoundedLaws- ]--testsInt32 :: TestTree-testsInt32 =- testGroup- "Int32"- [ testGroup "Integrals" $ testLawOf ([] :: [Int32]) <$> integralsLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Int32, Int32)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int32, Int32)]) <$>- normedBoundedLaws- ]--testsInt64 :: TestTree-testsInt64 =- testGroup- "Int64"- [ testGroup "Integrals" $ testLawOf ([] :: [Int64]) <$> integralsLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Int64, Int64)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int64, Int64)]) <$>- normedBoundedLaws- ]--testsWord :: TestTree-testsWord =- testGroup- "Word"- [ testGroup "Additive" $ testLawOf ([] :: [Word]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Word]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Word]) <$> distributionLaws- , testGroup "Integral" $ testLawOf ([] :: [Word]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Word]) <$> signedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Word, Word)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word, Word)]) <$>- normedBoundedLaws- ]--testsWord8 :: TestTree-testsWord8 =- testGroup- "Word8"- [ testGroup "Additive" $ testLawOf ([] :: [Word8]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Word8]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Word8]) <$> distributionLaws- , testGroup "Integral" $ testLawOf ([] :: [Word8]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Word8]) <$> signedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Word8, Word8)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word8, Word8)]) <$>- normedBoundedLaws- ]--testsWord16 :: TestTree-testsWord16 =- testGroup- "Word16"- [ testGroup "Additive" $ testLawOf ([] :: [Word16]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Word16]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Word16]) <$> distributionLaws- , testGroup "Integral" $ testLawOf ([] :: [Word16]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Word16]) <$> signedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Word16, Word16)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word16, Word16)]) <$>- normedBoundedLaws- ]--testsWord32 :: TestTree-testsWord32 =- testGroup- "Word32"- [ testGroup "Additive" $ testLawOf ([] :: [Word32]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Word32]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Word32]) <$> distributionLaws- , testGroup "Integral" $ testLawOf ([] :: [Word32]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Word32]) <$> signedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Word32, Word32)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word32, Word32)]) <$>- normedBoundedLaws- ]--testsWord64 :: TestTree-testsWord64 =- testGroup- "Word64"- [ testGroup "Additive" $ testLawOf ([] :: [Word64]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Word64]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Word64]) <$> distributionLaws- , testGroup "Integral" $ testLawOf ([] :: [Word64]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Word64]) <$> signedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Word64, Word64)]) <$>- metricIntegralBoundedLaws- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Word64, Word64)]) <$>- normedBoundedLaws- ]--testsNatural :: TestTree-testsNatural =- testGroup- "Natural"- [ testGroup "Additive" $ testLawOf ([] :: [Natural]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Natural]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Natural]) <$> distributionLaws- , testGroup "Naturalegral" $ testLawOf ([] :: [Natural]) <$> integralLaws- , testGroup "Signed" $ testLawOf ([] :: [Natural]) <$> signedLaws- , testGroup "Normed" $ testLawOf2 ([] :: [(Natural, Natural)]) <$> normedLaws- ]--testsFloat :: TestTree-testsFloat =- testGroup- "Float"- [ testGroup "Additive - Associative Fail" $- testLawOf ([] :: [Float]) <$> additiveLawsFail- , testGroup "Additive Group" $- testLawOf ([] :: [Float]) <$> additiveGroupLaws- , testGroup "Multiplicative - Associative Fail" $- testLawOf ([] :: [Float]) <$> multiplicativeLawsFail- , testGroup "MultiplicativeGroup" $- testLawOf ([] :: [Float]) <$> multiplicativeGroupLaws_- , testGroup "Distribution - Fail" $- testLawOf ([] :: [Float]) <$> distributionLawsFail- , testGroup "Signed" $ testLawOf ([] :: [Float]) <$> signedLaws- , testGroup "Normed" $ testLawOf2 ([] :: [(Float, Float)]) <$> normedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Float, Float)]) <$> metricRationalLaws- , testGroup "Upper Bounded Field" $- testLawOf ([] :: [Float]) <$> upperBoundedFieldLaws- , testGroup "Lower Bounded Field" $- testLawOf ([] :: [Float]) <$> lowerBoundedFieldLaws- , testGroup "Quotient Field" $- testLawOf2 ([] :: [(Float,Integer)]) <$> quotientFieldLaws- , testGroup "Exponential Field" $ testLawOf2 ([] :: [(Float,Float)]) <$> expFieldLaws- , testGroup "Rational" $ testLawOf ([] :: [Float]) <$> rationalLaws- ]--testsDouble :: TestTree-testsDouble =- testGroup- "Double"- [ testGroup "Additive - Associative Fail" $- testLawOf ([] :: [Double]) <$> additiveLawsFail- , testGroup "Additive Group" $- testLawOf ([] :: [Double]) <$> additiveGroupLaws- , testGroup "Multiplicative - Associative Fail" $- testLawOf ([] :: [Double]) <$> multiplicativeLawsFail- , testGroup "MultiplicativeGroup" $- testLawOf ([] :: [Double]) <$> multiplicativeGroupLaws_- , testGroup "Distribution - Fail" $- testLawOf ([] :: [Double]) <$> distributionLawsFail- , testGroup "Signed" $ testLawOf ([] :: [Double]) <$> signedLaws- , testGroup "Normed" $ testLawOf2 ([] :: [(Double, Double)]) <$> normedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Double, Double)]) <$> metricRationalLaws- , testGroup "Upper Bounded Field" $- testLawOf ([] :: [Double]) <$> upperBoundedFieldLaws- , testGroup "Lower Bounded Field" $- testLawOf ([] :: [Double]) <$> lowerBoundedFieldLaws- , testGroup "Quotient Field" $- testLawOf2 ([] :: [(Double,Integer)]) <$> quotientFieldLaws- , testGroup "Exponential Field" $ testLawOf2 ([] :: [(Double,Double)]) <$> expFieldLaws- , testGroup "Rational" $ testLawOf ([] :: [Double]) <$> rationalLaws- ]--testsBool :: TestTree-testsBool =- testGroup- "Bool"- [ testGroup "Idempotent" $ testLawOf ([] :: [Bool]) <$> idempotentLaws- , testGroup "Additive" $ testLawOf ([] :: [Bool]) <$> additiveLaws- , testGroup "Multiplicative" $- testLawOf ([] :: [Bool]) <$> multiplicativeLaws- , testGroup "Distribution" $ testLawOf ([] :: [Bool]) <$> distributionLaws- ]--testsComplexFloat :: TestTree-testsComplexFloat =- testGroup- "Complex Float"- [ testGroup "Additive - Associative Fail" $- testLawOf ([] :: [Complex Float]) <$> additiveLawsFail- , testGroup "Additive Group" $- testLawOf ([] :: [Complex Float]) <$> additiveGroupLaws- , testGroup "Multiplicative - Associative Fail" $- testLawOf ([] :: [Complex Float]) <$> multiplicativeLawsFail- , testGroup "MultiplicativeGroup" $- testLawOf ([] :: [Complex Float]) <$> multiplicativeGroupLaws_- , testGroup "Distribution - Fail" $- testLawOf ([] :: [Complex Float]) <$> distributionLawsFail- -- , testGroup "Exponential Field" $- -- testLawOf2 ([] :: [(Complex Float, Float)]) <$> expFieldLaws - , testGroup "Normed" $ testLawOf2 ([] :: [(Complex Float, Float)]) <$>- normedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Complex Float, Float)]) <$>- metricRationalLaws- , testGroup "Involutive Ring" $ testLawOf ([] :: [Complex Float]) <$>- involutiveRingLaws- ]--testsRational :: TestTree-testsRational =- testGroup- "Rational"- [ testGroup "Additive - Associative" $- testLawOf ([] :: [Rational]) <$> additiveLaws- , testGroup "Additive Group" $- testLawOf ([] :: [Rational]) <$> additiveGroupLaws- , testGroup "Multiplicative - Associative" $- testLawOf ([] :: [Rational]) <$> multiplicativeLaws- , testGroup "MultiplicativeGroup" $- testLawOf ([] :: [Rational]) <$> multiplicativeGroupLaws_- , testGroup "Distribution" $- testLawOf ([] :: [Rational]) <$> distributionLaws- , testGroup "Signed" $ testLawOf ([] :: [Rational]) <$> signedLaws- , testGroup "Normed" $ testLawOf2 ([] :: [(Rational, Rational)]) <$> normedLaws- , testGroup "Metric" $ testLawOf2 ([] :: [(Rational, Rational)]) <$> metricRationalLaws- , testGroup "Rational" $ testLawOf ([] :: [Rational]) <$> rationalLaws-- -- fixme: rounding and infinities need work-{-- , testGroup "Quotient Field" $- testLawOf ([] :: [Rational]) <$> quotientFieldLaws- , testGroup "Upper Bounded Field" $- testLawOf ([] :: [Rational]) <$> upperBoundedFieldLaws- , testGroup "Lower Bounded Field" $- testLawOf ([] :: [Rational]) <$> lowerBoundedFieldLaws+main = doctest ["src/NumHask/Examples.hs"] --}- ]