Skip to content
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
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ prerequisites:
* Ensure that you have the `z3` SMT solver in your `PATH`. `z3` binaries are
available at https://github.com/Z3Prover/z3/releases.

Alternatively, the verifier can be configured to use one of the following
SMT solvers instead:

* `cvc4`: https://cvc4.github.io/downloads.html
* `cvc5`: https://github.com/cvc5/cvc5/releases/
* `yices`: https://yices.csl.sri.com

Then, clone the repo and run:

```
Expand Down
3 changes: 3 additions & 0 deletions copilot-verifier/CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
2025-01-31
* Add `smtSolver` option to `VerifierOptions`. (#78)

2025-01-20
* Version bump (4.2). (#76)
* Reject specs that use multiple triggers with the same name. (#74)
Expand Down
1 change: 1 addition & 0 deletions copilot-verifier/copilot-verifier.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ library
exposed-modules:
Copilot.Verifier
Copilot.Verifier.Log
Copilot.Verifier.Solver

library copilot-verifier-examples
import: bldflags
Expand Down
21 changes: 14 additions & 7 deletions copilot-verifier/src/Copilot/Verifier.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import qualified Copilot.Core.Type as CT
import qualified Copilot.Theorem.What4 as CW4

import qualified Copilot.Verifier.Log as Log
import qualified Copilot.Verifier.Solver as Solver

import Data.Parameterized.Ctx (EmptyCtx)
import Data.Parameterized.Context (pattern Empty)
Expand Down Expand Up @@ -160,7 +161,6 @@ import What4.InterpretedFloatingPoint
)
import What4.ProgramLoc (ProgramLoc, mkProgramLoc, plFunction, Position(..))
import What4.Solver.Adapter (SolverAdapter(..))
import What4.Solver.Z3 (z3Adapter)
import What4.Symbol (safeSymbol)

-- | @'verify' csettings props prefix spec@ verifies the Copilot specification
Expand Down Expand Up @@ -202,6 +202,8 @@ data VerifierOptions = VerifierOptions
-- * @<solver>@ is the name of the SMT solver used to discharge the proof
-- goal. Currently, this will always be @z3@, although we might make this
-- configurable in the future.
, smtSolver :: Solver.Solver
-- ^ Which SMT solver to use when solving proof goals.
} deriving stock Show

-- | The default 'VerifierOptions':
Expand All @@ -212,11 +214,14 @@ data VerifierOptions = VerifierOptions
-- * Do not assume any side conditions related to partial operations.
--
-- * Do not log any SMT solver interactions.
--
-- * Use the Z3 SMT solver.
defaultVerifierOptions :: VerifierOptions
defaultVerifierOptions = VerifierOptions
{ verbosity = Default
, assumePartialSideConds = False
, logSmtInteractions = False
, smtSolver = Solver.Z3
}

-- | Like 'defaultVerifierOptions', except that the verifier will assume side
Expand Down Expand Up @@ -332,7 +337,8 @@ verifyBitcode ::
verifyBitcode opts csettings properties spec cruxOpts llvmOpts cFile bcFile =
do -- Set up the expression builder and symbolic backend
halloc <- newHandleAllocator
sym <- newExprBuilder FloatUninterpretedRepr CopilotVerifierData globalNonceGenerator
(sym :: ExprBuilder t st fs) <-
newExprBuilder FloatUninterpretedRepr CopilotVerifierData globalNonceGenerator
bak <- newSimpleBackend sym
-- turn on hash-consing
startCaching sym
Expand All @@ -341,9 +347,10 @@ verifyBitcode opts csettings properties spec cruxOpts llvmOpts cFile bcFile =
clRefs <- newCopilotLogRefs
let ?recordLLVMAnnotation = recordLLVMAnnotation clRefs

-- Set up the solver to use for verification. Right now we hard-code this to Z3.
let adapters = [z3Adapter] -- TODO? configurable
extendConfig (solver_adapter_config_options z3Adapter) (getConfiguration sym)
-- Set up the solver to use for verification.
let adapter :: SolverAdapter st
adapter = Solver.solverAdapter (smtSolver opts)
extendConfig (solver_adapter_config_options adapter) (getConfiguration sym)

-- Set up the Crucible/LLVM simulation context
memVar <- mkMemVar "llvm_memory" halloc
Expand Down Expand Up @@ -386,13 +393,13 @@ verifyBitcode opts csettings properties spec cruxOpts llvmOpts cFile bcFile =
-- segment of the associated Copilot streams.
let cruxOptsInit = setCruxOfflineSolverOutput "initial-step" cruxOpts
initGoals <-
verifyInitialState cruxOptsInit adapters clRefs simctx initialMem
verifyInitialState cruxOptsInit [adapter] clRefs simctx initialMem
(CW4.initialStreamState proofStateBundle)

-- Now, the real meat. Carry out the bisimulation step of the proof.
let cruxOptsTrans = setCruxOfflineSolverOutput "transition-step" cruxOpts
bisimGoals <-
verifyStepBisimulation opts cruxOptsTrans adapters csettings
verifyStepBisimulation opts cruxOptsTrans [adapter] csettings
clRefs simctx llvmMod trans memVar initialMem proofStateBundle

Log.sayCopilot $ Log.SuccessfulProofSummary cFile initGoals bisimGoals
Expand Down
25 changes: 25 additions & 0 deletions copilot-verifier/src/Copilot/Verifier/Solver.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Copilot.Verifier.Solver
( Solver(..)
, solverAdapter
) where

import qualified What4.Solver.Adapter as W4
import qualified What4.Solver.CVC4 as W4.CVC4
import qualified What4.Solver.CVC5 as W4.CVC5
import qualified What4.Solver.Yices as W4.Yices
import qualified What4.Solver.Z3 as W4.Z3

-- | General-purpose SMT solvers that @copilot-verifier@ supports.
data Solver
= CVC4
| CVC5
| Yices
| Z3
deriving Show

-- | Return the @what4@ 'W4.SolverAdapter' corresponding to a given 'Solver'.
solverAdapter :: Solver -> W4.SolverAdapter st
solverAdapter CVC4 = W4.CVC4.cvc4Adapter
solverAdapter CVC5 = W4.CVC5.cvc5Adapter
solverAdapter Yices = W4.Yices.yicesAdapter
solverAdapter Z3 = W4.Z3.z3Adapter