{-# OPTIONS_GHC -Wno-orphans #-}
{-|
    Module      :  AERN2.Real.Tests
    Description :  Tests for operations on Cauchy real numbers
    Copyright   :  (c) Michal Konecny
    License     :  BSD3

    Maintainer  :  mikkonecny@gmail.com
    Stability   :  experimental
    Portability :  portable

    Tests for operations on Cauchy real numbers.

    To run the tests using stack, execute:

    @
    stack test aern2-real --test-arguments "-a 1000 -m CReal"
    @
-}
module AERN2.Real.Tests
  (
    specCReal, tCReal
  )
where

import MixedTypesNumPrelude
-- import qualified Prelude as P
-- import Data.Ratio
-- import Text.Printf

import qualified Numeric.CollectErrors as CN

import Test.Hspec
import Test.QuickCheck
-- import qualified Test.Hspec.SmallCheck as SC

-- import AERN2.Norm
import AERN2.MP.Accuracy
--
import AERN2.MP
import AERN2.MP.Dyadic

import AERN2.Limit
import AERN2.Select
import AERN2.Real.Type
-- import AERN2.Real.CKleenean
import AERN2.Real.Field ()
import AERN2.Real.Elementary ()
import AERN2.Real.Limit ()

instance Arbitrary CReal where
  arbitrary :: Gen CReal
arbitrary =
    [(Int, Gen CReal)] -> Gen CReal
forall a. [(Int, Gen a)] -> Gen a
frequency
      [(Integer -> Int
forall t. CanBeInt t => t -> Int
int Integer
1, Integer -> CReal
forall t. CanBeCReal t => t -> CReal
creal (Integer -> CReal) -> Gen Integer -> Gen CReal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer -> Gen Integer
forall a.
(Arbitrary a, HasOrderCertainly a Integer) =>
Integer -> Gen a
arbitrarySmall Integer
1000000 :: Gen Integer)),
       (Integer -> Int
forall t. CanBeInt t => t -> Int
int Integer
1, Rational -> CReal
forall t. CanBeCReal t => t -> CReal
creal (Rational -> CReal) -> Gen Rational -> Gen CReal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer -> Gen Rational
forall a.
(Arbitrary a, HasOrderCertainly a Integer) =>
Integer -> Gen a
arbitrarySmall Integer
1000000 :: Gen Rational)),
       (Integer -> Int
forall t. CanBeInt t => t -> Int
int Integer
2, Integer -> CReal -> CReal
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
(*) (Integer -> CReal -> CReal) -> Gen Integer -> Gen (CReal -> CReal)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Integer -> Gen Integer
forall a.
(Arbitrary a, HasOrderCertainly a Integer) =>
Integer -> Gen a
arbitrarySmall Integer
1000000 :: Gen Integer) Gen (CReal -> CReal) -> Gen CReal -> Gen CReal
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Gen CReal
arbitrarySignedBinary)
      ]
      where
      arbitrarySignedBinary :: Gen CReal
arbitrarySignedBinary =
        [Integer] -> CReal
forall a.
(HasEqAsymmetric a Integer, EqCompareType a Integer ~ Bool) =>
[a] -> CReal
signedBinary2Real ([Integer] -> CReal) -> Gen [Integer] -> Gen CReal
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Integer -> Gen [Integer]
forall a. Gen a -> Gen [a]
infiniteListOf ([Integer] -> Gen Integer
forall a. [a] -> Gen a
elements [-Integer
1,Integer
0,Integer
1])
      signedBinary2Real :: [a] -> CReal
signedBinary2Real [a]
sbits =
        (Precision -> CN MPBall) -> CReal
crealFromPrecFunction ((Precision -> CN MPBall) -> CReal)
-> (Precision -> CN MPBall) -> CReal
forall a b. (a -> b) -> a -> b
$ \ Precision
p -> MPBall -> CN MPBall
forall v. v -> CN v
cn (MPBall -> CN MPBall) -> MPBall -> CN MPBall
forall a b. (a -> b) -> a -> b
$ [MPBall]
[MulType MPBall Dyadic]
balls [MPBall] -> Precision -> MPBall
forall n a. CanBeInteger n => [a] -> n -> a
!! Precision
p
        where
        balls :: [MulType MPBall Dyadic]
