sbv: SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.

[ bit-vectors, bsd3, formal-methods, library, math, smt, symbolic-computation, theorem-provers ] [ Propose Tags ] [ Report a vulnerability ]

Express properties about Haskell programs and automatically prove them using SMT (Satisfiability Modulo Theories) solvers.


[Skip to Readme]

Modules

[Index] [Quick Jump]

Flags

Manual Flags

NameDescriptionDefault
doctest_is_running

Define this flag during doctest run

Disabled

Use -f <flag> to enable a flag, or -f -<flag> to disable that flag. More info

Downloads

Maintainer's Corner

Package maintainers

For package maintainers and hackage trustees

Candidates

  • No Candidates
Versions [RSS] 0.9, 0.9.1, 0.9.2, 0.9.3, 0.9.4, 0.9.5, 0.9.6, 0.9.7, 0.9.8, 0.9.9, 0.9.10, 0.9.11, 0.9.12, 0.9.13, 0.9.14, 0.9.15, 0.9.16, 0.9.17, 0.9.18, 0.9.19, 0.9.20, 0.9.21, 0.9.22, 0.9.23, 0.9.24, 1.0, 1.1, 1.2, 1.3, 1.4, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 2.10, 3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 4.0, 4.1, 4.2, 4.3, 4.4, 5.0, 5.1, 5.2, 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 5.9, 5.10, 5.11, 5.12, 5.13, 5.14, 5.15, 6.0, 6.1, 7.0, 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7, 7.8, 7.9, 7.10, 7.11, 7.12, 7.13, 8.0, 8.1, 8.2, 8.3, 8.4, 8.5, 8.6, 8.7, 8.8, 8.9, 8.10, 8.11, 8.12, 8.13, 8.14, 8.15, 8.16, 8.17, 9.0, 9.1, 9.2, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5, 10.6, 10.7, 10.8, 10.9, 10.10, 10.11, 10.12, 11.0, 11.1, 11.2, 11.3, 11.4, 11.5, 11.6, 11.7, 12.0, 12.1, 12.2, 13.0, 13.1, 13.2, 13.3, 13.4, 13.5, 13.6, 14.0
Change log CHANGES.md
Dependencies array, async, base (>=4.19.2 && <5), base16-bytestring, bytestring, containers, cryptohash-sha512, deepseq, directory, filepath, haskell-src-exts, haskell-src-meta, libBF, mtl, pretty, process, QuickCheck, random, syb, template-haskell, text, th-expand-syns, time, transformers, tree-view, uniplate [details]
License BSD-3-Clause
Copyright Levent Erkok, 2010-2026
Author Levent Erkok
Maintainer Levent Erkok ([email protected])
Uploaded by LeventErkok at 2026-04-01T20:18:40Z
Category Formal Methods, Theorem Provers, Bit vectors, Symbolic Computation, Math, SMT
Home page http://github.com/LeventErkok/sbv
Bug tracker http://github.com/LeventErkok/sbv/issues
Source repo head: git clone https://github.com/LeventErkok/sbv.git
Reverse Dependencies 13 direct, 12 indirect [details]
Downloads 85947 total (320 in the last 30 days)
Rating 2.75 (votes: 9) [estimated by Bayesian average]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2026-04-01 [all 1 reports]

Readme for sbv-14.0

[back to package description]

SBV: SMT Based Verification in Haskell

Build Status

Express properties about Haskell programs and automatically prove them using SMT solvers.

Hackage | Release Notes | Documentation

SBV provides symbolic versions of Haskell types. Programs written with these types can be automatically verified, checked for satisfiability, optimized, or compiled to C — all via SMT solvers.

SBV in 5 Minutes

Fire up GHCi with SBV:

$ cabal repl --build-depends sbv

For unbounded integers, x + 1 .> x is always true:

ghci> :m Data.SBV
ghci> prove $ \x -> x + 1 .> (x :: SInteger)
Q.E.D.

But with machine arithmetic, overflow lurks:

ghci> prove $ \x -> x + 1 .> (x :: SInt8)
Falsifiable. Counter-example:
  s0 = 127 :: Int8

IEEE-754 floats break reflexivity of equality:

ghci> prove $ \x -> (x :: SFloat) .== x
Falsifiable. Counter-example:
  s0 = NaN :: Float

What's the multiplicative inverse of 3 modulo 256?

