Skip to content

Commit

Permalink
Add example demonstrating struct update support. Refs #57.
Browse files Browse the repository at this point in the history
This is adapted from a similar example in the upstream `copilot` repo.
  • Loading branch information
RyanGlScott committed Sep 9, 2024
1 parent bdae7f3 commit 1d0ab9c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 0 deletions.
1 change: 1 addition & 0 deletions copilot-verifier/copilot-verifier.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ library copilot-verifier-examples
Copilot.Verifier.Examples.ShouldPass.Partial.SubSignedWrap
Copilot.Verifier.Examples.ShouldPass.Structs
Copilot.Verifier.Examples.ShouldPass.UpdateArray
Copilot.Verifier.Examples.ShouldPass.UpdateStruct
Copilot.Verifier.Examples.ShouldPass.Voting
Copilot.Verifier.Examples.ShouldPass.WCV

Expand Down
2 changes: 2 additions & 0 deletions copilot-verifier/examples/Copilot/Verifier/Examples.hs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import qualified Copilot.Verifier.Examples.ShouldPass.Partial.ShiftRTooLarge a
import qualified Copilot.Verifier.Examples.ShouldPass.Partial.SubSignedWrap as Pass.SubSignedWrap
import qualified Copilot.Verifier.Examples.ShouldPass.Structs as Structs
import qualified Copilot.Verifier.Examples.ShouldPass.UpdateArray as UpdateArray
import qualified Copilot.Verifier.Examples.ShouldPass.UpdateStruct as UpdateStruct
import qualified Copilot.Verifier.Examples.ShouldPass.Voting as Voting
import qualified Copilot.Verifier.Examples.ShouldPass.WCV as WCV

Expand Down Expand Up @@ -74,6 +75,7 @@ shouldPassExamples verb = Map.fromList
, example "IntOps" (IntOps.verifySpec verb)
, example "Structs" (Structs.verifySpec verb)
, example "UpdateArray" (UpdateArray.verifySpec verb)
, example "UpdateStruct" (UpdateStruct.verifySpec verb)
, example "Voting" (Voting.verifySpec verb)
, example "WCV" (WCV.verifySpec verb)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE DataKinds #-}

-- | An example showing of using @copilot-verifier@ to verify a specification
-- involving structs where individual fields are updated.
module Copilot.Verifier.Examples.ShouldPass.UpdateStruct where

import Language.Copilot
import Copilot.Compile.C99
import Copilot.Verifier ( Verbosity, VerifierOptions(..)
, defaultVerifierOptions, verifyWithOptions )

-- | Definition for `Volts`.
data Volts = Volts
{ numVolts :: Field "numVolts" Word32
, flag :: Field "flag" Bool
}

-- | `Struct` instance for `Volts`.
instance Struct Volts where
typeName _ = "volts"
toValues vlts = [ Value Word32 (numVolts vlts)
, Value Bool (flag vlts)
]

-- | `Volts` instance for `Typed`.
instance Typed Volts where
typeOf = Struct (Volts (Field 0) (Field False))

data Battery = Battery
{ temp :: Field "temp" Word32
, volts :: Field "volts" (Array 10 Volts)
, other :: Field "other" (Array 10 (Array 5 Word32))
}

-- | `Battery` instance for `Struct`.
instance Struct Battery where
typeName _ = "battery"
toValues battery = [ Value typeOf (temp battery)
, Value typeOf (volts battery)
, Value typeOf (other battery)
]

-- | `Battery` instance for `Typed`. Note that `undefined` is used as an
-- argument to `Field`. This argument is never used, so `undefined` will never
-- throw an error.
instance Typed Battery where
typeOf = Struct (Battery (Field 0) (Field undefined) (Field undefined))

spec :: Spec
spec = do
let battery :: Stream Battery
battery = extern "battery" Nothing

-- Update a struct field, then check it for equality.
trigger "updateTrig"
((battery ## temp =$ (+1))#temp == (battery#temp + 1))
[arg battery]

verifySpec :: Verbosity -> IO ()
verifySpec verb = reify spec >>= verifyWithOptions defaultVerifierOptions{verbosity = verb}
mkDefaultCSettings [] "updateStruct"

0 comments on commit 1d0ab9c

Please sign in to comment.