balls = MulType MPBall Dyadic
-> [(a, Precision)] -> [MulType MPBall Dyadic]
forall a t1.
(HasEqAsymmetric a Integer,
 CanAddAsymmetric (MulType t1 Dyadic) (MulType t1 Dyadic),
 CanMulAsymmetric t1 Dyadic, CanSetPrecision (MulType t1 Dyadic),
 IsInterval (MulType t1 Dyadic),
 CanMinMaxAsymmetric
   (IntervalEndpoint (MulType t1 Dyadic))
   (IntervalEndpoint (MulType t1 Dyadic)),
 AddType (MulType t1 Dyadic) (MulType t1 Dyadic) ~ t1,
 EqCompareType a Integer ~ Bool,
 MinMaxType
   (IntervalEndpoint (MulType t1 Dyadic))
   (IntervalEndpoint (MulType t1 Dyadic))
 ~ IntervalEndpoint (MulType t1 Dyadic)) =>
MulType t1 Dyadic -> [(a, Precision)] -> [MulType t1 Dyadic]
nextBit ((Integer, Integer) -> MPBall
forall t. CanBeMPBall t => t -> MPBall
mpBall (Integer
0,Integer
1)) ([(a, Precision)] -> [MulType MPBall Dyadic])
-> [(a, Precision)] -> [MulType MPBall Dyadic]
forall a b. (a -> b) -> a -> b
$ [a] -> [Precision] -> [(a, Precision)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a]
sbits ((Integer -> Precision) -> [Integer] -> [Precision]
forall a b. (a -> b) -> [a] -> [b]
map Integer -> Precision
prec [Integer
10..])
        nextBit :: MulType t1 Dyadic -> [(a, Precision)] -> [MulType t1 Dyadic]
nextBit MulType t1 Dyadic
ball ((a
sbit, Precision
p):[(a, Precision)]
rest) =
          MulType t1 Dyadic
ball MulType t1 Dyadic -> [MulType t1 Dyadic] -> [MulType t1 Dyadic]
forall a. a -> [a] -> [a]
: MulType t1 Dyadic -> [(a, Precision)] -> [MulType t1 Dyadic]
nextBit MulType t1 Dyadic
newBall [(a, Precision)]
rest
          where
          newBall :: MulType t1 Dyadic
newBall =
            case a
sbit of
              (-1) -> MulType t1 Dyadic -> MulType t1 Dyadic -> MulType t1 Dyadic
forall i.
(IsInterval i, CanMinMaxSameType (IntervalEndpoint i)) =>
i -> i -> i
fromEndpointsAsIntervals MulType t1 Dyadic
l MulType t1 Dyadic
m
              a
0 -> MulType t1 Dyadic -> MulType t1 Dyadic -> MulType t1 Dyadic
forall i.
(IsInterval i, CanMinMaxSameType (IntervalEndpoint i)) =>
i -> i -> i
fromEndpointsAsIntervals MulType t1 Dyadic
l2 MulType t1 Dyadic
r2
              a
1 -> MulType t1 Dyadic -> MulType t1 Dyadic -> MulType t1 Dyadic
forall i.
(IsInterval i, CanMinMaxSameType (IntervalEndpoint i)) =>
i -> i -> i
fromEndpointsAsIntervals MulType t1 Dyadic
m MulType t1 Dyadic
r
              a
_ -> [Char] -> MulType t1 Dyadic
forall a. HasCallStack => [Char] -> a
error [Char]
"in Arbitrary CReal"
          (MulType t1 Dyadic
l_,MulType t1 Dyadic
r_) = MulType t1 Dyadic -> (MulType t1 Dyadic, MulType t1 Dyadic)
forall i. IsInterval i => i -> (i, i)
endpointsAsIntervals MulType t1 Dyadic
ball
          l :: MulType t1 Dyadic
l = Precision -> MulType t1 Dyadic -> MulType t1 Dyadic
forall t. CanSetPrecision t => Precision -> t -> t
setPrecision Precision
p MulType t1 Dyadic
l_
          r :: MulType t1 Dyadic