ghci> sat $ \x -> x * 3 .== (1 :: SWord8)
Satisfiable. Model:
  s0 = 171 :: Word8

Use quantifiers for named results:

ghci> sat $ skolemize $ \(Exists @"x" x) (Exists @"y" y) -> x * y .== (96::SInteger) .&& x + y .== 28
Satisfiable. Model:
  x = 24 :: Integer
  y =  4 :: Integer

Optimize a cost function subject to constraints:

ghci> :{
optimize Lexicographic $ do x <- sInteger "x"
                            y <- sInteger "y"
                            constrain $ x + y .== 20
                            constrain $ x .>= 5
                            constrain $ y .>= 5
                            minimize "cost" $ x * y
:}
Optimal in an extension field:
  x    =  5 :: Integer
  y    = 15 :: Integer
  cost = 75 :: Integer

For inductive proofs and equational reasoning, SBV includes a theorem prover:

revApp :: forall a. SymVal a => TP (Proof (Forall "xs" [a] -> Forall "ys" [a] -> SBool))
revApp = induct "revApp"
                 (\(Forall xs) (Forall ys) -> reverse (xs ++ ys) .== reverse ys ++ reverse xs) $
                 \ih (x, xs) ys -> [] |- reverse ((x .: xs) ++ ys)
                                      =: reverse (x .: (xs ++ ys))
                                      =: reverse (xs ++ ys) ++ [x]
                                      ?? ih
                                      =: (reverse ys ++ reverse xs) ++ [x]
                                      =: reverse ys ++ (reverse xs ++ [x])
                                      =: reverse ys ++ reverse (x .: xs)
                                      =: qed
ghci> runTP $ revApp @Integer
Inductive lemma: revApp
  Step: Base                            Q.E.D.
  Step: 1                               Q.E.D.
  Step: 2                               Q.E.D.
  Step: 3                               Q.E.D.
  Step: 4                               Q.E.D.
  Step: 5                               Q.E.D.
  Result:                               Q.E.D.
Functions proven terminating: sbv.reverse
[Proven] revApp :: Ɐxs ∷ [Integer] → Ɐys ∷ [Integer] → Bool

Features

Symbolic types — Booleans, signed/unsigned integers (8/16/32/64-bit and arbitrary-width), unbounded integers, reals, rationals, IEEE-754 floats, characters, strings, lists, tuples, sums, optionals, sets, enumerations, algebraic data types, and uninterpreted sorts.

Verificationprove/sat/allSat for property checking and model finding, safe/sAssert for assertion verification, dsat/dprove for delta-satisfiability, and QuickCheck integration.

Optimization — Minimize/maximize cost functions subject to constraints via optimize/maximize/minimize, with support for lexicographic, independent, and Pareto objectives.

Quantifiers and functions — Universal and existential quantifiers (including alternating), with skolemization for named bindings. Define SMT-level functions directly from Haskell via smtFunction, including recursive and mutually recursive definitions with automatic termination checking.

Theorem proving (TP) — Semi-automated inductive proofs (including strong induction) with equational reasoning chains. Includes termination checking, recursive and mutually recursive definitions, productive (co-recursive) functions, and user-defined measures.

Code generation — Compile symbolic programs to C as straight-line programs or libraries (compileToC, compileToCLib), and generate test vectors (genTest).

SMT interaction — Incremental mode via runSMT/query for programmatic solver interaction with a high-level typed API. Run multiple solvers simultaneously with proveWithAny/proveWithAll.

Algebraic Data Types

User-defined algebraic data types — including enumerations, recursive, and parametric types — are supported via mkSymbolic, with pattern matching via sCase (and its proof counterpart pCase):

