-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add example demonstrating struct update support. Refs #57.
This is adapted from a similar example in the upstream `copilot` repo.
- Loading branch information
1 parent
bdae7f3
commit 1d0ab9c
Showing
3 changed files
with
65 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
62 changes: 62 additions & 0 deletions
62
copilot-verifier/examples/Copilot/Verifier/Examples/ShouldPass/UpdateStruct.hs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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" |