packages feed

liquidhaskell-0.9.0.2.1: tests/neg/T1814.hs

{-@ LIQUID "--expect-any-error" @-}
{-@ LIQUID "--reflection" @-}
{-@ LIQUID "--ple"        @-}

module T1814 where

import qualified Data.Set as S 

type Acc = Int 
type Reg = Int 
type Config = (Acc, Mem Reg) 

data Code 
  = Add   Reg Code 
  | Halt 

{-@ exec :: c:Code -> (a::Acc, {m:Mem Int | validMem m c a}) -> Config @-}
exec :: Code -> Config -> Config
exec (Add r c)   (a,m) = exec c (a + get r m ,m) 
exec Halt        (a,m) = (a,m) 


{-@ reflect validMem @-}
validMem :: Mem Int -> Code -> Acc -> Bool 
validMem m (Add r c) a = if S.member r (memAddrs m) then validMem m c (a + get r m) else False
validMem m _ a = True 


{-@ type ValidCode = {c:Code | validMem MEmp c 0 } @-}
{-@ code :: ValidCode  @-} 
code :: Code 
code =  Add 42 Halt


{-@ reflect get   @-}



data Mem v = MEmp | MCons Int v (Mem v)

{-@ measure memAddrs @-}
memAddrs :: Mem v -> S.Set Int
memAddrs MEmp                 = S.empty
memAddrs (MCons addr val mem) = S.union (S.singleton addr) (memAddrs mem)

{-@ get :: addr : Int -> { mem : Mem v | S.member addr (memAddrs mem) } -> v @-}
get :: Int -> Mem v -> v
get addr (MCons addr' val' mem)
  | addr == addr' = val'
  | otherwise     = get addr mem