packages feed

copilot-verifier-4.3: examples/Copilot/Verifier/Examples/ShouldPass/FPNegation.hs

{-# LANGUAGE NoImplicitPrelude #-}

-- | This will not succeed when 'smtFloatMode' is 'FloatUninterpreted', as Clang
-- will turn @input /= 30.0@ below into a more complicated expression that also
-- checks if @30.0@ is NaN or not. This is logically equivalent to the original
-- specification, but an SMT solver cannot conclude this when all of the
-- floating-point operations involved are treated as uninterpreted functions.
--
-- To make this work, we set 'smtFloatMode' to 'FloatIEEE' instead. This works
-- because all of the floating-point operations in the specification below are
-- native to SMT-LIB.
module Copilot.Verifier.Examples.ShouldPass.FPNegation where

import Copilot.Compile.C99 (mkDefaultCSettings)
import Copilot.Verifier ( Verbosity, VerifierOptions(..)
                        , defaultVerifierOptions, verifyWithOptions )
import Copilot.Verifier.FloatMode (FloatMode(..))
import qualified Copilot.Library.PTLTL as PTLTL
import Language.Copilot

input :: Stream Float
input = extern "input" Nothing

-- | MyProperty
--   @
--   Input is never 30.0
--   @
propMyProperty :: Stream Bool
propMyProperty = PTLTL.alwaysBeen (input /= 30.0)

-- | Clock that increases in one-unit steps.
clock :: Stream Int64
clock = [0] ++ (clock + 1)

-- | First Time Point
ftp :: Stream Bool
ftp = [True] ++ false

pre :: Stream Bool -> Stream Bool
pre = ([False] ++)

tpre :: Stream Bool -> Stream Bool
tpre = ([True] ++)

notPreviousNot :: Stream Bool -> Stream Bool
notPreviousNot = not . PTLTL.previous . not

-- | Complete specification. Calls C handler functions when properties are
-- violated.
spec :: Spec
spec = do
  trigger "handlerMyProperty" (not propMyProperty) []

verifySpec :: Verbosity -> IO ()
verifySpec verb = do
  spec' <- reify spec
  verifyWithOptions
    (defaultVerifierOptions
      { verbosity = verb
      , smtFloatMode = FloatIEEE
      })
    mkDefaultCSettings [] "fpNegation" spec'