{-# LANGUAGE QuasiQuotes     #-}
{-# LANGUAGE TemplateHaskell #-}

import Data.SBV

data Expr a = Val a
            | Add (Expr a) (Expr a)
            | Mul (Expr a) (Expr a)
            deriving Show

-- Make Expr symbolically available, named SExpr
mkSymbolic [''Expr]

eval :: SymVal a => (SBV a -> SBV a -> SBV a) -> (SBV a -> SBV a -> SBV a) -> SBV (Expr a) -> SBV a
eval add mul = smtFunction "eval" $ \e ->
    [sCase| e of
       Val v   -> v
       Add x y -> eval add mul x `add` eval add mul y
       Mul x y -> eval add mul x `mul` eval add mul y
    |]

The sCase construct supports nested pattern matching, as-patterns, guards, and wildcards, making programming with algebraic data types natural. Plain case expressions inside sCase are automatically treated as symbolic case-splits. The pCase variant provides the same features for proof case-splits in the theorem proving context.

Supported SMT Solvers

SBV communicates with solvers via the standard SMT-Lib interface:

Solver From Solver From
ABC Berkeley DReal CMU
Bitwuzla Stanford MathSAT FBK / Trento
Boolector JKU OpenSMT USI
CVC4 Stanford / Iowa Yices SRI
CVC5 Stanford / Iowa Z3 Microsoft

Z3 is the default solver. Use proveWith, satWith, etc. to select a different one (e.g., proveWith cvc5). See tested versions for details. Other SMT-Lib compatible solvers can be hooked up with minimal effort — get in touch if you'd like to use one not listed here.

A Selection of Examples

SBV ships with many worked examples. Here are some highlights:

Example Description
Sudoku Solve Sudoku puzzles using SMT constraints
N-Queens Solve the N-Queens placement puzzle
SEND + MORE = MONEY The classic cryptarithmetic puzzle
Fish/Zebra Einstein's logic puzzle
SQL Injection Find inputs that cause SQL injection vulnerabilities
Regex Crossword Solve regex crossword puzzles
BitTricks Verify bit-manipulation tricks from Stanford's bithacks collection
Legato multiplier Correctness proof of Legato's 8-bit multiplier
Prefix sum Ladner-Fischer prefix-sum implementation proof
AES AES encryption with C code generation
CRC Symbolic CRC computation with C code generation
Sqrt2 irrational Prove that the square root of 2 is irrational
Sorting Prove insertion sort, merge sort, and quick sort correct
Kadane Prove Kadane's maximum segment-sum algorithm correct
McCarthy91 Prove McCarthy's 91 function meets its specification
Binary search Prove binary search correct
Collatz Explore properties of the Collatz sequence
Infinitely many primes Prove there are infinitely many primes
Tautology checker A verified BDD-style tautology checker

Browse the full collection in Documentation.SBV.Examples on Hackage.

License

SBV is distributed under the BSD3 license. See COPYRIGHT and LICENSE for details.

Please report bugs and feature requests at the GitHub issue tracker.

Thanks

The following people made major contributions to SBV, by developing new features and contributing to the design in significant ways: Joel Burget, Brian Huffman, Brian Schroeder, and Jeffrey Young.

The following people reported bugs, provided comments/feedback, or contributed to the development of SBV in various ways: Andreas Abel, Ara Adkins, Andrew Anderson, Kanishka Azimi, Markus Barenhoff, Reid Barton, Ben Blaxill, Ian Blumenfeld, Guillaume Bouchard, Martin Brain, Ian Calvert, Oliver Charles, Christian Conkle, Matthew Danish, Iavor Diatchki, Alex Dixon, Robert Dockins, Thomas DuBuisson, Trevor Elliott, Gergő Érdi, John Erickson, Richard Fergie, Adam Foltzer, Joshua Gancher, Remy Goldschmidt, Jan Grant, Brad Hardy, Tom Hawkins, Greg Horn, Jan Hrcek, Georges-Axel Jaloyan, Anders Kaseorg, Tom Sydney Kerckhove, Lars Kuhtz, Piërre van de Laar, Pablo Lamela, Ken Friis Larsen, Andrew Lelechenko, Joe Leslie-Hurd, Nick Lewchenko, Brett Letner, Sirui Lu, Georgy Lukyanov, Martin Lundfall, Daniel Matichuk, John Matthews, Curran McConnell, Philipp Meyer, Fabian Mitterwallner, Joshua Moerman, Matt Parker, Jan Path, Matt Peddie, Lucas Peña, Matthew Pickering, Lee Pike, Gleb Popov, Rohit Ramesh, Geoffrey Ramseyer, Blake C. Rawlings, Jaro Reinders, Stephan Renatus, Dan Rosén, Ryan Scott, Eric Seidel, Austin Seipp, Andrés Sicard-Ramírez, Don Stewart, Greg Sullivan, Josef Svenningsson, George Thomas, May Torrence, Daniel Wagner, Sean Weaver, Robin Webbers, Eddy Westbrook, Nis Wegmann, Jared Ziegler, and Marco Zocca.

Thanks!