r = Precision -> MulType t1 Dyadic -> MulType t1 Dyadic
forall t. CanSetPrecision t => Precision -> t -> t
setPrecision Precision
p MulType t1 Dyadic
r_
          m :: MulType t1 Dyadic
m = (MulType t1 Dyadic
l MulType t1 Dyadic
-> MulType t1 Dyadic
-> AddType (MulType t1 Dyadic) (MulType t1 Dyadic)
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ MulType t1 Dyadic
r) t1 -> Dyadic -> MulType t1 Dyadic
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
* (Rational -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Rational
0.5)
          l2 :: MulType t1 Dyadic
l2 = (MulType t1 Dyadic
l MulType t1 Dyadic
-> MulType t1 Dyadic
-> AddType (MulType t1 Dyadic) (MulType t1 Dyadic)
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ MulType t1 Dyadic
m) t1 -> Dyadic -> MulType t1 Dyadic
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
* (Rational -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Rational
0.5)
          r2 :: MulType t1 Dyadic
r2 = (MulType t1 Dyadic
r MulType t1 Dyadic
-> MulType t1 Dyadic
-> AddType (MulType t1 Dyadic) (MulType t1 Dyadic)
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+ MulType t1 Dyadic
m) t1 -> Dyadic -> MulType t1 Dyadic
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
* (Rational -> Dyadic
forall t. CanBeDyadic t => t -> Dyadic
dyadic Rational
0.5)
        nextBit MulType t1 Dyadic
_ [(a, Precision)]
_ = [Char] -> [MulType t1 Dyadic]
forall a. HasCallStack => [Char] -> a
error [Char]
"in Arbitrary CReal"

arbitrarySmall :: (Arbitrary a, HasOrderCertainly a Integer) => Integer -> Gen a
arbitrarySmall :: Integer -> Gen a
arbitrarySmall Integer
bound = Gen a
aux
  where
  aux :: Gen a
aux =
    do
    a
x <- Gen a
forall a. Arbitrary a => Gen a
arbitrary
    if -Integer
bound Integer -> a -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<=! a
x Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& a
x a -> Integer -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<=! Integer
bound
      then a -> Gen a
forall (m :: * -> *) a. Monad m => a -> m a
return a
x
      else Gen a
aux


{-|
  A runtime representative of type @CReal@.
  Used for specialising polymorphic tests to concrete types.
-}
tCReal :: T CReal
tCReal :: T CReal
tCReal = [Char] -> T CReal
forall t. [Char] -> T t
T [Char]
"CReal"

specCRrespectsAccuracy1 ::
  String ->
  (CReal -> CReal) ->
  (CReal -> Accuracy -> Bool) ->
  Spec
