|
| 1 | +{-@ LIQUID "--ple" @-} |
| 2 | +-- | Tests that we can unfold reflected functions in the solutions |
| 3 | +-- of KVars. |
| 4 | +-- |
| 5 | +-- https://github.com/ucsd-progsys/liquid-fixpoint/issues/780 |
| 6 | +-- |
| 7 | +module TestLF780 where |
| 8 | + |
| 9 | +import Data.Set as Set |
| 10 | + |
| 11 | +{-@ data State s a <p :: s -> Bool, q :: s -> a -> s -> Bool> |
| 12 | + = State (x:s<p> -> (a, s)<\w -> {v:s<q x w> | true}>) |
| 13 | + @-} |
| 14 | +data State s a = State {runState :: s -> (a, s)} |
| 15 | + |
| 16 | +{-@ runState :: forall <p :: s -> Bool, q :: s -> a -> s -> Bool>. |
| 17 | + State <p, q> s a -> x:s<p> -> (a, s)<\w -> {v:s<q x w> | true}> @-} |
| 18 | + |
| 19 | +instance Functor (State s) where |
| 20 | +{-@ |
| 21 | +instance Functor (State s) where |
| 22 | + fmap :: forall < p :: s -> Bool |
| 23 | + , q :: s -> a -> s -> Bool |
| 24 | + , q2 :: s -> a -> s -> Bool |
| 25 | + , pa :: a -> Bool |
| 26 | + , pb :: b -> Bool |
| 27 | + >. |
| 28 | + {x::a<pa>, s0::s<p>, y::b<pb> |- s<q s0 x> <: s<q2 s0 y>} |
| 29 | + (a<pa> -> b<pb>) |
| 30 | + -> State <p, q> s a<pa> |
| 31 | + -> State <p, q2> s b<pb> |
| 32 | +@-} |
| 33 | + fmap f x = State $ \s -> let (y, s') = runState x s in (f y, s') |
| 34 | + |
| 35 | +instance Applicative (State s) where |
| 36 | +{-@ |
| 37 | +instance Applicative (State s) where |
| 38 | + pure :: forall <p :: s -> Bool>. |
| 39 | + x:a -> State <p, \w0 y -> {w1:s<p> | w0 == w1 && y == x}> s a |
| 40 | +@-} |
| 41 | + pure x = State $ \s -> (x, s) |
| 42 | + mf <*> mx = State $ \s -> |
| 43 | + let (f, s1) = runState mf s |
| 44 | + (x, s2) = runState mx s1 |
| 45 | + in (f x, s2) |
| 46 | + |
| 47 | +instance Monad (State s) where |
| 48 | +{-@ |
| 49 | +instance Monad (State s) where |
| 50 | + >>= :: forall < p :: s -> Bool |
| 51 | + , p2 :: a -> s -> Bool |
| 52 | + , r :: a -> Bool |
| 53 | + , q1 :: s -> a -> s -> Bool |
| 54 | + , q2 :: a -> s -> b -> s -> Bool |
| 55 | + , q :: s -> b -> s -> Bool>. |
| 56 | + {x::a<r>, w::s<p>|- s<q1 w x> <: s<p2 x>} |
| 57 | + {w::s<p>, x::a, w1::s<q1 w x>, y::b |- s<q2 x w1 y> <: s<q w y>} |
| 58 | + {x::a, w::s, w2::s<q1 w x>|- {v:a | v = x} <: a<r>} |
| 59 | + State <p, q1> s a |
| 60 | + -> (x:a<r> -> State <{v:s<p2 x> | true}, \w1 y -> {v:s<q2 x w1 y> | true}> s b) |
| 61 | + -> State <p, q> s b ; |
| 62 | + >> :: forall < p :: s -> Bool |
| 63 | + , p2 :: s -> Bool |
| 64 | + , q1 :: s -> a -> s -> Bool |
| 65 | + , q2 :: s -> b -> s -> Bool |
| 66 | + , q :: s -> b -> s -> Bool>. |
| 67 | + {x::a, w::s<p>|- s<q1 w x> <: s<p2>} |
| 68 | + {w::s<p>, w2::s<p2>, x::b, y::a |- s<q2 w2 x> <: s<q w x>} |
| 69 | + State <p, q1> s a |
| 70 | + -> State <p2, q2> s b |
| 71 | + -> State <p, q> s b ; |
| 72 | + return :: forall <p :: s -> Bool>. |
| 73 | + x:a -> State <p, \w0 y -> {w1:s<p> | w0 == w1 && y == x}> s a |
| 74 | +@-} |
| 75 | + (State g) >>= f = State $ \x -> case g x of {(y, s) -> (runState (f y)) s} |
| 76 | + |
| 77 | + (State g) >> f = State $ \x -> case g x of {(y, s) -> (runState f ) s} |
| 78 | + |
| 79 | + return w = State $ \s -> (w, s) |
| 80 | + |
| 81 | + |
| 82 | +{-@ |
| 83 | +get :: forall <p :: s -> Bool>. |
| 84 | + State <p, {\s0 v s -> v = s && s = s0}> s s<p> |
| 85 | +@-} |
| 86 | +get :: State s s |
| 87 | +get = State $ \s -> (s, s) |
| 88 | + |
| 89 | +{-@ |
| 90 | +put :: forall <p :: s -> Bool>. |
| 91 | + s0:s -> State <p, {\_ v s -> s = s0}> s () |
| 92 | +@-} |
| 93 | +put :: s -> State s () |
| 94 | +put s = State $ \_ -> ((), s) |
| 95 | + |
| 96 | +{-@ reflect gt0 @-} |
| 97 | +gt0 :: Int -> Bool |
| 98 | +gt0 x = x > 0 |
| 99 | + |
| 100 | +{-@ |
| 101 | +stFun |
| 102 | + :: i:Int |
| 103 | + -> State |
| 104 | + <{\m0 -> gt0 i } |
| 105 | + , {\m0 v m -> v > 0 }> |
| 106 | + _ _ |
| 107 | +@-} |
| 108 | +stFun :: Int -> State Int Int |
| 109 | +stFun i = do |
| 110 | + put i |
| 111 | + get |
0 commit comments