Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

minor fixes #359

Merged
merged 6 commits into from
Dec 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crucible-llvm/crucible-llvm.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ library
directory,
ghc-prim,
extra,
filepath,
hashable,
hashtables,
lens,
Expand Down
5 changes: 4 additions & 1 deletion crucible-llvm/src/Lang/Crucible/LLVM/Translation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ import Data.Maybe
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import qualified Data.Text as Text
import System.FilePath

import qualified Text.LLVM.AST as L

Expand Down Expand Up @@ -247,8 +248,10 @@ setLocation (x:xs) =

where
getFile = Text.pack . maybe "" filenm . findFile
filenm di = L.difDirectory di ++ "/" ++ L.difFilename di

filenm di
| isRelative (L.difFilename di) = L.difDirectory di </> L.difFilename di
| otherwise = L.difFilename di

findFile :: (?lc :: TypeContext) => L.ValMd -> Maybe L.DIFile
findFile (L.ValMdRef x) = findFile =<< lookupMetadata x
Expand Down
1 change: 0 additions & 1 deletion crucible/src/Lang/Crucible/Simulator/EvalStmt.hs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ import What4.InterpretedFloatingPoint (freshFloatConstant)
import What4.Partial
import What4.ProgramLoc
import What4.Symbol (emptySymbol)
import What4.Utils.StringLiteral

import Lang.Crucible.Backend
import Lang.Crucible.CFG.Core
Expand Down
11 changes: 11 additions & 0 deletions crux/src/Crux/Config/Common.hs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ data CruxOptions = CruxOptions
-- ^ Should the MC-SAT Yices solver be enabled (disables unsat cores; default: no)
, floatMode :: String
-- ^ Tells the solver which representation to use for floating point values.

, proofGoalsFailFast :: Bool
-- ^ If true, stop attempting to prove goals as soon as one is disproved
}


Expand Down Expand Up @@ -152,6 +155,10 @@ cruxOptions = Config
++ " i.e. one of [real|ieee|uninterpreted|default].\n"
++ "Default representation is solver specific: [cvc4|yices]=>real, z3=>ieee.")

proofGoalsFailFast <-
section "proof-goals-fail-fast" yesOrNoSpec False
"If true, stop attempting to prove goals as soon as one of them is disproved"

pure CruxOptions { .. }


Expand Down Expand Up @@ -231,6 +238,10 @@ cruxOptions = Config
"Enable the MC-SAT solver in Yices (disables unsat cores)"
$ NoArg $ \opts -> Right opts { yicesMCSat = True }

, Option [] ["fail-fast"]
"Stop attempting to prove goals as soon as one of them is disproved"
$ NoArg $ \opts -> Right opts { proofGoalsFailFast = True }