specCRrespectsAccuracy1 :: [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
opName CReal -> CReal
op CReal -> Accuracy -> Bool
precond =
  [Char] -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it ([Char]
opName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" respects accuracy requests") (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ do
    (CReal -> Accuracy -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((CReal -> Accuracy -> Property) -> Property)
-> (CReal -> Accuracy -> Property) -> Property
forall a b. (a -> b) -> a -> b
$
      \ (CReal
x :: CReal) (Accuracy
ac :: Accuracy) ->
        Accuracy
ac Accuracy -> Accuracy -> OrderCompareType Accuracy Accuracy
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< (Integer -> Accuracy
forall t. ConvertibleExactly t Accuracy => t -> Accuracy
bits Integer
1000) Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& CReal -> Accuracy -> Bool
precond CReal
x Accuracy
ac Bool -> Property -> Property
forall prop. Testable prop => Bool -> prop -> Property
==>
        case CN MPBall -> Either NumErrors MPBall
forall es v. CanBeErrors es => CollectErrors es v -> Either es v
CN.toEither ((CReal -> CReal
op CReal
x) CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac) of
          Right MPBall
v -> MPBall -> Accuracy
forall a. HasAccuracy a => a -> Accuracy
getAccuracy MPBall
v Accuracy -> Accuracy -> Property
>=$ Accuracy
ac
          Either NumErrors MPBall
_ -> Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True

specCRrespectsAccuracy2 ::
  String ->
  (CReal -> CReal -> CReal) ->
  (CReal -> Accuracy -> Bool) ->
  (CReal -> Accuracy -> Bool) ->
  Spec
specCRrespectsAccuracy2 :: [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
opName CReal -> CReal -> CReal
op CReal -> Accuracy -> Bool
precond1 CReal -> Accuracy -> Bool
precond2 =
  [Char] -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it ([Char]
opName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" respects accuracy requests") (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ do
    (CReal -> CReal -> Accuracy -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((CReal -> CReal -> Accuracy -> Property) -> Property)
-> (CReal -> CReal -> Accuracy -> Property) -> Property
forall a b. (a -> b) -> a -> b
$
      \ (CReal
x :: CReal) (CReal
y :: CReal) (Accuracy
ac :: Accuracy) ->
        Accuracy
ac Accuracy -> Accuracy -> OrderCompareType Accuracy Accuracy
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< (Integer -> Accuracy
forall t. ConvertibleExactly t Accuracy => t -> Accuracy
bits Integer
1000) Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& CReal -> Accuracy -> Bool
precond1 CReal
x Accuracy
ac Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& CReal -> Accuracy -> Bool
precond2 CReal
y Accuracy
ac Bool -> Property -> Property
forall prop. Testable prop => Bool -> prop -> Property
==>
        case CN MPBall -> Either NumErrors MPBall
forall es v. CanBeErrors es => CollectErrors es v -> Either es v
CN.toEither ((CReal -> CReal -> CReal
op CReal
x CReal
y) CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac) of
          Right MPBall
v -> MPBall -> Accuracy
forall a. HasAccuracy a => a -> Accuracy
getAccuracy MPBall
v Accuracy -> Accuracy -> Property
>=$ Accuracy
ac
          Either NumErrors MPBall
_ -> Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True

(>=$) :: Accuracy -> Accuracy -> Property
>=$ :: Accuracy -> Accuracy -> Property
(>=$) = [Char]
-> (Accuracy -> Accuracy -> Bool)
-> Accuracy
-> Accuracy
-> Property
forall prop a b.
(Testable prop, Show a, Show b) =>
[Char] -> (a -> b -> prop) -> a -> b -> Property
printArgsIfFails2 [Char]
">=" Accuracy -> Accuracy -> Bool
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
(>=)

precondAnyReal :: CReal -> Accuracy -> Bool
precondAnyReal :: CReal -> Accuracy -> Bool
precondAnyReal CReal
_x Accuracy
_ac = Bool
True

precondPositiveReal :: CReal -> Accuracy -> Bool
precondPositiveReal :: CReal -> Accuracy -> Bool
precondPositiveReal CReal
x Accuracy
ac = (CReal
x CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac) CN MPBall -> Integer -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!>! Integer
0

precondNonZeroReal :: CReal -> Accuracy -> Bool
precondNonZeroReal :: CReal -> Accuracy -> Bool
precondNonZeroReal CReal
x Accuracy
ac = (CReal
x CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac) CN MPBall -> Integer -> Bool
forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
!/=! Integer
0

precondSmallReal :: CReal -> Accuracy -> Bool
precondSmallReal :: CReal -> Accuracy -> Bool
precondSmallReal CReal
x Accuracy
ac = CN MPBall -> AbsType (CN MPBall)
forall t. CanAbs t => t -> AbsType t
abs (CReal
x CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac) CN MPBall -> Integer -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<! Integer
1000

precondPositiveSmallReal :: CReal -> Accuracy -> Bool
precondPositiveSmallReal :: CReal -> Accuracy -> Bool
precondPositiveSmallReal CReal
x Accuracy
ac = Integer
0 Integer -> CN MPBall -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<! CN MPBall
ExtractedApproximation CReal Accuracy
b Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& CN MPBall
ExtractedApproximation CReal Accuracy
b CN MPBall -> Integer -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<! Integer
1000
  where b :: ExtractedApproximation CReal Accuracy
b = CReal
x CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac

-- specCRrespectsAccuracy2 ::
--   String ->
--   (CReal -> CReal -> CReal) ->
--   (CReal -> Accuracy -> Bool) ->
--   (CReal -> Accuracy -> Bool) ->
--   Spec
-- specCRrespectsAccuracy2 opName op =
--   specCRrespectsAccuracy2CN opName (\ a b -> cn (op a b))

specCRrespectsAccuracy2T ::
  (Arbitrary t, Show t) =>
  T t ->
  String ->
  (CReal -> t -> CReal) ->
  (CReal -> Accuracy -> Bool) ->
  (t -> Bool) ->
  Spec
specCRrespectsAccuracy2T :: T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T  (T [Char]
tName :: T t) [Char]
opName CReal -> t -> CReal
op CReal -> Accuracy -> Bool
precond1 t -> Bool
precond2 =
  [Char] -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it ([Char]
opName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" with " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
tName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" respects accuracy requests") (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ do
    (CReal -> t -> Accuracy -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((CReal -> t -> Accuracy -> Property) -> Property)
-> (CReal -> t -> Accuracy -> Property) -> Property
forall a b. (a -> b) -> a -> b
$
      \ (CReal
x :: CReal) (t
t :: t) (Accuracy
ac :: Accuracy) ->
        Accuracy
ac Accuracy -> Accuracy -> OrderCompareType Accuracy Accuracy
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< (Integer -> Accuracy
forall t. ConvertibleExactly t Accuracy => t -> Accuracy
bits Integer
1000) Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& CReal -> Accuracy -> Bool
precond1 CReal
x Accuracy
ac Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& t -> Bool
precond2 t
t Bool -> Property -> Property
forall prop. Testable prop => Bool -> prop -> Property
==>
        case CN MPBall -> Either NumErrors MPBall
forall es v. CanBeErrors es => CollectErrors es v -> Either es v
CN.toEither ((CReal -> t -> CReal
op CReal
x t
t) CReal -> Accuracy -> ExtractedApproximation CReal Accuracy
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Accuracy
ac) of
          Right MPBall
v -> MPBall -> Accuracy
forall a. HasAccuracy a => a -> Accuracy
getAccuracy MPBall
v Accuracy -> Accuracy -> Property
>=$ Accuracy
ac
          Either NumErrors MPBall
_ -> Bool -> Property
forall prop. Testable prop => prop -> Property
property Bool
True

precondAnyT :: t -> Bool
precondAnyT :: t -> Bool
precondAnyT t
_t = Bool
True

precondNonZeroT :: (HasEqCertainly t Integer) => t -> Bool
precondNonZeroT :: t -> Bool
precondNonZeroT t
t = t
t t -> Integer -> Bool
forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
!/=! Integer
0

precondSmallT :: (HasOrderCertainly t Integer) => t -> Bool
precondSmallT :: t -> Bool
precondSmallT t
t = -Integer
1000 Integer -> t -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<=! t
t Bool -> Bool -> AndOrType Bool Bool
forall a b. CanAndOrAsymmetric a b => a -> b -> AndOrType a b
&& t
t t -> Integer -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
!<=! Integer
1000

specCReal :: Spec
specCReal :: Spec
specCReal =
  [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe ([Char]
"CReal") (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
    -- specConversion tInteger tCReal creal (fst . integerBounds)
    -- describe "order" $ do
    --   specHasEqNotMixed tCReal
    --   specHasEq tInt tCReal tRational
    --   specCanPickNonZero tCReal
    --   specHasOrderNotMixed tCReal
    --   specHasOrder tInt tCReal tRational
    [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe [Char]
"min/max/abs" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"abs" CReal -> CReal
forall t. CanAbs t => t -> AbsType t
abs CReal -> Accuracy -> Bool
precondAnyReal
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"max" CReal -> CReal -> CReal
forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
max CReal -> Accuracy -> Bool
precondAnyReal CReal -> Accuracy -> Bool
precondAnyReal
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"min" CReal -> CReal -> CReal
forall t1 t2.
CanMinMaxAsymmetric t1 t2 =>
t1 -> t2 -> MinMaxType t1 t2
min CReal -> Accuracy -> Bool
precondAnyReal CReal -> Accuracy -> Bool
precondAnyReal
    [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe [Char]
"ring" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"negate" CReal -> CReal
forall t. CanNeg t => t -> NegType t
negate CReal -> Accuracy -> Bool
precondAnyReal
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"+" CReal -> CReal -> CReal
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add CReal -> Accuracy -> Bool
precondAnyReal CReal -> Accuracy -> Bool
precondAnyReal
      T Integer
-> [Char]
-> (CReal -> Integer -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Integer -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Integer
tInteger [Char]
"+" CReal -> Integer -> CReal
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add CReal -> Accuracy -> Bool
precondAnyReal Integer -> Bool
forall t. t -> Bool
precondAnyT
      T Rational
-> [Char]
-> (CReal -> Rational -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Rational -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Rational
tRational [Char]
"+" CReal -> Rational -> CReal
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add CReal -> Accuracy -> Bool
precondAnyReal Rational -> Bool
forall t. t -> Bool
precondAnyT
      T Dyadic
-> [Char]
-> (CReal -> Dyadic -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Dyadic -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Dyadic
tDyadic [Char]
"+" CReal -> Dyadic -> CReal
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
add CReal -> Accuracy -> Bool
precondAnyReal Dyadic -> Bool
forall t. t -> Bool
precondAnyT
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"a-b" CReal -> CReal -> CReal
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub CReal -> Accuracy -> Bool
precondAnyReal CReal -> Accuracy -> Bool
precondAnyReal
      T Integer
-> [Char]
-> (CReal -> Integer -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Integer -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Integer
tInteger [Char]
"a-b" CReal -> Integer -> CReal
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub CReal -> Accuracy -> Bool
precondAnyReal Integer -> Bool
forall t. t -> Bool
precondAnyT
      T Rational
-> [Char]
-> (CReal -> Rational -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Rational -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Rational
tRational [Char]
"a-b" CReal -> Rational -> CReal
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub CReal -> Accuracy -> Bool
precondAnyReal Rational -> Bool
forall t. t -> Bool
precondAnyT
      T Dyadic
-> [Char]
-> (CReal -> Dyadic -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Dyadic -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Dyadic
tDyadic [Char]
"a-b" CReal -> Dyadic -> CReal
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
sub CReal -> Accuracy -> Bool
precondAnyReal Dyadic -> Bool
forall t. t -> Bool
precondAnyT
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"*" CReal -> CReal -> CReal
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul CReal -> Accuracy -> Bool
precondAnyReal CReal -> Accuracy -> Bool
precondAnyReal
      T Integer
-> [Char]
-> (CReal -> Integer -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Integer -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Integer
tInteger [Char]
"*" CReal -> Integer -> CReal
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul CReal -> Accuracy -> Bool
precondAnyReal Integer -> Bool
forall t. t -> Bool
precondAnyT
      T Rational
-> [Char]
-> (CReal -> Rational -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Rational -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Rational
tRational [Char]
"*" CReal -> Rational -> CReal
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul CReal -> Accuracy -> Bool
precondAnyReal Rational -> Bool
forall t. t -> Bool
precondAnyT
      T Dyadic
-> [Char]
-> (CReal -> Dyadic -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Dyadic -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Dyadic
tDyadic [Char]
"*" CReal -> Dyadic -> CReal
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
mul CReal -> Accuracy -> Bool
precondAnyReal Dyadic -> Bool
forall t. t -> Bool
precondAnyT
    [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe [Char]
"field" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"/" CReal -> CReal -> CReal
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide CReal -> Accuracy -> Bool
precondAnyReal CReal -> Accuracy -> Bool
precondNonZeroReal
      T Integer
-> [Char]
-> (CReal -> Integer -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Integer -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Integer
tInteger [Char]
"/" CReal -> Integer -> CReal
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide CReal -> Accuracy -> Bool
precondAnyReal Integer -> Bool
forall t. HasEqCertainly t Integer => t -> Bool
precondNonZeroT
      T Rational
-> [Char]
-> (CReal -> Rational -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Rational -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Rational
tRational [Char]
"/" CReal -> Rational -> CReal
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide CReal -> Accuracy -> Bool
precondAnyReal Rational -> Bool
forall t. HasEqCertainly t Integer => t -> Bool
precondNonZeroT
      T Dyadic
-> [Char]
-> (CReal -> Dyadic -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Dyadic -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Dyadic
tDyadic [Char]
"/" CReal -> Dyadic -> CReal
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
divide CReal -> Accuracy -> Bool
precondAnyReal Dyadic -> Bool
forall t. HasEqCertainly t Integer => t -> Bool
precondNonZeroT
    [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe [Char]
"elementary" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"sqrt" CReal -> CReal
forall t. CanSqrt t => t -> SqrtType t
sqrt CReal -> Accuracy -> Bool
precondPositiveReal
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"exp" CReal -> CReal
forall t. CanExp t => t -> ExpType t
exp CReal -> Accuracy -> Bool
precondSmallReal
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"log" CReal -> CReal
forall t. CanLog t => t -> LogType t
log CReal -> Accuracy -> Bool
precondPositiveSmallReal
      [Char]
-> (CReal -> CReal -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (CReal -> Accuracy -> Bool)
-> Spec
specCRrespectsAccuracy2 [Char]
"pow" CReal -> CReal -> CReal
forall b e. CanPow b e => b -> e -> PowType b e
pow CReal -> Accuracy -> Bool
precondPositiveSmallReal CReal -> Accuracy -> Bool
precondSmallReal
      T Integer
-> [Char]
-> (CReal -> Integer -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Integer -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Integer
tInteger [Char]
"pow" CReal -> Integer -> CReal
forall b e. CanPow b e => b -> e -> PowType b e
pow CReal -> Accuracy -> Bool
precondNonZeroReal Integer -> Bool
forall t. HasOrderCertainly t Integer => t -> Bool
precondSmallT
      T Rational
-> [Char]
-> (CReal -> Rational -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (Rational -> Bool)
-> Spec
forall t.
(Arbitrary t, Show t) =>
T t
-> [Char]
-> (CReal -> t -> CReal)
-> (CReal -> Accuracy -> Bool)
-> (t -> Bool)
-> Spec
specCRrespectsAccuracy2T T Rational
tRational [Char]
"pow" CReal -> Rational -> CReal
forall b e. CanPow b e => b -> e -> PowType b e
pow CReal -> Accuracy -> Bool
precondPositiveSmallReal Rational -> Bool
forall t. HasOrderCertainly t Integer => t -> Bool
precondSmallT
      -- specCRrespectsAccuracy2T tDyadic "pow" pow precondPositiveSmallReal precondSmallT
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"cos" CReal -> CReal
forall t. CanSinCos t => t -> SinCosType t
cos CReal -> Accuracy -> Bool
precondAnyReal
      [Char] -> (CReal -> CReal) -> (CReal -> Accuracy -> Bool) -> Spec
specCRrespectsAccuracy1 [Char]
"sine" CReal -> CReal
forall t. CanSinCos t => t -> SinCosType t
sin CReal -> Accuracy -> Bool
precondAnyReal
    [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe [Char]
"select" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"soft abs via select" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ do
        (CReal -> Precision -> Rational -> Property) -> Property
forall prop. Testable prop => prop -> Property
property ((CReal -> Precision -> Rational -> Property) -> Property)
-> (CReal -> Precision -> Rational -> Property) -> Property
forall a b. (a -> b) -> a -> b
$ \ (CReal
x :: CReal) (Precision
p :: Precision) (Rational
q :: Rational) ->
          (Integer
1 Integer -> Rational -> OrderCompareType Integer Rational
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< Rational
q) Bool -> Bool -> Property
forall prop. Testable prop => Bool -> prop -> Property
==>
          let eps :: DivType Integer Rational
eps = Integer
1Integer -> Rational -> DivType Integer Rational
forall t1 t2. CanDiv t1 t2 => t1 -> t2 -> DivType t1 t2
/Rational
q in
          (CReal -> AbsType CReal
forall t. CanAbs t => t -> AbsType t
abs (CReal -> AbsType CReal
forall t. CanAbs t => t -> AbsType t
abs CReal
x CReal -> CReal -> SubType CReal CReal
forall t1 t2. CanSub t1 t2 => t1 -> t2 -> SubType t1 t2
- (if CSequence Kleenean
-> CSequence Kleenean -> SelectType (CSequence Kleenean)
forall k. CanSelect k => k -> k -> SelectType k
select (CReal
x CReal -> Rational -> OrderCompareType CReal Rational
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
> -Rational
DivType Integer Rational
eps) (CReal
x CReal -> Rational -> OrderCompareType CReal Rational
forall a b.
HasOrderAsymmetric a b =>
a -> b -> OrderCompareType a b
< Rational
DivType Integer Rational
eps) then CReal
x else -CReal
x)) CReal -> Precision -> ExtractedApproximation CReal Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Precision
p) CN MPBall -> Rational -> Bool
forall a b. HasOrderCertainlyAsymmetric a b => a -> b -> Bool
?<? Integer
2Integer -> Rational -> MulType Integer Rational
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
*Rational
DivType Integer Rational
eps
    [Char] -> Spec -> Spec
forall a. HasCallStack => [Char] -> SpecWith a -> SpecWith a
describe [Char]
"limit" (Spec -> Spec) -> Spec -> Spec
forall a b. (a -> b) -> a -> b
$ do
      [Char] -> Property -> SpecWith (Arg Property)
forall a.
(HasCallStack, Example a) =>
[Char] -> a -> SpecWith (Arg a)
it [Char]
"computing e as a limit of Taylor series" (Property -> SpecWith (Arg Property))
-> Property -> SpecWith (Arg Property)
forall a b. (a -> b) -> a -> b
$ do
        (Precision -> Bool) -> Property
forall prop. Testable prop => prop -> Property
property ((Precision -> Bool) -> Property)
-> (Precision -> Bool) -> Property
forall a b. (a -> b) -> a -> b
$ \ (Precision
p :: Precision) ->
          ((MPBall -> ExpType MPBall
forall t. CanExp t => t -> ExpType t
exp (Precision -> Rational -> MPBall
forall t. CanBeMPBallP t => Precision -> t -> MPBall
mpBallP Precision
p Rational
1.0)) MPBall -> CN MPBall -> Bool
forall a b. HasEqCertainlyAsymmetric a b => a -> b -> Bool
?==?) (CN MPBall -> Bool) -> CN MPBall -> Bool
forall a b. (a -> b) -> a -> b
$
            ((Integer -> CReal) -> LimitType Integer CReal
forall ix s. HasLimits ix s => (ix -> s) -> LimitType ix s
limit ((Integer -> CReal) -> LimitType Integer CReal)
-> (Integer -> CReal) -> LimitType Integer CReal
forall a b. (a -> b) -> a -> b
$ \(Integer
n :: Integer) -> [CReal] -> CReal
forall t.
(CanAddSameType t, ConvertibleExactly Integer t) =>
[t] -> t
sum ([CReal] -> CReal) -> [CReal] -> CReal
forall a b. (a -> b) -> a -> b
$ (Integer -> CReal) -> [Integer] -> [CReal]
forall a b. (a -> b) -> [a] -> [b]
map (CReal -> CReal
forall t. CanRecip t => t -> DivType Integer t
recip (CReal -> CReal) -> (Integer -> CReal) -> Integer -> CReal
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> CReal
forall t. CanBeCReal t => t -> CReal
creal) ([Integer] -> [CReal]) -> [Integer] -> [CReal]
forall a b. (a -> b) -> a -> b
$ Integer -> [Integer] -> [Integer]
forall n a. CanBeInteger n => n -> [a] -> [a]
take (Integer
nInteger -> Integer -> AddType Integer Integer
forall t1 t2. CanAddAsymmetric t1 t2 => t1 -> t2 -> AddType t1 t2
+Integer
3) ([Integer] -> [Integer]) -> [Integer] -> [Integer]
forall a b. (a -> b) -> a -> b
$ (Integer -> Integer -> Integer)
-> Integer -> [Integer] -> [Integer]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl Integer -> Integer -> Integer
forall t1 t2. CanMulAsymmetric t1 t2 => t1 -> t2 -> MulType t1 t2
(*) Integer
1 [Integer
1..(Integer
n)]) CReal -> Precision -> ExtractedApproximation CReal Precision
forall e q.
CanExtractApproximation e q =>
e -> q -> ExtractedApproximation e q
? Precision
p