co-feldspar-0.1.0.1: src/Feldspar/Software/Verify.hs
{-# language Rank2Types #-}
{-# language ScopedTypeVariables #-}
{-# language DataKinds #-}
{-# language TypeOperators #-}
{-# language TypeFamilies #-}
{-# language FlexibleInstances #-}
{-# language FlexibleContexts #-}
{-# language MultiParamTypeClasses #-}
{-# language PolyKinds #-}
{-# language GADTs #-}
{-# language ConstraintKinds #-}
{-# language GeneralizedNewtypeDeriving #-}
module Feldspar.Software.Verify where
import Feldspar.Software.Representation (Software(..), SoftwareCMD, AssertCMD, ControlCMD(..), MMapCMD)
import Feldspar.Software.Primitive (Prim, SoftwarePrimType)
import Feldspar.Software.Compile (ProgC, translate)
import Feldspar.Software.Verify.Command
import Feldspar.Software.Verify.Primitive
import Control.Monad.Trans
import qualified Feldspar.Verify.Monad as V
import qualified Feldspar.Verify.FirstOrder as FO
-- imperative-edsl.
import qualified Language.Embedded.Imperative.CMD as Imp
import qualified Language.Embedded.Backend.C as Imp
-- operational-higher.
import Control.Monad.Operational.Higher
--------------------------------------------------------------------------------
-- * Verification of Software programs.
--------------------------------------------------------------------------------
verifySoft :: Software () -> IO ()
verifySoft = verifiedSoft Imp.icompile
verifiedSoft :: (ProgC () -> IO a) -> Software () -> IO a
verifiedSoft comp prog =
do (prg, ws) <- V.runVerify $ do
lift declareFeldsparGlobals
V.verify $ translate $ prog
comp prg <* unless (null ws) (do
putStrLn "Warnings:"
sequence_ [ putStrLn ('\t' : warn) | warn <- ws])
--------------------------------------------------------------------------------
instance V.Verifiable
(Program
( Imp.RefCMD
:+: Imp.ArrCMD
:+: Imp.ControlCMD
:+: Imp.FileCMD
:+: Imp.PtrCMD
:+: Imp.C_CMD
:+: MMapCMD
)
(Param2 Prim SoftwarePrimType))
where
verifyWithResult prog = do
let inv = undefined :: [[SomeLiteral]]
(p, r) <- V.verifyWithResult (FO.defunctionalise inv prog)
return (FO.refunctionalise inv p, r)
instance V.Verifiable
(FO.Sequence
( Imp.RefCMD
:+: Imp.ArrCMD
:+: ControlCMD [[SomeLiteral]]
:+: Imp.FileCMD
:+: Imp.PtrCMD
:+: Imp.C_CMD
:+: MMapCMD
)
(Param2 Prim SoftwarePrimType))
where
verifyWithResult (FO.Val a) = return (FO.Val a, a)
verifyWithResult (FO.Seq a m k) = do
((m', breaks), warns) <- V.swallowWarns $
V.getWarns $ V.withBreaks $ V.verifyInstr m a
(_, (k', res)) <-
V.ite breaks (return ()) (V.verifyWithResult k)
let
comment msg prog = flip (FO.Seq ()) prog (inj
(Comment msg :: ControlCMD [[SomeLiteral]] (Param3
(FO.Sequence prog (Param2 Prim SoftwarePrimType))
(Prim) (SoftwarePrimType)) ()))
return (foldr comment (FO.Seq a m' k') warns, res)
--------------------------------------------------------------------------------
instance FO.Defunctionalise inv AssertCMD where refunc = error "todo: assert"
instance FO.Defunctionalise inv MMapCMD where refunc = error "todo: mmap"
instance V.VerifyInstr AssertCMD exp pred where verifyInstr = error "todo: assert"
instance V.VerifyInstr MMapCMD exp pred where verifyInstr = error "todo: mmap"
--------------------------------------------------------------------------------