{-@ LIQUID "--pruneunsorted" @-} module Elems where import Prelude hiding (elem) import Data.Set (Set (..)) {-@ append :: xs:_ -> ys:_ -> {v:_ | UnElts v xs ys} @-} append [] ys = ys append (x:xs) ys = x : append xs ys {-@ reverse :: xs:_ -> {v:_ | EqElts v xs} @-} reverse xs = revAcc xs [] where revAcc [] acc = acc revAcc (x:xs) acc = revAcc xs (x:acc) {-@ nub :: (Eq a) => xs:_ -> {v:_ | nodups v && EqElts v xs} @-} nub xs = go xs [] where go (x:xs) l | x `elem` l = go xs l | otherwise = go xs (x:l) go [] l = l {-@ elem :: (Eq a) => x:_ -> ys:_ -> {v:Bool | v <=> Set_mem x (elems ys)} @-} elem x [] = False elem x (y:ys) = x == y || elem x ys {-@ find :: (Eq a) => key:_ -> {map:_ | ValidKey key map} -> b @-} find key ((k,v):kvs) | key == k = v | otherwise = find key kvs find _ [] = die "Lookup failed!" {-@ die :: {v:String | false} -> b @-} die x = error x ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- ---------------------------------------------------------------------------- {-@ predicate ValidKey K M = Set_mem K (keys M) @-} {-@ predicate EqElts Xs Ys = elems Xs = elems Ys @-} {-@ predicate UnElts Xs Ys Zs = elems Xs = Set_cup (elems Ys) (elems Zs) @-} {-@ measure keys :: [(a, b)] -> (Set a) keys ([]) = (Set_empty 0) keys (kv:kvs) = (Set_cup (Set_sng (fst kv)) (keys kvs)) @-} {-@ measure elems :: [a] -> (Set a) elems ([]) = (Set_empty 0) elems (x:xs) = (Set_cup (Set_sng x) (elems xs)) @-} {-@ measure nodups :: [a] -> Bool nodups ([]) = true nodups (x:xs) = (not (Set_mem x (elems xs)) && nodups xs) @-}