, Option "f" ["floating-point"]
("Select floating point representation,"
++ " i.e. one of [real|ieee|uninterpreted|default].\n"
Expand Down
33 changes: 23 additions & 10 deletions crux/src/Crux/Goal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
module Crux.Goal where

import Control.Lens ((^.), view)
import Control.Monad (forM_, unless)
import Control.Monad (forM_, unless, when)
import Data.Either (partitionEithers)
import Data.IORef
import Data.Maybe (fromMaybe)
Expand Down Expand Up @@ -116,16 +116,18 @@ proveGoals opts _ctxt Nothing =
proveGoals opts ctxt (Just gs0) =
do let sym = ctxt ^. ctxSymInterface
sp <- getSolverProcess sym
goalNum <- newIORef (0,0) -- total, proved
goalNum <- newIORef (0,0,0) -- total, proved, disproved
nameMap <- newIORef Map.empty
unless hasUnsatCores $
sayWarn "Crux" "Warning: skipping unsat cores because MC-SAT is enabled."
res <- inNewFrame sp (go sp goalNum gs0 nameMap)
(tot,proved) <- readIORef goalNum
(tot,proved,disproved) <- readIORef goalNum
if proved /= tot
then sayFail "Crux" $ unwords
[ "Failed to prove", show (tot - proved)
, "out of", show tot, "goals." ]
[ "Disproved", show disproved
, "out of", show tot, "goals."
, show (tot - proved - disproved), "goals are unknown."
]
else sayOK "Crux" $ unwords [ "Proved all", show tot, "goals." ]
return (Just res)
where
Expand All @@ -135,6 +137,8 @@ proveGoals opts ctxt (Just gs0) =

hasUnsatCores = not (yicesMCSat opts)

failfast = proofGoalsFailFast opts

go sp gn gs nameMap = do
case gs of

Expand All @@ -147,7 +151,7 @@ proveGoals opts ctxt (Just gs0) =
return (Assuming ps res)

Prove p ->
do num <- atomicModifyIORef' gn (\(val,y) -> ((val + 1,y), val))
do num <- atomicModifyIORef' gn (\(val,y,z) -> ((val + 1,y,z), val))
start num
let sym = ctxt ^. ctxSymInterface
nm <- doAssume =<< mkFormula conn =<< notPred sym (p ^. labeledPred)
Expand All @@ -156,15 +160,17 @@ proveGoals opts ctxt (Just gs0) =
res <- check sp "proof"
ret <- case res of
Unsat () ->
do modifyIORef' gn (\(x,f) -> (x,f+1))
do modifyIORef' gn (\(x,u,s) -> (x,u+1,s))
namemap <- readIORef nameMap
core <- if hasUnsatCores
then map (lookupnm namemap) <$> getUnsatCore sp
else return (Map.elems namemap)
return (Prove (p, (Proved core)))

Sat () ->
do f <- smtExprGroundEvalFn conn (solverEvalFuns sp)
do modifyIORef' gn (\(x,u,s) -> (x,u,s+1))
when failfast (sayOK "Crux" "Counterexample found, skipping remaining goals.")
f <- smtExprGroundEvalFn conn (solverEvalFuns sp)
let model = ctxt ^. cruciblePersonality
vals <- evalModel f model
return (Prove (p, NotProved (Just (ModelView vals))))
Expand All @@ -177,8 +183,15 @@ proveGoals opts ctxt (Just gs0) =
do g1' <- inNewFrame sp (go sp gn g1 nameMap)
-- NB, we don't need 'inNewFrame' here because
-- we don't need to back up to this point again.
g2' <- go sp gn g2 nameMap
return (ProveConj g1' g2')

if failfast then
do (_,_,s) <- readIORef gn
if s > 0 then
return g1'
else
ProveConj g1' <$> go sp gn g2 nameMap
else
ProveConj g1' <$> go sp gn g2 nameMap

where
conn = solverConn sp
Expand Down
1 change: 0 additions & 1 deletion what4/src/What4/Interface.hs
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,6 @@ class (IsExpr (SymExpr sym), HashableF (SymExpr sym)) => IsExprBuilder sym where

-- | Equality of boolean values
eqPred :: sym -> Pred sym -> Pred sym -> IO (Pred sym)
eqPred sym x y = notPred sym =<< xorPred sym x y
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the problem with this default implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing, really, but xor is defined as the negation of equality now, and eqPred is actually the primitive that is defined. The only real problem is that the definition is misleading


-- | If-then-else on a predicate.
itePred :: sym -> Pred sym -> Pred sym -> Pred sym -> IO (Pred sym)
Expand Down
2 changes: 1 addition & 1 deletion what4/src/What4/Protocol/SMTLib2/Syntax.hs
Original file line number Diff line number Diff line change
Expand Up @@ -679,7 +679,7 @@ bvashr = bin_app "bvashr"
--
-- Note. This is in @QF_BV@, but not the bitvector theory.
bvsdiv :: Term -> Term -> Term
bvsdiv = bin_app "bvudiv"
bvsdiv = bin_app "bvsdiv"

-- | @bvsrem x y@ returns @x - y * bvsdiv x y@ when @y != 0@.
--
Expand Down
2 changes: 1 addition & 1 deletion what4/src/What4/Solver/Yices.hs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ newConnection stream ack reqFeatures timeout bindings = do
let nlSolver = reqFeatures `hasProblemFeature` useNonlinearArithmetic
let features | efSolver = useLinearArithmetic
| nlSolver = useNonlinearArithmetic .|. useIntegerArithmetic
| otherwise = useIntegerArithmetic
| otherwise = yicesDefaultFeatures
let nm | efSolver = "Yices ef-solver"
| nlSolver = "Yices nl-solver"
| otherwise = "Yices"
Expand Down