copilot-verifier-0.1: examples/Copilot/Verifier/Examples/ShouldPass/FPOps.hs
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module Copilot.Verifier.Examples.ShouldPass.FPOps where
import Copilot.Compile.C99 (mkDefaultCSettings)
import qualified Copilot.Language.Stream as Copilot
import Copilot.Verifier ( Verbosity, VerifierOptions(..)
, defaultVerifierOptions, verifyWithOptions )
import Data.Proxy (Proxy(..))
import Language.Copilot
import qualified Prelude as P
mkSpecFor :: forall a proxy. (RealFloat a, Typed a) => proxy a -> String -> Spec
mkSpecFor _ nameSuffix = do
let mkName :: String -> String
mkName namePrefix = namePrefix P.++ nameSuffix
stream :: Stream a
stream = extern (mkName "stream") Nothing
triggerOp1 (mkName "abs") abs stream
triggerOp1 (mkName "signum") signum stream
triggerOp1 (mkName "recip") recip stream
triggerOp1 (mkName "exp") exp stream
triggerOp1 (mkName "sqrt") sqrt stream
triggerOp1 (mkName "log") log stream
triggerOp1 (mkName "sin") sin stream
triggerOp1 (mkName "tan") tan stream
triggerOp1 (mkName "cos") cos stream
triggerOp1 (mkName "asin") asin stream
triggerOp1 (mkName "atan") atan stream
triggerOp1 (mkName "acos") acos stream
triggerOp1 (mkName "sinh") sinh stream
triggerOp1 (mkName "tanh") tanh stream
triggerOp1 (mkName "cosh") cosh stream
triggerOp1 (mkName "asinh") asinh stream
triggerOp1 (mkName "atanh") atanh stream
triggerOp1 (mkName "acosh") acosh stream
triggerOp1 (mkName "ceiling") Copilot.ceiling stream
triggerOp1 (mkName "floor") Copilot.floor stream
triggerOp2 (mkName "add") (+) stream
triggerOp2 (mkName "sub") (-) stream
triggerOp2 (mkName "mul") (*) stream
triggerOp2 (mkName "div") (/) stream
triggerOp2 (mkName "pow") (**) stream
triggerOp2 (mkName "logBase") logBase stream
triggerOp2 (mkName "atan2") Copilot.atan2 stream
spec :: Spec
spec = do
mkSpecFor (Proxy @Float) "F"
mkSpecFor (Proxy @Double) "D"
triggerOp1 :: (RealFloat a, Typed a) =>
String ->
(Stream a -> Stream a) ->
Stream a ->
Spec
triggerOp1 name op stream =
trigger (name P.++ "Trigger") (testOp1 op stream) [arg stream]
triggerOp2 :: (RealFloat a, Typed a) =>
String ->
(Stream a -> Stream a -> Stream a) ->
Stream a ->
Spec
triggerOp2 name op stream =
trigger (name P.++ "Trigger") (testOp2 op stream) [arg stream]
testOp1 :: (RealFloat a, Typed a) =>
(Stream a -> Stream a) -> Stream a -> Stream Bool
testOp1 op stream =
-- NB: Use (>=) rather than (==) here, as floating-point equality gets weird
-- due to NaNs.
op stream >= op stream
testOp2 :: (RealFloat a, Typed a) =>
(Stream a -> Stream a -> Stream a) -> Stream a -> Stream Bool
testOp2 op stream =
op stream stream >= op stream stream
verifySpec :: Verbosity -> IO ()
verifySpec verb = do
spec' <- reify spec
verifyWithOptions defaultVerifierOptions{verbosity = verb}
mkDefaultCSettings [] "fpOps" spec'