packages feed

liquidhaskell-0.8.10.7: benchmarks/icfp15/todo/FindRec.hs

{-# Language EmptyDataDecls #-}
module FindRec where
{-@ LIQUID "--no-termination" @-}

import RIO2
import Data.Map
import Data.Set
import Language.Haskell.Liquid.Prelude 
import Privileges

{- ** API ** -}
{-@ measure caps :: World -> Map FHandle Privilege @-}
{-@ measure active :: World -> Set FHandle @-}
{-@ measure derive :: Path -> Prop @-}

data Path = P String deriving Eq
data FHandle = FH Int deriving Eq

{-@ qualif Deriv(v:World, x:FHandle): (pwrite (pcreateFilePrivs (Map_select (caps v) x))) @-}
{-@ qualif Write(v:World, x:FHandle): (pwrite (Map_select (caps v) x)) @-}
{-@ qualif List(v:World, x:FHandle): (pcontents (Map_select (caps v) x)) @-}
{-@ qualif Lkup(v:World, x:FHandle): (plookup (Map_select (caps v) x)) @-}

{-@ qualif ActiveSub(v:World, w:World): Set_sub (active v) (active w)                         @-}
{-@ qualif UpdActive(v:World,w1:World,x:FHandle): (active v) = (Set_cup (Set_sng x) (active w1)) @-}
{-@ qualif Sto(v:World,w1:World,x:FHandle,h:FHandle): (caps v) = (Map_store (caps w1) x (Map_select (caps w1) h)) @-}

{-@ qualif MpEq0(v:World,w:World,x:FHandle): (Map_select (caps v) x) = (Map_select (caps w) x) @-}
{-@ qualif MpEq0(v:World,b:FHandle,x:FHandle): (Map_select (caps v) x) = (Map_select (caps v) b) @-}

{-@ qualif Deriv(v:World,w1:World,x:FHandle,h:FHandle): (caps v) = (Map_store (caps w1) x (pcreateFilePrivs (Map_select (caps w1) h))) @-}

{-@ predicate Active W F = Set_mem F (active W) @-}
{-@ predicate HasPriv W P F = (Active W F) && (P (Map_select (caps W) F)) @-}
{-@ predicate Rd  W F = HasPriv W pread F @-}
{-@ predicate Wr  W F = HasPriv W pwrite F @-}
{-@ predicate Cr  W F = HasPriv W pcreateFile F @-}
{-@ predicate Lkup W F = HasPriv W plookup F @-}
{-@ predicate Lst W F = HasPriv W pcontents F @-}
{-@ predicate CrWO W F = (pwrite (pcreateFilePrivs (Map_select (caps W) F))) @-}
{-@ predicate CrAll W F = (pcreateFilePrivs (Map_select (caps W) F)) = (Map_select (caps W) F) @-}

{-@ predicate UpdActive W1 W2 F = (~ (Active W1 F)) && (Active W2 F) && ((active W2) = (Set_cup (Set_sng F) (active W1))) @-}
{-@ predicate UpdCaps W1 W2 X Y = (caps W2) = (Map_store (caps W1) X (Map_select (caps W1) Y)) @-}
{-@ predicate DeriveCaps W1 W2 X Y = (caps W2) = (Map_store (caps W1) X (pcreateFilePrivs (Map_select (caps W1) Y))) @-}
{-@ predicate NoChange W1 W2 = (active W1) = (active W2) && (caps W1) = (caps W2) @-}


{- ** API ** -}
{-@ contents :: 
  d:FHandle -> RIO<{v:World | Lst v d},\w1 x -> {v:World | NoChange w1 v}> [Path] 
@-}
contents :: FHandle -> RIO [Path]
contents = undefined
{-@ measure parent :: FHandle -> FHandle @-}
{-@ flookup :: 
  h:FHandle -> Path -> RIO<{v:World | Lkup v h },\w x -> {v:World | UpdActive w v x && UpdCaps w v x h }> FHandle @-}
flookup :: FHandle -> Path -> RIO FHandle
flookup = undefined
          
{-@ create :: 
  h:FHandle -> p:Path -> RIO<{v:World | Cr v h},\w1 x -> {v:World | (UpdActive w1 v x) && DeriveCaps w1 v x h}> FHandle @-}
create :: FHandle -> Path -> RIO FHandle
create = undefined          
          
{-@ createDir :: 
  h:FHandle -> p:Path -> RIO<{w:World | Cr w h},\w1 x -> {w2:World | (UpdActive w1 w2 x) && UpdCaps w1 w2 x h}> FHandle @-}
createDir :: FHandle -> Path -> RIO FHandle
createDir = undefined          

{-@ write :: 
  h:FHandle -> s:String -> RIO<{w:World | Wr w h},\w1 x -> {w2:World | NoChange w1 w2}> () @-}
write :: FHandle -> String -> RIO ()
write = undefined

{-@ fread ::
  h:FHandle -> RIO<{w:World | Rd w h},\w1 x -> {w2:World | NoChange w1 w2}> String @-}
fread :: FHandle -> RIO String
fread = undefined
        
{-@ isFile :: h:FHandle -> Bool @-}
isFile :: FHandle -> Bool
isFile = undefined

{-@ isDir :: h:FHandle -> Bool @-}
isDir :: FHandle -> Bool
isDir = undefined

{-@ 
forM_ :: forall <i :: World -> Prop>.
         [a] -> 
         (a -> RIO <i,\w1 x -> {v:World<i> | true}> b) ->
         RIO <i,\w1 x -> {v:World<i> | true}> ()          
@-}
forM_ :: [a] -> (a -> RIO b) -> RIO ()
forM_ []     _ = return ()
forM_ (x:xs) m = m x >> forM_ xs m

{-@
when :: forall <p    :: World -> Prop>.
        z:Bool ->
        RIO <p, \w1 x -> {v:World<p> | true}> () ->
        RIO <p, \w1 x -> {v:World<p> | true}> ()
@-}
when :: Bool -> RIO () -> RIO ()
when False  _ = return ()

{-@ predicate StableInv W1 W2 X Y = NoChange W1 W2 || (UpdActive W1 W2 Y && (UpdCaps W1 W2 Y X || DeriveCaps W1 W2 Y X)) @-}

-- | GOOD!!
{-@ predicate FindSpec V F = Lst V F && Lkup V F @-}

-- | BAD!!
{- predicate FindSpec V F = Active V F && Lst V F @-}

{-@
findExec ::
  forall <i :: World -> Prop, p :: FHandle -> World -> Prop, q :: FHandle -> Prop>.
  { x :: FHandle, b :: FHandle, w :: World<i> |- {v:World | StableInv w v x b } <: World<i> }
  { f :: FHandle<q> |- World<i> <: World<p f> }
  { f :: FHandle<q>, z::FHandle |- {v:World<p f> | (Active v z) && (Map_select (caps v) f) == (Map_select (caps v) z)} <: World<p z> }
  f:FHandle<q> ->
  (z:FHandle -> RIO<{v:World<p z> | true },\w x -> {v:World | NoChange w v }> ()) ->
  RIO <{v:World<i> | FindSpec v f},\w x -> {v:World<i> | FindSpec v f }> () 
@-}
findExec :: FHandle -> (FHandle -> RIO ()) -> RIO ()
findExec f cmd = do 
  when (isFile f) $ 
       (cmd f >>= return)
  when (isDir f) $ do
    cs <- contents f
    forM_ cs $ \p -> do
      h <- flookup f p
      (findExec h cmd >>= return)

{-@ qualif MpEq0(v:World,w:World,x:FHandle,z:FHandle): (Map_select (caps v) x) = (Map_select (caps w) z) @-}

-- DELETING THIS QUAL MAKES THE EXAMPLE "SAFE":
{-@ qualif ActiveEq(v:World,x:FHandle,b:FHandle): (Set_mem x (active v)) => (Set_mem b (active v)) @-}
      
{-@
  prepend :: f:FHandle -> String ->
          RIO <{v:World | Lst v f && Lkup v f && Wr v f} ,True> () @-}
prepend :: FHandle -> String -> RIO ()
prepend f s = findExec f (\f -> write f s)