numhask-test (empty) → 0.1.0.0
raw patch · 6 files changed
+1107/−0 lines, 6 filesdep +QuickCheckdep +basedep +numhask-preludesetup-changed
Dependencies added: QuickCheck, base, numhask-prelude, numhask-test, tasty, tasty-quickcheck
Files
- LICENSE +30/−0
- Setup.hs +2/−0
- numhask-test.cabal +55/−0
- src/NumHask/Laws.hs +661/−0
- stack.yaml +8/−0
- test/test.hs +351/−0
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Tony Day (c) 2016++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Tony Day nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ numhask-test.cabal view
@@ -0,0 +1,55 @@+name: numhask-test+version: 0.1.0.0+synopsis: Laws and tests for numhask+description: Laws and tests for numhask.+category: mathematics+homepage: https://github.com/tonyday567/numhask#readme+bug-reports: https://github.com/tonyday567/numhask/issues+author: Tony Day+maintainer: tonyday567@gmail.com+copyright: Tony Day+license: BSD3+license-file: LICENSE+build-type: Simple+cabal-version: >= 1.18++extra-source-files:+ stack.yaml++source-repository head+ type: git+ location: https://github.com/tonyday567/numhask++library+ hs-source-dirs:+ src+ default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax+ ghc-options:+ -Wall+ -Wcompat+ -Wincomplete-record-updates+ -Wincomplete-uni-patterns+ -Wredundant-constraints+ build-depends:+ QuickCheck >=2.8 && <3+ , base >=4.7 && <4.12+ , numhask-prelude >=0.1.0.0 && <0.2+ , tasty >= 1.0.1.1 && <1.2+ , tasty-quickcheck >= 0.9.2 && <1.0+ exposed-modules:+ NumHask.Laws+ default-language: Haskell2010++test-suite test+ type: exitcode-stdio-1.0+ main-is: test.hs+ hs-source-dirs:+ test+ default-extensions: NegativeLiterals NoImplicitPrelude OverloadedStrings UnicodeSyntax+ build-depends:+ base >=4.7 && <5+ , QuickCheck >=2.8 && <3+ , numhask-test+ , numhask-prelude >= 0.1.0.0 && < 0.2+ , tasty+ default-language: Haskell2010
+ src/NumHask/Laws.hs view
@@ -0,0 +1,661 @@+{-# 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, 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 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, AdditiveGroup 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, Additive a, AdditiveGroup 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, Ord 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 -> case even ((floor $ a + one / (one + one)) :: Integer) of+ True -> ((round a :: Integer) == (floor $ a + (one / (one + one))))+ False -> ((round a :: Integer) == (ceiling $ a - (one / (one + one))))+ )+ )+ ] where+ sign' a+ | (floor a :: Integer) < 0 = -1+ | otherwise = 1++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, Additive (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, Additive (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, Additive (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+ , Additive (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)+ , Additive (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++
+ stack.yaml view
@@ -0,0 +1,8 @@+resolver: nightly-2018-05-06++packages:+ - .+ - ../numhask+ - ../numhask-prelude++extra-deps: []
+ test/test.hs view
@@ -0,0 +1,351 @@+{-# 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 NumHask.Laws++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))++instance (Signed a, Arbitrary a, ExpField a) => Arbitrary (LogField a) where+ arbitrary = logField . abs <$> arbitrary++main :: IO ()+main = defaultMain tests++tests :: TestTree+tests =+ testGroup+ "NumHask"+ [ testsInt+ , testsInt8+ , testsInt16+ , testsInt32+ , testsInt64+ , testsWord+ , testsWord8+ , testsWord16+ , testsWord32+ , testsWord64+ , testsNatural+ , testsFloat+ , testsDouble+ , testsBool+ , testsComplexFloat+ , testsRational+ , testsLogFieldDouble+ ]++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" $ testLawOf2 ([] :: [(Rational, Integer)]) <$> quotientFieldLaws+ , testGroup "Upper Bounded Field" $ testLawOf ([] :: [Rational]) <$> upperBoundedFieldLaws+ , testGroup "Lower Bounded Field" $ testLawOf ([] :: [Rational]) <$> lowerBoundedFieldLaws+++ ]++ -- testGroup "Distribution" $ testLawOf ([] :: [Int]) <$> distributionLaws+ -- , testGroup "Metric" $ testLawOf2 ([] :: [(Int, Int)]) <$>+ -- metricIntegralLaws+ -- , testGroup "Normed or maxBound" $ testLawOf2 ([] :: [(Int, Int)]) <$> normedBoundedLaws++testsLogFieldDouble :: TestTree+testsLogFieldDouble =+ testGroup+ "LogField Double"+ [ testGroup "Additive - Associative Fail" $+ testLawOf ([] :: [LogField Double]) <$> additiveLawsFail+ , testGroup "Multiplicative - Associative Fail" $+ testLawOf ([] :: [LogField Double]) <$> multiplicativeLawsFail+ , testGroup "MultiplicativeGroup" $+ testLawOf ([] :: [LogField Double]) <$> multiplicativeGroupLaws_+ , testGroup "Distribution - Fail" $+ testLawOf ([] :: [LogField Double]) <$> distributionLawsFail+ ]