sbvPlugin 0.4 → 0.5
raw patch · 53 files changed
+423/−505 lines, 53 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Data.SBV.Plugin.Examples.BitTricks: conditionalSetClearCorrect :: Bool -> Word32 -> Word32 -> Bool
+ Data.SBV.Plugin.Examples.BitTricks: fastMaxCorrect :: Int -> Int -> Bool
+ Data.SBV.Plugin.Examples.BitTricks: fastMinCorrect :: Int -> Int -> Bool
+ Data.SBV.Plugin.Examples.BitTricks: oneIf :: Num a => Bool -> a
+ Data.SBV.Plugin.Examples.BitTricks: oppositeSignsCorrect :: Int -> Int -> Bool
+ Data.SBV.Plugin.Examples.BitTricks: powerOfTwoCorrect :: Word32 -> Bool
+ Data.SBV.Plugin.Examples.MergeSort: isPermutationOf :: Eq a => [a] -> [a] -> Bool
+ Data.SBV.Plugin.Examples.MergeSort: merge :: Ord a => [a] -> [a] -> [a]
+ Data.SBV.Plugin.Examples.MergeSort: mergeSort :: Ord a => [a] -> [a]
+ Data.SBV.Plugin.Examples.MergeSort: mergeSortCorrect :: [Int] -> Bool
+ Data.SBV.Plugin.Examples.MergeSort: nonDecreasing :: Ord a => [a] -> Bool
Files
- CHANGES.md +9/−1
- Data/SBV/Plugin/Analyze.hs +165/−105
- Data/SBV/Plugin/Common.hs +38/−12
- Data/SBV/Plugin/Env.hs +29/−2
- Data/SBV/Plugin/Examples/BitTricks.hs +73/−0
- Data/SBV/Plugin/Examples/MergeSort.hs +101/−0
- Data/SBV/Plugin/Plugin.hs +5/−4
- sbvPlugin.cabal +3/−2
- tests/GoldFiles/T00.hs.golden +0/−8
- tests/GoldFiles/T01.hs.golden +0/−7
- tests/GoldFiles/T02.hs.golden +0/−5
- tests/GoldFiles/T03.hs.golden +0/−3
- tests/GoldFiles/T04.hs.golden +0/−3
- tests/GoldFiles/T05.hs.golden +0/−5
- tests/GoldFiles/T06.hs.golden +0/−5
- tests/GoldFiles/T07.hs.golden +0/−5
- tests/GoldFiles/T08.hs.golden +0/−5
- tests/GoldFiles/T09.hs.golden +0/−3
- tests/GoldFiles/T10.hs.golden +0/−3
- tests/GoldFiles/T11.hs.golden +0/−5
- tests/GoldFiles/T12.hs.golden +0/−6
- tests/GoldFiles/T13.hs.golden +0/−7
- tests/GoldFiles/T14.hs.golden +0/−5
- tests/GoldFiles/T15.hs.golden +0/−3
- tests/GoldFiles/T16.hs.golden +0/−7
- tests/GoldFiles/T17.hs.golden +0/−7
- tests/GoldFiles/T18.hs.golden +0/−59
- tests/GoldFiles/T19.hs.golden +0/−14
- tests/GoldFiles/T20.hs.golden +0/−1
- tests/GoldFiles/T21.hs.golden +0/−36
- tests/GoldFiles/T22.hs.golden +0/−5
- tests/GoldFiles/T23.hs.golden +0/−3
- tests/GoldFiles/T24.hs.golden +0/−3
- tests/GoldFiles/T25.hs.golden +0/−3
- tests/GoldFiles/T26.hs.golden +0/−4
- tests/GoldFiles/T27.hs.golden +0/−29
- tests/GoldFiles/T28.hs.golden +0/−3
- tests/GoldFiles/T29.hs.golden +0/−4
- tests/GoldFiles/T30.hs.golden +0/−3
- tests/GoldFiles/T31.hs.golden +0/−19
- tests/GoldFiles/T32.hs.golden +0/−7
- tests/GoldFiles/T33.hs.golden +0/−7
- tests/GoldFiles/T34.hs.golden +0/−3
- tests/GoldFiles/T35.hs.golden +0/−6
- tests/GoldFiles/T36.hs.golden +0/−9
- tests/GoldFiles/T37.hs.golden +0/−6
- tests/GoldFiles/T38.hs.golden +0/−7
- tests/GoldFiles/T39.hs.golden +0/−6
- tests/GoldFiles/T40.hs.golden +0/−3
- tests/GoldFiles/T41.hs.golden +0/−8
- tests/GoldFiles/T42.hs.golden +0/−9
- tests/GoldFiles/T43.hs.golden +0/−21
- tests/GoldFiles/T44.hs.golden +0/−9
CHANGES.md view
@@ -1,7 +1,15 @@ * Hackage: <http://hackage.haskell.org/package/sbvPlugin> * GitHub: <http://github.com/LeventErkok/sbvPlugin> -* Latest Hackage released version: 0.4, 2015-12-24+* Latest Hackage released version: 0.5, 2015-12-26++### Version 0.5, 2015-12-26+ + * Allow higher-order (i.e., function) arguments to theorems.+ * Rework uninterpreted functions, generalize types+ * Simplify cabal file; no need to ship gold-files for tests+ * Add merge-sort example "Data/SBV/Plugin/Examples/MergeSort.hs"+ * Add bit-tricks example "Data/SBV/Plugin/Examples/BitTricks.hs" ### Version 0.4, 2015-12-24
Data/SBV/Plugin/Analyze.hs view
@@ -44,16 +44,18 @@ bind (b, e) = mapM_ work (sbvAnnotation b) where work (SBV opts)- | Just s <- hasSkip opts = liftIO $ putStrLn $ "[SBV] " ++ showSpan cfg b topLoc ++ " Skipping " ++ show (showSDoc (flags cfgEnv) (ppr b)) ++ ": " ++ s- | Uninterpret `elem` opts = return ()- | True = liftIO $ prove cfg opts b topLoc e+ | Just s <- hasSkip opts + = liftIO $ putStrLn $ "[SBV] " ++ showSpan cfg (pickSpan [varSpan b]) ++ " Skipping " ++ show (showSDoc (flags cfgEnv) (ppr b)) ++ ": " ++ s+ | Uninterpret `elem` opts+ = return ()+ | True+ = liftIO $ prove cfg opts b e hasSkip opts = listToMaybe [s | Skip s <- opts]- topLoc = bindSpan b -- | Prove an SBVTheorem-prove :: Config -> [SBVOption] -> Var -> SrcSpan -> CoreExpr -> IO ()-prove cfg@Config{isGHCi} opts b topLoc e = do- success <- safely $ proveIt cfg opts (topLoc, b) e+prove :: Config -> [SBVOption] -> Var -> CoreExpr -> IO ()+prove cfg@Config{isGHCi} opts b e = do+ success <- safely $ proveIt cfg opts b e unless (success || isGHCi || IgnoreFailure `elem` opts) $ do putStrLn $ "[SBV] Failed. (Use option '" ++ show IgnoreFailure ++ "' to continue.)" exitFailure@@ -65,16 +67,24 @@ bad e = do print e return False +-- | Sometimes life is hard. Giving up is an option.+die :: Config -> [SrcSpan] -> String -> [String] -> a+die cfg locs w es = error $ concatMap ("\n" ++) $ tag ("Skipping proof. " ++ w ++ ":") : map tab es+ where marker = "[SBV] " ++ showSpan cfg (pickSpan locs)+ tag s = marker ++ " " ++ s+ tab s = replicate (length marker) ' ' ++ " " ++ s+ -- | Returns True if proof went thru-proveIt :: Config -> [SBVOption] -> (SrcSpan, Var) -> CoreExpr -> IO Bool-proveIt cfg@Config{cfgEnv, sbvAnnotation} opts (topLoc, topBind) topExpr = do+proveIt :: Config -> [SBVOption] -> Var -> CoreExpr -> IO Bool+proveIt cfg@Config{cfgEnv, sbvAnnotation} opts topBind topExpr = do solverConfigs <- pickSolvers opts let verbose = Verbose `elem` opts qCheck = QuickCheck `elem` opts runProver prop | qCheck = Left `fmap` S.svQuickCheck prop | True = Right `fmap` S.proveWithAny [s{S.verbose = verbose} | s <- solverConfigs] prop- loc = "[SBV] " ++ showSpan cfg topBind topLoc+ topLoc = varSpan topBind+ loc = "[SBV] " ++ showSpan cfg topLoc slvrTag = ", using " ++ tag ++ "." where tag = case solverConfigs of [] -> "no solvers" -- can't really happen@@ -83,7 +93,7 @@ xs -> intercalate ", " (map show (init xs)) ++ ", and " ++ show (last xs) putStrLn $ "\n" ++ loc ++ (if qCheck then " QuickChecking " else " Proving ") ++ show (sh topBind) ++ slvrTag (finalResult, finalUninterps) <- do- finalResult <- runProver (res cfgEnv)+ finalResult <- runProver (res cfgEnv topLoc) finalUninterps <- readIORef (rUninterpreted cfgEnv) return (finalResult, finalUninterps) case finalResult of@@ -97,8 +107,8 @@ putStr $ "[" ++ show solver ++ "] " print sres - -- If proof failed and there are uninterpreted values, print a warning; except for "uninteresting" types- let unintVals = filter ((`notElem` uninteresting cfgEnv) . snd) $ nub $ sortBy (comparing fst) [vt | (vt, _) <- finalUninterps]+ -- If proof failed and there are uninterpreted non-input values, print a warning; except for "uninteresting" types+ let unintVals = filter ((`notElem` uninteresting cfgEnv) . snd) $ nub $ sortBy (comparing fst) [vt | (vt, (False, _, _)) <- finalUninterps] unless (success || null unintVals) $ do let plu | length finalUninterps > 1 = "s:" | True = ":"@@ -116,21 +126,17 @@ where debug = Debug `elem` opts - res initEnv = do- v <- runReaderT (symEval topExpr) initEnv{curLoc = topLoc}+ res initEnv topLoc = do+ v <- runReaderT (symEval topExpr) initEnv { curLoc = [topLoc]+ , mbListSize = listToMaybe [n | ListSize n <- opts]+ } case v of Base r -> return r r -> error $ "Impossible happened. Final result reduced to a non-base value: " ++ showSDocUnsafe (ppr r) - die :: SrcSpan -> String -> [String] -> a- die loc w es = error $ concatMap ("\n" ++) $ tag ("Skipping proof. " ++ w ++ ":") : map tab es- where marker = "[SBV] " ++ showSpan cfg topBind loc- tag s = marker ++ " " ++ s- tab s = replicate (length marker) ' ' ++ " " ++ s- tbd :: String -> [String] -> Eval Val tbd w ws = do Env{curLoc} <- ask- die curLoc w ws+ die cfg curLoc w ws sh o = showSDoc (flags cfgEnv) (ppr o) @@ -140,8 +146,7 @@ symEval :: CoreExpr -> Eval Val symEval e = do let (bs, body) = collectBinders (pushLetLambda e) Env{curLoc} <- ask- let mbListSize = listToMaybe [n | ListSize n <- opts]- bodyType <- getType curLoc (exprType body)+ bodyType <- getType (pickSpan curLoc) (exprType body) -- Figure out if there were some unmentioned variables; happens if the top -- level wasn't fully saturated.@@ -152,22 +157,22 @@ case finalType of KBase S.KBool -> do -- First collect the named arguments: argKs <- mapM (\b -> getType (getSrcSpan b) (varType b) >>= \bt -> return (b, bt)) bs- let mkVar ((b, k), mbN) = do sv <- mkSym mbListSize curLoc (Just (idType b)) k (mbN `mplus` Just (sh b))+ let mkVar ((b, k), mbN) = do sv <- mkSym cfg (Just b) (varSpan b) (Just (idType b)) k (mbN `mplus` Just (sh b)) return ((b, k), sv)- bArgs <- mapM (lift . mkVar) (zip argKs (concat [map Just ns | Names ns <- opts] ++ repeat Nothing))+ bArgs <- mapM mkVar (zip argKs (concat [map Just ns | Names ns <- opts] ++ repeat Nothing)) -- Go ahead and run the body symbolically; on bArgs bRes <- local (\env -> env{envMap = foldr (uncurry M.insert) (envMap env) bArgs}) (go body) -- If there are extraArgs; then create symbolics and apply to the result: let feed [] sres = return sres- feed (k:ks) (Func _ f) = do sv <- lift $ mkSym mbListSize curLoc Nothing k Nothing+ feed (k:ks) (Func _ f) = do sv <- mkSym cfg Nothing (pickSpan curLoc) Nothing k Nothing f sv >>= feed ks feed ks v = error $ "Impossible! Left with extra args to apply on a non-function: " ++ sh (ks, v) feed extraArgs bRes - _ -> die curLoc "Non-boolean property declaration" (concat [ ["Found : " ++ sh (exprType e)]+ _ -> die cfg curLoc "Non-boolean property declaration" (concat [ ["Found : " ++ sh (exprType e)] , ["Returning: " ++ sh (exprType body) | not (null bs)] , ["Expected : Bool" ++ if null bs then "" else " result"] ])@@ -175,39 +180,11 @@ pushLetLambda (Let b (Lam x bd)) = Lam x (pushLetLambda (Let b bd)) pushLetLambda o = o - -- Create a symbolic variable:- mkSym :: Maybe Int -> SrcSpan -> Maybe Type -> SKind -> Maybe String -> S.Symbolic Val- mkSym mbLs curLoc mbBType = sym- where tinfo k = case mbBType of- Nothing -> "Kind: " ++ sh k- Just t -> "Type: " ++ sh t-- sym (KBase k) nm = do v <- S.svMkSymVar Nothing k nm- return (Base v)-- sym (KTup ks) nm = do let ns = map (\i -> (++ ("_" ++ show i)) `fmap` nm) [1 .. length ks]- vs <- zipWithM sym ks ns- return $ Tup vs-- sym (KLst ks) nm = do let ls = fromMaybe bad mbLs- bad = die curLoc "List-argument found, with no size info"- [ "Name: " ++ fromMaybe "anonymous" nm- , tinfo (KLst ks)- , "Hint: Use the \"ListSize\" annotation"- ]- ns = map (\i -> (++ ("_" ++ show i)) `fmap` nm) [1 .. ls]- vs <- zipWithM sym (replicate ls ks) ns- return (Lst vs)-- sym k nm = die curLoc "Unsupported symbolic input" [ "Name: " ++ show nm- , tinfo k- ]- isUninterpretedBinding :: Var -> Bool isUninterpretedBinding v = any (Uninterpret `elem`) [opt | SBV opt <- sbvAnnotation v] go :: CoreExpr -> Eval Val- go (Tick t e) = local (\envMap -> envMap{curLoc = tickSpan t (curLoc envMap)}) $ go e+ go (Tick t e) = local (\envMap -> envMap{curLoc = tickSpan t : curLoc envMap}) $ go e go e = tgo (exprType e) e debugTrace s w@@ -224,11 +201,11 @@ case (v, k) `M.lookup` envMap of Just b -> return b Nothing -> case v `M.lookup` coreMap of- Just b -> if isUninterpretedBinding v- then uninterpret t v- else go b- Nothing -> debugTrace ("Uninterpreting: " ++ sh (v, k, nub $ sort $ map (fst . fst) (M.toList envMap)))- $ uninterpret t v+ Just (l, b) -> if isUninterpretedBinding v+ then uninterpret cfg False t v+ else local (\env -> env{curLoc = l : curLoc env}) $ go b+ Nothing -> debugTrace ("Uninterpreting: " ++ sh (v, k, nub $ sort $ map (fst . fst) (M.toList envMap)))+ $ uninterpret cfg False t v tgo t e@(Lit l) = do Env{machWordSize} <- ask case l of@@ -259,15 +236,21 @@ Env{specials} <- ask -- handle specials: Equality, tuples, and lists- let isEq (App (App (Var v) (Type _)) dict) | isReallyADictionary dict, Just f <- isEquality specials v = Just f- isEq _ = Nothing+ let getVar (Var v) = Just v+ getVar (Tick _ e) = getVar e+ getVar _ = Nothing + isEq (App (App ev (Type _)) dict) | Just v <- getVar ev, isReallyADictionary dict, Just f <- isEquality specials v = Just f+ isEq _ = Nothing+ isTup (Var v) = isTuple specials v isTup (App f (Type _)) = isTup f+ isTup (Tick _ e) = isTup e isTup _ = Nothing isLst (Var v) = isList specials v isLst (App f (Type _)) = isLst f+ isLst (Tick _ e) = isLst e isLst _ = Nothing isSpecial e = isEq e `mplus` isTup e `mplus` isLst e@@ -275,6 +258,23 @@ case isSpecial reduced of Just f -> debugTrace ("Special located: " ++ sh (orig, f)) $ return f Nothing -> case reduced of++ -- special case for split and join; there must be a better way to do this+ App (App (App (Var v) (Type t1)) (Type t2)) dict | isReallyADictionary dict -> do+ Env{envMap} <- ask+ let vSpan = getSrcSpan v+ k1 <- getType vSpan t1+ k2 <- getType vSpan t2+ let kSplit = KFun k1 (KTup [k2, k2])+ kJoin = KFun k1 (KFun k1 k2)+ case ((v, kSplit) `M.lookup` envMap, (v, kJoin) `M.lookup` envMap) of+ (Just b, _) -> debugTrace ("Located split: " ++ sh (reduced, kSplit)) $ return b+ (_, Just b) -> debugTrace ("Located join: " ++ sh (reduced, kJoin)) $ return b+ _ -> do Env{coreMap} <- ask+ case v `M.lookup` coreMap of+ Just (l, e) -> local (\env -> env{curLoc = l : curLoc env}) $ tgo tFun (App (App (App e (Type t1)) (Type t2)) dict)+ Nothing -> tgo tFun (Var v)+ App (App (Var v) (Type t)) dict | isReallyADictionary dict -> do Env{envMap} <- ask k <- getType (getSrcSpan v) t@@ -282,14 +282,14 @@ Just b -> return b Nothing -> do Env{coreMap} <- ask case v `M.lookup` coreMap of- Just e -> tgo tFun (App (App e (Type t)) dict)- Nothing -> tgo tFun (Var v)+ Just (l, e) -> local (\env -> env{curLoc = l : curLoc env}) $ tgo tFun (App (App e (Type t)) dict)+ Nothing -> tgo tFun (Var v) App (Var v) (Type t) -> do Env{coreMap} <- ask case v `M.lookup` coreMap of- Just e -> tgo tFun (App e (Type t))- Nothing -> tgo tFun (Var v)+ Just (l, e) -> local (\env -> env{curLoc = l : curLoc env}) $ tgo tFun (App e (Type t))+ Nothing -> tgo tFun (Var v) App (Let (Rec bs) f) a -> go (Let (Rec bs) (App f a)) @@ -307,35 +307,38 @@ Env{envMap} <- ask return $ Func (Just (sh b)) $ \s -> local (\env -> env{envMap = M.insert (b, k) s envMap}) (go body) - tgo _ (Let (NonRec b e) body) = local (\env -> env{coreMap = M.insert b e (coreMap env)}) (go body)+ tgo _ (Let (NonRec b e) body) = local (\env -> env{coreMap = M.insert b (varSpan b, e) (coreMap env)}) (go body) - tgo _ (Let (Rec bs) body) = local (\env -> env{coreMap = foldr (uncurry M.insert) (coreMap env) bs}) (go body)+ tgo _ (Let (Rec bs) body) = local (\env -> env{coreMap = foldr (\(b, e) m -> M.insert b (varSpan b, e) m) (coreMap env) bs}) (go body) -- Case expressions. We take advantage of the core-invariant that each case alternative -- is exhaustive; and DEFAULT (if present) is the first alternative. We turn it into a -- simple if-then-else chain with the last element on the DEFAULT, or whatever comes last. tgo _ e@(Case ce caseBinder caseType alts) = do sce <- go ce- Env{curLoc} <- ask- let caseTooComplicated l w [] = die l ("Unsupported case-expression (" ++ w ++ ")") [sh e]- caseTooComplicated l w xs = die l ("Unsupported case-expression (" ++ w ++ ")") $ [sh e, "While Analyzing:"] ++ xs+ let caseTooComplicated l w [] = die cfg l ("Unsupported case-expression (" ++ w ++ ")") [sh e]+ caseTooComplicated l w xs = die cfg l ("Unsupported case-expression (" ++ w ++ ")") $ [sh e, "While Analyzing:"] ++ xs isDefault (DEFAULT, _, _) = True isDefault _ = False (defs, nonDefs) = partition isDefault alts walk ((p, bs, rhs) : rest) = do -- try to get a "good" location for this alternative, if possible: let eLoc = case (rhs, bs) of- (Tick t _, _ ) -> tickSpan t curLoc- (_, b:_) -> bindSpan b- _ -> curLoc+ (Tick t _, _ ) -> tickSpan t+ (Var v, _ ) -> varSpan v+ (_, b:_) -> varSpan b+ _ -> varSpan caseBinder mr <- match eLoc sce p bs case mr of- Just (m, bs') -> do let result = local (\env -> env{envMap = foldr (uncurry M.insert) (envMap env) bs'}) $ go rhs+ Just (m, bs') -> do let result = local (\env -> env{curLoc = eLoc : curLoc env, envMap = foldr (uncurry M.insert) (envMap env) bs'}) $ go rhs if null rest then result- else choose (caseTooComplicated eLoc "with-complicated-alternatives-during-merging") m result (walk rest)- Nothing -> caseTooComplicated eLoc "with-complicated-match" ["MATCH " ++ sh (ce, p), " --> " ++ sh rhs]- walk [] = caseTooComplicated curLoc "with-non-exhaustive-match" [] -- can't really happen+ else do Env{curLoc} <- ask+ choose (caseTooComplicated (eLoc : curLoc) "with-complicated-alternatives-during-merging") m result (walk rest)+ Nothing -> do Env{curLoc} <- ask+ caseTooComplicated (eLoc : curLoc) "with-complicated-match" ["MATCH " ++ sh (ce, p), " --> " ++ sh rhs]+ walk [] = do Env{curLoc} <- ask+ caseTooComplicated curLoc "with-non-exhaustive-match" [] -- can't really happen k <- getType (getSrcSpan caseBinder) caseType local (\env -> env{envMap = M.insert (caseBinder, k) sce (envMap env)}) $ walk (nonDefs ++ defs) where choose bailOut t tb fb = case S.svAsBool t of@@ -363,11 +366,11 @@ tgo t (Cast e c) = debugTrace ("Going thru a Cast: " ++ sh c) $ tgo t e - tgo _ (Tick t e) = local (\envMap -> envMap{curLoc = tickSpan t (curLoc envMap)}) $ go e+ tgo _ (Tick t e) = local (\envMap -> envMap{curLoc = tickSpan t : curLoc envMap}) $ go e tgo _ (Type t) = do Env{curLoc} <- ask- k <- getType curLoc t+ k <- getType (pickSpan curLoc) t return (Typ k) tgo _ e@Coercion{}@@ -384,8 +387,8 @@ else do let chaseVars :: CoreExpr -> Eval CoreExpr chaseVars (Var x) = do Env{coreMap} <- ask case x `M.lookup` coreMap of- Nothing -> return (Var x)- Just b -> chaseVars b+ Nothing -> return (Var x)+ Just (_, b) -> chaseVars b chaseVars (Tick _ x) = chaseVars x chaseVars x = return x func <- chaseVars rf@@ -405,29 +408,86 @@ isReallyADictionary (Var v) = "$" `isPrefixOf` unpackFS (occNameFS (occName (varName v))) isReallyADictionary _ = False +-- Create a symbolic variable.+mkSym :: Config -> Maybe Var -> SrcSpan -> Maybe Type -> SKind -> Maybe String -> Eval Val+mkSym cfg@Config{cfgEnv} mbBind curLoc mbBType = sym+ where sh o = showSDoc (flags cfgEnv) (ppr o)++ tinfo k = case mbBType of+ Nothing -> "Kind: " ++ sh k+ Just t -> "Type: " ++ sh t++ sym (KBase k) nm = do v <- lift $ S.svMkSymVar Nothing k nm+ return (Base v)++ sym (KTup ks) nm = do let ns = map (\i -> (++ ("_" ++ show i)) `fmap` nm) [1 .. length ks]+ vs <- zipWithM sym ks ns+ return $ Tup vs++ sym (KLst ks) nm = do Env{mbListSize} <- ask+ let ls = fromMaybe bad mbListSize+ bad = die cfg [curLoc] "List-argument found, with no size info"+ [ "Name: " ++ fromMaybe "anonymous" nm+ , tinfo (KLst ks)+ , "Hint: Use the \"ListSize\" annotation"+ ]+ ns = map (\i -> (++ ("_" ++ show i)) `fmap` nm) [1 .. ls]+ vs <- zipWithM sym (replicate ls ks) ns+ return (Lst vs)++ sym k@KFun{} nm = case mbBind of+ Just v -> uninterpret cfg True (varType v) v+ _ -> die cfg [curLoc] "Unsupported unnamed higher-order symbolic input"+ [ "Name: " ++ fromMaybe "<anonymous>" nm+ , tinfo k+ , "Hint: Name all higher-order inputs explicitly"+ ]++ -- | Uninterpret an expression-uninterpret :: Type -> Var -> Eval Val-uninterpret t v = do+uninterpret :: Config -> Bool -> Type -> Var -> Eval Val+uninterpret cfg isInput t var = do Env{rUninterpreted, flags} <- ask prevUninterpreted <- liftIO $ readIORef rUninterpreted- case (v, t) `lookup` prevUninterpreted of- Just (_, val) -> return val- Nothing -> do let (tvs, t') = splitForAllTys t- (args, res) = splitFunTys t'- sp = getSrcSpan v- argKs <- mapM (getType sp) args- resK <- getType sp res- nm <- mkValidName $ showSDoc flags (ppr v)- let fVal = wrap tvs $ walk argKs (nm, resK) []- liftIO $ modifyIORef rUninterpreted (((v, t), (nm, fVal)) :)- return fVal- where walk :: [SKind] -> (String, SKind) -> [S.SVal] -> Val- walk [] (nm, k) args = case k of- KBase b -> Base $ S.svUninterpreted b nm Nothing (reverse args)- _ -> error $ "Not yet supported uninterpreted type with non-base type: " ++ showSDocUnsafe (ppr k)- walk (_:as) nmk args = Func Nothing $ \a -> case a of- Base p -> return (walk as nmk (p:args))- _ -> return (walk as nmk args)+ case (var, t) `lookup` prevUninterpreted of+ Just (_, _, val) -> return val+ Nothing -> do let (tvs, t') = splitForAllTys t+ (args, res) = splitFunTys t'+ sp = getSrcSpan var+ argKs <- mapM (getType sp) args+ resK <- getType sp res+ nm <- mkValidName $ showSDoc flags (ppr var)+ body <- walk argKs (nm, resK) []+ let fVal = wrap tvs body+ liftIO $ modifyIORef rUninterpreted (((var, t), (isInput, nm, fVal)) :)+ return fVal+ where walk :: [SKind] -> (String, SKind) -> [Val] -> Eval Val+ walk [] (nm, k) args = do Env{curLoc, mbListSize} <- ask++ let ls = fromMaybe bad mbListSize+ bad = die cfg curLoc "List-argument found in uninterpreted function, with no size info"+ ["Hint: Use the \"ListSize\" annotation"]++ mkArg :: Val -> [S.SVal]+ mkArg (Base v) = [v]+ mkArg (Tup vs) = concatMap mkArg vs+ mkArg (Lst vs) = concatMap mkArg vs+ mkArg sk = error $ "Not yet supported uninterpreted function with a higher-order argument: " ++ showSDocUnsafe (ppr sk)++ bArgs = concatMap mkArg (reverse args)++ mkRes :: String -> SKind -> [S.SVal]+ mkRes n (KBase b) = [S.svUninterpreted b n Nothing bArgs]+ mkRes n (KTup bs) = concat $ zipWith mkRes [n ++ "_" ++ show i | i <- [(1 :: Int) .. ]] bs+ mkRes n (KLst b) = concat [mkRes (n ++ "_" ++ show i) b | i <- [(1 :: Int) .. ls]]+ mkRes _ sk = error $ "Not yet supported uninterpreted function with a higher-order result: " ++ showSDocUnsafe (ppr sk)++ res = map Base $ mkRes nm k+ case res of+ [x] -> return x+ _ -> return $ Tup res++ walk (_:ks) nmk args = return $ Func Nothing $ \a -> walk ks nmk (a:args) wrap [] f = f wrap (_:ts) f = Func Nothing $ \(Typ _) -> return (wrap ts f) @@ -458,7 +518,7 @@ -- | Convert a Core type to an SBV Type, retaining functions and tuples getType :: SrcSpan -> Type -> Eval SKind-getType sp typ = do let (tvs, typ') = splitForAllTys typ+getType sp typ = do let (tvs, typ') = splitForAllTys typ (args, res) = splitFunTys typ' argKs <- mapM (getType sp) args resK <- getComposite res
Data/SBV/Plugin/Common.hs view
@@ -10,6 +10,8 @@ ----------------------------------------------------------------------------- {-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE FlexibleInstances #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Data.SBV.Plugin.Common where@@ -36,18 +38,19 @@ } -- | Interpreter environment-data Env = Env { curLoc :: SrcSpan+data Env = Env { curLoc :: [SrcSpan] , flags :: DynFlags , machWordSize :: Int+ , mbListSize :: Maybe Int , uninteresting :: [Type]- , rUninterpreted :: IORef [((Var, Type), (String, Val))]+ , rUninterpreted :: IORef [((Var, Type), (Bool, String, Val))] , rUsedNames :: IORef [String] , rUITypes :: IORef [(Type, S.Kind)] , specials :: Specials , tcMap :: M.Map (TyCon, [TyCon]) S.Kind , envMap :: M.Map (Var, SKind) Val , destMap :: M.Map Var (Val -> [(Var, SKind)] -> (S.SVal, [((Var, SKind), Val)]))- , coreMap :: M.Map Var CoreExpr+ , coreMap :: M.Map Var (SrcSpan, CoreExpr) } @@ -138,15 +141,38 @@ ] -- | Compute the span given a Tick. Returns the old-span if the tick span useless.-tickSpan :: Tickish t -> SrcSpan -> SrcSpan-tickSpan (ProfNote cc _ _) _ = cc_loc cc-tickSpan (SourceNote s _) _ = RealSrcSpan s-tickSpan _ s = s+tickSpan :: Tickish t -> SrcSpan+tickSpan (ProfNote cc _ _) = cc_loc cc+tickSpan (SourceNote s _) = RealSrcSpan s+tickSpan _ = noSrcSpan -- | Compute the span for a binding.-bindSpan :: Var -> SrcSpan-bindSpan = nameSrcSpan . varName+varSpan :: Var -> SrcSpan+varSpan = nameSrcSpan . varName --- | Show a GHC span in user-friendly form.-showSpan :: Config -> Var -> SrcSpan -> String-showSpan Config{cfgEnv} b s = showSDoc (flags cfgEnv) $ if isGoodSrcSpan s then ppr s else ppr b+-- | Pick the first "good" span, hopefully corresponding to+-- the closest location to where we are in the code+-- when we issue an error message.+pickSpan :: [SrcSpan] -> SrcSpan+pickSpan ss = case filter isGoodSrcSpan ss of+ (s:_) -> s+ [] -> noSrcSpan++-- | Show a GHC span in user-friendly form+showSpan :: Config -> SrcSpan -> String+showSpan Config{cfgEnv} s = showSDoc (flags cfgEnv) (ppr s)++-- | This comes mighty handy! Wonder why GHC doesn't have it already:+instance Show CoreExpr where+ show = go+ where sh x = showSDocUnsafe (ppr x)+ go (Var i) = "(Var " ++ sh i ++ ")"+ go (Lit l) = "(Lit " ++ sh l ++ ")"+ go (App f a) = "(App " ++ go f ++ " " ++ go a ++ ")"+ go (Lam b e) = "(Lam " ++ sh b ++ " " ++ go e ++ ")"+ go (Let b e) = "(Let " ++ sh b ++ " " ++ go e ++ ")"+ go (Case e b t _) = "(Case " ++ go e ++ " " ++ sh b ++ " " ++ sh t ++ "...)"+ go (Cast e _) = "(Cast " ++ go e ++ " ...)"+ go (Tick _ e) = "(Tick " ++ go e ++ ")"+ go (Type t) = "(Type " ++ sh t ++ ")"+ go (Coercion _) = "(Coercion ...)"
Data/SBV/Plugin/Env.hs view
@@ -32,7 +32,6 @@ import Data.SBV.Plugin.Common - -- | What tuple-sizes we support? We go upto 15, but would be easy to change if necessary supportTupleSizes :: [Int] supportTupleSizes = [2 .. 15]@@ -108,9 +107,15 @@ ++ [ (op, tlift2 (KBase k), lift2 sOp) | k <- bvKinds, (op, sOp) <- bvBinOps ] ++ [ (op, tlift2ShRot wsz (KBase k), lift2 sOp) | k <- bvKinds, (op, sOp) <- bvShiftRots] + -- bv-splits+ ++ [('S.split, tSplit s, liftSplit s) | s <- [16, 32, 64]]++ -- bv-joins+ ++ [ ('(S.#), tJoin s, lift2 S.svJoin) | s <- [8, 16, 32]]+ where -- Bit-vectors- bvKinds = [S.KBounded s sz | s <- [False, True], sz <- [8, 16, 32, 64]]+ bvKinds = [S.KBounded s sz | s <- [False, True], sz <- [8, 16, 32, 64]] -- Those that are "integral"ish integralKinds = S.KUnbounded : bvKinds@@ -262,6 +267,18 @@ tlift2ShRot :: Int -> SKind -> SKind tlift2ShRot wsz k = KFun k (KFun (KBase (S.KBounded True wsz)) k) +-- | Construct the type for a split operation+tSplit :: Int -> SKind+tSplit n = KFun a (KTup [r, r])+ where a = KBase (S.KBounded False n)+ r = KBase (S.KBounded False (n `div` 2))++-- | Construct the type for a join operation+tJoin :: Int -> SKind+tJoin n = KFun a (KFun a r)+ where a = KBase (S.KBounded False n)+ r = KBase (S.KBounded False (n*2))+ -- | Lift a unary SBV function that via kind/integer lift1Int :: (Integer -> S.SVal) -> Val lift1Int f = Func Nothing g@@ -285,6 +302,16 @@ h v = error $ "Impossible happened: lift2 received non-base argument (h): " ++ showSDocUnsafe (ppr v) k a (Base b) = return $ Base $ f a b k _ v = error $ "Impossible happened: lift2 received non-base argument (k): " ++ showSDocUnsafe (ppr v)++-- | Lifting splits+liftSplit :: Int -> Val+liftSplit n = Func Nothing g+ where g (Typ _) = return $ Func Nothing g+ g (Base a) = do let half = n `div` 2+ f = Base $ S.svExtract (n-1) half a+ s = Base $ S.svExtract (half-1) 0 a+ return $ Tup [f, s]+ g v = error $ "Impossible happened: liftSplit received unexpected argument: " ++ showSDocUnsafe (ppr (n, v)) -- | Lifting an equality is special; since it acts uniformly over tuples. liftEq :: (S.SVal -> S.SVal -> S.SVal) -> Val
+ Data/SBV/Plugin/Examples/BitTricks.hs view
@@ -0,0 +1,73 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.SBV.Plugin.Examples.BitTricks+-- Copyright : (c) Levent Erkok+-- License : BSD3+-- Maintainer : erkokl@gmail.com+-- Stability : experimental+--+-- Checks the correctness of a few tricks from the large collection found in:+-- <http://graphics.stanford.edu/~seander/bithacks.html>+-----------------------------------------------------------------------------++{-# OPTIONS_GHC -fplugin=Data.SBV.Plugin #-}++module Data.SBV.Plugin.Examples.BitTricks where++import Data.SBV.Plugin++import Data.Bits+import Data.Word++-- | Returns 1 if bool is @True@+oneIf :: Num a => Bool -> a+oneIf True = 1+oneIf False = 0++-- | Formalizes <http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax>+{-# ANN fastMinCorrect theorem #-}+fastMinCorrect :: Int -> Int -> Bool+fastMinCorrect x y = m == fm+ where m = if x < y then x else y+ fm = y `xor` ((x `xor` y) .&. (-(oneIf (x < y))));++-- | Formalizes <http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax>+{-# ANN fastMaxCorrect theorem #-}+fastMaxCorrect :: Int -> Int -> Bool+fastMaxCorrect x y = m == fm+ where m = if x < y then y else x+ fm = x `xor` ((x `xor` y) .&. (-(oneIf (x < y))));++-- | Formalizes <http://graphics.stanford.edu/~seander/bithacks.html#DetectOppositeSigns>+{-# ANN oppositeSignsCorrect theorem #-}+oppositeSignsCorrect :: Int -> Int -> Bool+oppositeSignsCorrect x y = r == os+ where r = (x < 0 && y >= 0) || (x >= 0 && y < 0)+ os = (x `xor` y) < 0++-- | Formalizes <http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching>+{-# ANN conditionalSetClearCorrect theorem #-}+conditionalSetClearCorrect :: Bool -> Word32 -> Word32 -> Bool+conditionalSetClearCorrect f m w = r == r'+ where r | f = w .|. m+ | True = w .&. complement m+ r' = w `xor` ((-(oneIf f) `xor` w) .&. m)++-- | Formalizes <http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2>+{-# ANN powerOfTwoCorrect theorem #-}+powerOfTwoCorrect :: Word32 -> Bool+powerOfTwoCorrect v = f == search powers+ where f = (v /= 0) && ((v .&. (v-1)) == 0)++ powers :: [Word32]+ powers = [ 1, 2, 4, 8, 16, 32, 64, 128+ , 256, 512, 1024, 2048, 4096, 8192, 16384, 32768+ , 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608+ , 16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648+ ]++ search :: [Word32] -> Bool+ search [] = False+ search (x:xs)+ | x == v = True+ | True = search xs
+ Data/SBV/Plugin/Examples/MergeSort.hs view
@@ -0,0 +1,101 @@+-----------------------------------------------------------------------------+-- |+-- Module : Data.SBV.Plugin.Examples.MergeSort+-- Copyright : (c) Levent Erkok+-- License : BSD3+-- Maintainer : erkokl@gmail.com+-- Stability : experimental+--+-- An implementation of merge-sort and its correctness.+-----------------------------------------------------------------------------+--+{-# OPTIONS_GHC -fplugin=Data.SBV.Plugin #-}++module Data.SBV.Plugin.Examples.MergeSort where++import Data.SBV.Plugin++-----------------------------------------------------------------------------+-- * Implementing merge-sort+-- ${mergeSort}+-----------------------------------------------------------------------------+{- $mergeSort+A straightforward implementation of merge sort. We simply divide the input list+in to two halves so long as it has at least two elements, sort each half on its+own, and then merge.+-}++-- | Merging two given sorted lists, preserving the order.+merge :: Ord a => [a] -> [a] -> [a]+merge [] ys = ys+merge xs [] = xs+merge xs@(x:xr) ys@(y:yr)+ | x < y = x : merge xr ys+ | True = y : merge xs yr++-- | Simple merge-sort implementation.+mergeSort :: Ord a => [a] -> [a]+mergeSort [] = []+mergeSort [x] = [x]+mergeSort xs = merge (mergeSort th) (mergeSort bh)+ where (th, bh) = split xs ([], [])+ split :: [a] -> ([a], [a]) -> ([a], [a])+ split [] sofar = sofar+ split (a:as) (fs, ss) = split as (ss, a:fs)++-----------------------------------------------------------------------------+-- * Proving correctness of sorting+-- ${props}+-----------------------------------------------------------------------------+{- $props+There are two main parts to proving that a sorting algorithm is correct:++ * Prove that the output is non-decreasing+ + * Prove that the output is a permutation of the input+-}++-- | Check whether a given sequence is non-decreasing.+nonDecreasing :: Ord a => [a] -> Bool+nonDecreasing [] = True+nonDecreasing [_] = True+nonDecreasing (a:b:xs) = a <= b && nonDecreasing (b:xs)++-- | Check whether two given sequences are permutations. We simply check that each sequence+-- is a subset of the other, when considered as a set. The check is slightly complicated+-- for the need to account for possibly duplicated elements.+isPermutationOf :: Eq a => [a] -> [a] -> Bool+isPermutationOf as bs = go as [(b, True) | b <- bs] && go bs [(a, True) | a <- as]+ where go :: Eq a => [a] -> [(a, Bool)] -> Bool+ go [] _ = True+ go (x:xs) ys = found && go xs ys'+ where (found, ys') = mark x ys++ -- Go and mark off an instance of 'x' in the list, if possible. We keep track+ -- of unmarked elements by associating a boolean bit. Note that we have to+ -- keep the lists equal size for the recursive result to merge properly.+ mark :: Eq a => a -> [(a, Bool)] -> (Bool, [(a, Bool)])+ mark _ [] = (False, [])+ mark x ((y, v) : ys)+ | v && x == y = (True, (y, not v) : ys)+ | True = (r, (y, v) : ys')+ where (r, ys') = mark x ys++-----------------------------------------------------------------------------+-- * The correctness theorem+-----------------------------------------------------------------------------++-- | Asserting correctness of merge-sort for a list of the given size. Note that we can+-- only check correctness for fixed-size lists. Also, the proof will get more and more+-- complicated for the backend SMT solver as 'n' increases. Here we try it with 4.+--+-- We have:+--+-- @+-- [SBV] tests/T48.hs:100:1-16 Proving "mergeSortCorrect", using Z3.+-- [Z3] Q.E.D.+-- @+{-# ANN mergeSortCorrect theorem { options = [ListSize 4] } #-}+mergeSortCorrect :: [Int] -> Bool+mergeSortCorrect xs = nonDecreasing ys && isPermutationOf xs ys+ where ys = mergeSort xs
Data/SBV/Plugin/Plugin.hs view
@@ -66,9 +66,10 @@ let cfg = Config { isGHCi = hscTarget df == HscInterpreted , opts = [] , sbvAnnotation = lookupWithDefaultUFM anns [] . varUnique- , cfgEnv = Env { curLoc = noSrcSpan+ , cfgEnv = Env { curLoc = [] , flags = df , machWordSize = wsz+ , mbListSize = Nothing , uninteresting = uninteresting , rUninterpreted = rUninterpreted , rUsedNames = rUsedNames@@ -77,13 +78,13 @@ , tcMap = baseTCs , envMap = baseEnv , destMap = baseDests- , coreMap = M.fromList (flattenBinds mg_binds)+ , coreMap = M.fromList [(b, (varSpan b, e)) | (b, e) <- flattenBinds mg_binds] } } - let bindLoc (NonRec b _) = bindSpan b+ let bindLoc (NonRec b _) = varSpan b bindLoc (Rec []) = noSrcSpan- bindLoc (Rec ((b, _):_)) = bindSpan b+ bindLoc (Rec ((b, _):_)) = varSpan b mapM_ (analyzeBind cfg) $ sortBy (comparing bindLoc) mg_binds
sbvPlugin.cabal view
@@ -1,5 +1,5 @@ Name : sbvPlugin-Version : 0.4+Version : 0.5 Category : Formal methods, Theorem provers, Math, SMT, Symbolic Computation Synopsis : Formally prove properties of Haskell programs using SBV/SMT Description : GHC plugin for proving properties over Haskell functions using SMT solvers, based@@ -16,7 +16,6 @@ Maintainer : Levent Erkok (erkokl@gmail.com) Build-Type : Simple Cabal-Version : >= 1.14-Data-Files : tests/GoldFiles/*.hs.golden Extra-Source-Files: INSTALL, README.md, COPYRIGHT, CHANGES.md source-repository head@@ -27,7 +26,9 @@ default-language: Haskell2010 ghc-options : -Wall -fplugin-opt Data.SBV.Plugin:skip Exposed-modules : Data.SBV.Plugin+ , Data.SBV.Plugin.Examples.MergeSort , Data.SBV.Plugin.Examples.MicroController+ , Data.SBV.Plugin.Examples.BitTricks build-depends : base >= 4.8 && < 5, ghc, ghc-prim, containers, sbv >= 5.7, mtl, template-haskell Other-modules : Data.SBV.Plugin.Analyze , Data.SBV.Plugin.Data
− tests/GoldFiles/T00.hs.golden
@@ -1,8 +0,0 @@--[SBV] tests/T00.hs:12:1 Proving "f", using Z3.-[Z3] Q.E.D.--[SBV] tests/T00.hs:16:1 Proving "g", using Z3.-[Z3] Falsifiable. Counter-example:- _x = 0 :: Int8- _y = False :: Bool
− tests/GoldFiles/T01.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T01.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 40959.98499298095 :: Double- y = -73732.00109529495 :: Double- z = 257.9890136271454 :: Double-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T02.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T02.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 1 :: Integer- y = 0 :: Integer
− tests/GoldFiles/T03.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T03.hs:10:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T04.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T04.hs:10:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T05.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T05.hs:9:1 Proving "f", using CVC4.-[CVC4] Falsifiable. Counter-example:- x = 0 :: Integer- y = -1 :: Integer
− tests/GoldFiles/T06.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T06.hs:10:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = -128 :: Int8-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T07.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T07.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = NaN :: Double-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T08.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T08.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 0.0 :: Double-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T09.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T09.hs:10:1 QuickChecking "f", using Z3.-(0 tests) (1 test) (2 tests) (3 tests) (4 tests) (5 tests) (6 tests) (7 tests) (8 tests) (9 tests) (10 tests) (11 tests) (12 tests) (13 tests) (14 tests) (15 tests) (16 tests) (17 tests) (18 tests) (19 tests) (20 tests) (21 tests) (22 tests) (23 tests) (24 tests) (25 tests) (26 tests) (27 tests) (28 tests) (29 tests) (30 tests) (31 tests) (32 tests) (33 tests) (34 tests) (35 tests) (36 tests) (37 tests) (38 tests) (39 tests) (40 tests) (41 tests) (42 tests) (43 tests) (44 tests) (45 tests) (46 tests) (47 tests) (48 tests) (49 tests) (50 tests) (51 tests) (52 tests) (53 tests) (54 tests) (55 tests) (56 tests) (57 tests) (58 tests) (59 tests) (60 tests) (61 tests) (62 tests) (63 tests) (64 tests) (65 tests) (66 tests) (67 tests) (68 tests) (69 tests) (70 tests) (71 tests) (72 tests) (73 tests) (74 tests) (75 tests) (76 tests) (77 tests) (78 tests) (79 tests) (80 tests) (81 tests) (82 tests) (83 tests) (84 tests) (85 tests) (86 tests) (87 tests) (88 tests) (89 tests) (90 tests) (91 tests) (92 tests) (93 tests) (94 tests) (95 tests) (96 tests) (97 tests) (98 tests) (99 tests) +++ OK, passed 100 tests.
− tests/GoldFiles/T10.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T10.hs:12:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T11.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T11.hs:15:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 11 :: Integer-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T12.hs.golden
@@ -1,6 +0,0 @@--[SBV] tests/T12.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- i = 2 :: Integer- b = False :: Bool-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T13.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T13.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- i = 0 :: Integer- d = 0.0 :: Double- b = False :: Bool-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T14.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T14.hs:10:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 1.0 :: Real-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T15.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T15.hs:11:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T16.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T16.hs:11:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- age = Age!val!0 :: Age-[SBV] Counter-example might be bogus due to uninterpreted constant:- [<no location info>] ds_d6ck :: Int-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T17.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T17.hs:14:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 0 :: Int64-[SBV] Counter-example might be bogus due to uninterpreted constant:- [tests/T17.hs:9:1] g :: Int -> Int-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T18.hs.golden
@@ -1,59 +0,0 @@--[SBV] tests/T18.hs:11:1 Proving "f", using Z3.-** Starting symbolic simulation..-** Generated symbolic trace:-SORTS- Age-INPUTS- s0 :: Age, aliasing "a"- s1 :: Age, aliasing "b"-CONSTANTS- s_2 = False :: Bool- s_1 = True :: Bool-TABLES-ARRAYS-UNINTERPRETED CONSTANTS-USER GIVEN CODE SEGMENTS-AXIOMS-DEFINE- s2 :: SBool = s0 == s1-CONSTRAINTS-ASSERTIONS-OUTPUTS- s2-** Translating to SMT-Lib..-** Checking Theoremhood..-** Generated SMTLib program:-; Automatically generated by SBV. Do not edit.-(set-option :produce-models true)-; has user-defined sorts, no logic specified.-; --- uninterpreted sorts ----(declare-sort Age 0) ; N.B. Uninterpreted: originating from sbvPlugin: tests/T18.hs:11:3-; --- literal constants ----(define-fun s_2 () Bool false)-(define-fun s_1 () Bool true)-; --- skolem constants ----(declare-fun s0 () Age) ; tracks user variable "a"-(declare-fun s1 () Age) ; tracks user variable "b"-; --- constant tables ----; --- skolemized tables ----; --- arrays ----; --- uninterpreted constants ----; --- user given axioms ----; --- formula ----(assert ; no quantifiers- (let ((s2 (= s0 s1)))- (not s2)))-** Calling: "z3 -nw -in -smt2"-** Sending the following model extraction commands:-(get-value (s0))-(get-value (s1))-** Z3 output:-sat-((s0 Age!val!0))-((s1 Age!val!1))-** Done..-[Z3] Falsifiable. Counter-example:- a = Age!val!0 :: Age- b = Age!val!1 :: Age-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T19.hs.golden
@@ -1,14 +0,0 @@--[SBV] tests/T19.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.--[SBV] tests/T19.hs:15:1 Proving "g", using Z3.-[Z3] Falsifiable. Counter-example:- s_1 = sbvChar!val!0 :: sbvChar- s_2 = sbvChar!val!0 :: sbvChar- s_3 = sbvChar!val!0 :: sbvChar- s_4 = sbvChar!val!0 :: sbvChar- s_5 = sbvChar!val!0 :: sbvChar- s_6 = sbvChar!val!0 :: sbvChar-[SBV] Counter-example might be bogus due to uninterpreted constants:- [<wired into compiler>] C# :: Char# -> Char
− tests/GoldFiles/T20.hs.golden
@@ -1,1 +0,0 @@-[SBV] tests/T20.hs:10:1 Skipping "f": Don't want to prove this now.
− tests/GoldFiles/T21.hs.golden
@@ -1,36 +0,0 @@--[SBV] tests/T21.hs:9:1 Proving "f", using Z3.-** Starting symbolic simulation..-** Generated symbolic trace:-True :: Bool-** Translating to SMT-Lib..-** Checking Theoremhood..-** Generated SMTLib program:-; Automatically generated by SBV. Do not edit.-(set-option :produce-models true)-; has user-defined sorts, no logic specified.-; --- uninterpreted sorts ----(declare-sort sbvChar 0) ; N.B. Uninterpreted: originating from sbvPlugin: tests/T21.hs:9:3-; --- literal constants ----(define-fun s_2 () Bool false)-(define-fun s_1 () Bool true)-; --- skolem constants ----(declare-fun s0 () sbvChar) ; tracks user variable "c"-(declare-fun s1 () sbvChar) ; tracks user variable "s_1"-(declare-fun s2 () sbvChar) ; tracks user variable "s_2"-(declare-fun s3 () sbvChar) ; tracks user variable "s_3"-(declare-fun s4 () sbvChar) ; tracks user variable "s_4"-(declare-fun s5 () sbvChar) ; tracks user variable "s_5"-; --- constant tables ----; --- skolemized tables ----; --- arrays ----; --- uninterpreted constants ----; --- user given axioms ----; --- formula ----(assert ; no quantifiers- (not s_1))-** Calling: "z3 -nw -in -smt2"-** Z3 output:-unsat-** Done..-[Z3] Q.E.D.
− tests/GoldFiles/T22.hs.golden
@@ -1,5 +0,0 @@--[SBV] tests/T22.hs:12:1 Proving "g", using Z3.-[Z3] Falsifiable. Counter-example:- s0 = -1 :: Int64-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T23.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T23.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T24.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T24.hs:10:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T25.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T25.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T26.hs.golden
@@ -1,4 +0,0 @@--[SBV] tests/T26.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T27.hs.golden
@@ -1,29 +0,0 @@--[SBV] tests/T27.hs:9:1 Proving "g", using Z3.-** Starting symbolic simulation..-** Generated symbolic trace:-True :: Bool-** Translating to SMT-Lib..-** Checking Theoremhood..-** Generated SMTLib program:-; Automatically generated by SBV. Do not edit.-(set-option :produce-models true)-(set-logic QF_BV)-; --- uninterpreted sorts ----; --- literal constants ----(define-fun s_2 () Bool false)-(define-fun s_1 () Bool true)-; --- skolem constants ----; --- constant tables ----; --- skolemized tables ----; --- arrays ----; --- uninterpreted constants ----; --- user given axioms ----; --- formula ----(assert ; no quantifiers- (not s_1))-** Calling: "z3 -nw -in -smt2"-** Z3 output:-unsat-** Done..-[Z3] Q.E.D.
− tests/GoldFiles/T28.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T28.hs:13:1 Proving "g", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T29.hs.golden
@@ -1,4 +0,0 @@--[SBV] tests/T29.hs:13:1 Proving "g", using Z3.-[Z3] Falsifiable-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T30.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T30.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T31.hs.golden
@@ -1,19 +0,0 @@--[SBV] tests/T31.hs:9:1 Proving "f", using Z3.--[SBV] tests/T31.hs:9:1 Skipping proof. Non-boolean property declaration:- Found : Int -> Int- Returning: Int- Expected : Bool result--[SBV] tests/T31.hs:13:1 Proving "g", using Z3.--[SBV] tests/T31.hs:13:1 Skipping proof. Non-boolean property declaration:- Found : Char- Expected : Bool--[SBV] tests/T31.hs:17:1 Proving "h", using Z3.--[SBV] tests/T31.hs:17:1 Skipping proof. Non-boolean property declaration:- Found : Double- Expected : Bool
− tests/GoldFiles/T32.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T32.hs:11:1 Proving "f", using Z3.-[Z3] Q.E.D.--[SBV] tests/T32.hs:15:1 Proving "g", using Z3.-[Z3] Falsifiable. Counter-example:- x = 32 :: Word8
− tests/GoldFiles/T33.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T33.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = 0 :: Int64--[SBV] tests/T33.hs:15:1 Proving "g", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T34.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T34.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T35.hs.golden
@@ -1,6 +0,0 @@--[SBV] tests/T35.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- x = -1 :: Int64- y = 0 :: Int64-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T36.hs.golden
@@ -1,9 +0,0 @@--[SBV] tests/T36.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.--[SBV] tests/T36.hs:14:1 Proving "g", using Z3.-[Z3] Falsifiable. Counter-example:- a = -65 :: Int64- b = -65 :: Int64- c = 64 :: Int64
− tests/GoldFiles/T37.hs.golden
@@ -1,6 +0,0 @@--[SBV] tests/T37.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- a = 2 :: Int64- b = 2.3 :: Double-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T38.hs.golden
@@ -1,7 +0,0 @@--[SBV] tests/T38.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- a = 1 :: Int64- b = 2 :: Int64- c = 4 :: Int64-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T39.hs.golden
@@ -1,6 +0,0 @@--[SBV] tests/T39.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- p_1 = -1 :: Int64- p_2 = 0 :: Int64-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T40.hs.golden
@@ -1,3 +0,0 @@--[SBV] tests/T40.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.
− tests/GoldFiles/T41.hs.golden
@@ -1,8 +0,0 @@--[SBV] tests/T41.hs:9:1 Proving "f", using Z3.-[Z3] Q.E.D.--[SBV] tests/T41.hs:13:1 Proving "g", using Z3.-[Z3] Falsifiable. Counter-example:- x = -1 :: Int64- y = 0 :: Int64
− tests/GoldFiles/T42.hs.golden
@@ -1,9 +0,0 @@--[SBV] tests/T42.hs:9:1 Proving "f", using Z3.-[Z3] Falsifiable. Counter-example:- xs_1 = 10 :: Int64- xs_2 = 0 :: Int64- xs_3 = 0 :: Int64- xs_4 = 0 :: Int64- xs_5 = 0 :: Int64-[SBV] Failed. (Use option 'IgnoreFailure' to continue.)
− tests/GoldFiles/T43.hs.golden
@@ -1,21 +0,0 @@--[SBV] tests/T43.hs:13:1 Proving "t", using Z3.-[Z3] Q.E.D.--[SBV] tests/T43.hs:19:1 Proving "r", using Z3.--[SBV] tests/T43.hs:19:1 Skipping proof. Unsupported case-expression (with-complicated-alternatives-during-merging):- case == @ Int $fEqInt x (I# 0) of _ [Occ=Dead] {- False ->- (\ _ [Occ=Dead, OS=OneShot] ->- : @ Int x (: @ Int x (: @ Int x (: @ Int x ([] @ Int)))))- void#;- True -> : @ Int x (: @ Int x (: @ Int x ([] @ Int)))-}- While Analyzing:- Alternatives are producing lists of differing sizes:- Length 4: [<symbolic> :: SInt64,- <symbolic> :: SInt64,- <symbolic> :: SInt64,- <symbolic> :: SInt64]- vs Length 3: [<symbolic> :: SInt64, <symbolic> :: SInt64, <symbolic> :: SInt64]
− tests/GoldFiles/T44.hs.golden
@@ -1,9 +0,0 @@--[SBV] tests/T44.hs:12:1 Proving "t", using Z3.-[Z3] Q.E.D.--[SBV] tests/T44.hs:20:1 Proving "r", using Z3.-[Z3] Falsifiable. Counter-example:- b = False :: Bool- x = 0 :: Integer- y = -1 :: Integer