sbv-11.0: SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.
Copyright(c) Levent Erkok
LicenseBSD3
Maintainererkokl@gmail.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Data.SBV.Tools.KnuckleDragger

Description

A lightweight theorem proving like interface, built on top of SBV. Inspired by and modeled after Philip Zucker's tool with the same name, see http://github.com/philzook58/knuckledragger.

See the directory Documentation.SBV.Examples.KnuckleDragger for various examples.

Synopsis

Propositions and their proofs

type Proposition a = (QuantifiedBool a, QNot a, Skolemize (NegatesTo a), Satisfiable (Symbolic (SkolemsTo (NegatesTo a))), Constraint Symbolic (SkolemsTo (NegatesTo a))) Source #

A proposition is something SBV is capable of proving/disproving. We capture this with a set of constraints. This type might look scary, but for the most part you can ignore it and treat it as anything you can pass to prove or sat in SBV.

data Proof Source #

Proof for a property. This type is left abstract, i.e., the only way to create on is via a call to lemma/theorem etc., ensuring soundness. (Note that the trusted-code base here is still large: The underlying solver, SBV, and KnuckleDragger kernel itself. But this mechanism ensures we can't create proven things out of thin air, following the standard LCF methodology.)

Instances

Instances details
Show Proof Source #

Show instance for Proof

Instance details

Defined in Data.SBV.Tools.KDKernel

Methods

showsPrec :: Int -> Proof -> ShowS #

show :: Proof -> String #

showList :: [Proof] -> ShowS #

Adding axioms/definitions

axiom :: Proposition a => String -> a -> KD Proof Source #

Accept the given definition as a fact. Usually used to introduce definitial axioms, giving meaning to uninterpreted symbols. Note that we perform no checks on these propositions, if you assert nonsense, then you get nonsense back. So, calls to axiom should be limited to definitions, or basic axioms (like commutativity, associativity) of uninterpreted function symbols.

Basic proofs

lemma :: Proposition a => String -> a -> [Proof] -> KD Proof Source #

Prove a given statement, using auxiliaries as helpers. Using the default solver.

lemmaWith :: Proposition a => SMTConfig -> String -> a -> [Proof] -> KD Proof Source #

Prove a given statement, using auxiliaries as helpers. Using the given solver.

theorem :: Proposition a => String -> a -> [Proof] -> KD Proof Source #

Prove a given statement, using auxiliaries as helpers. Essentially the same as lemma, except for the name, using the default solver.

theoremWith :: Proposition a => SMTConfig -> String -> a -> [Proof] -> KD Proof Source #

Prove a given statement, using auxiliaries as helpers. Essentially the same as lemmaWith, except for the name.

Chain of reasoning

chainLemma :: (ChainLemma steps step, Proposition a) => String -> a -> steps -> [Proof] -> KD Proof Source #

Prove a property via a series of equality steps, using the default solver. Let H be a list of already established lemmas. Let P be a property we wanted to prove, named name. Consider a call of the form chainLemma name P [A, B, C, D] H. Note that H is a list of already proven facts, ensured by the type signature. We proceed as follows:

  • Prove: H -> A == B
  • Prove: H && A == B -> B == C
  • Prove: H && A == B && B == C -> C == D
  • Prove: H && A == B && B == C && C == D -> P
  • If all of the above steps succeed, conclude P.

Note that if the type of steps (i.e., A .. D above) is SBool, then we use implication as opposed to equality; which better captures line of reasoning.

So, chain-lemma is essentially modus-ponens, applied in a sequence of stepwise equality reasoning in the case of non-boolean steps.

If there are no helpers given (i.e., if H is empty), then this call is equivalent to lemmaWith. If H is a singleton, then we error-out. A single step in H indicates a user-error, since there's no sequence of steps to reason about.

chainLemmaWith :: (ChainLemma steps step, Proposition a) => SMTConfig -> String -> a -> steps -> [Proof] -> KD Proof Source #

Prove a property via a series of equality steps, using the given solver.

chainTheorem :: (ChainLemma steps step, Proposition a) => String -> a -> steps -> [Proof] -> KD Proof Source #

Same as chainLemma, except tagged as Theorem

chainTheoremWith :: (ChainLemma steps step, Proposition a) => SMTConfig -> String -> a -> steps -> [Proof] -> KD Proof Source #

Same as chainLemmaWith, except tagged as Theorem

Induction

class Induction a where Source #

Given a predicate, return an induction principle for it. Typically, we only have one viable induction principle for a given type, but we allow for alternative ones.

Minimal complete definition

induct

Instances

Instances details
(SymVal a, SymVal b, SymVal c) => Induction (SBV a -> SBV b -> SBV c -> SInteger -> SBool) Source #

Induction over four argument predicates, with last argument SInteger.

Instance details

Defined in Data.SBV.Tools.KDKernel

Methods

induct :: (SBV a -> SBV b -> SBV c -> SInteger -> SBool) -> Proof Source #

inductAlt1 :: (SBV a -> SBV b -> SBV c -> SInteger -> SBool) -> Proof Source #

inductAlt2 :: (SBV a -> SBV b -> SBV c -> SInteger -> SBool) -> Proof Source #

(SymVal a, SymVal b, SymVal c, SymVal e) => Induction (SBV a -> SBV b -> SBV c -> SList e -> SBool) Source #

Induction over four argument predicates, with last argument a list.

Instance details

Defined in Data.SBV.Tools.KDKernel

Methods

induct :: (SBV a -> SBV b -> SBV c -> SList e -> SBool) -> Proof Source #

inductAlt1 :: (SBV a -> SBV b -> SBV c -> SList e -> SBool) -> Proof Source #

inductAlt2 :: (SBV a -> SBV b -> SBV c -> SList e -> SBool) -> Proof Source #

(SymVal a, SymVal b) => Induction (SBV a -> SBV b -> SInteger -> SBool) Source #

Induction over three argument predicates, with last argument SInteger.

Instance details

Defined in Data.SBV.Tools.KDKernel

Methods

induct :: (SBV a -> SBV b -> SInteger -> SBool) -> Proof Source #

inductAlt1 :: (SBV a -> SBV b -> SInteger -> SBool) -> Proof Source #

inductAlt2 :: (SBV a -> SBV b -> SInteger -> SBool) -> Proof Source #

(SymVal a, SymVal b, SymVal e) => Induction (SBV a -> SBV b -> SList e -> SBool) Source #

Induction over three argument predicates, with last argument a list.

Instance details

Defined in Data.SBV.Tools.KDKernel

Methods

induct :: (SBV a -> SBV b -> SList e -> SBool) -> Proof Source #

inductAlt1 :: (SBV a -> SBV b -> SList e -> SBool) -> Proof Source #

inductAlt2 :: (SBV a -> SBV b -> SList e -> SBool) -> Proof Source #

SymVal a => Induction (SBV a -> SInteger -> SBool) Source #

Induction over two argument predicates, with the last argument SInteger.

Instance details

Defined in Data.SBV.Tools.KDKernel

(SymVal a, SymVal e) => Induction (SBV a -> SList e -> SBool) Source #

Induction over two argument predicates, with last argument a list.

Instance details

Defined in Data.SBV.Tools.KDKernel

Methods

induct :: (SBV a -> SList e -> SBool) -> Proof Source #

inductAlt1 :: (SBV a -> SList e -> SBool) -> Proof Source #

inductAlt2 :: (SBV a -> SList e -> SBool) -> Proof Source #

Induction (SInteger -> SBool) Source #

Induction over SInteger. We provide various induction principles here: The first one is over naturals, will only prove predicates that explicitly restrict the argument to >= 0. The second and third ones are induction over the entire range of integers, two different principles that might work better for different problems.

Instance details

Defined in Data.SBV.Tools.KDKernel

SymVal a => Induction (SList a -> SBool) Source #

Induction over lists

Instance details

Defined in Data.SBV.Tools.KDKernel

Faking proofs

sorry :: Proof Source #

A manifestly false theorem. This is useful when we want to prove a theorem that the underlying solver cannot deal with, or if we want to postpone the proof for the time being. KnuckleDragger will keep track of the uses of sorry and will print them appropriately while printing proofs.

Running KnuckleDragger proofs

data KD a Source #

Monad for running KnuckleDragger proofs in.

Instances

Instances details
MonadIO KD Source # 
Instance details

Defined in Data.SBV.Tools.KDUtils

Methods

liftIO :: IO a -> KD a #

Applicative KD Source # 
Instance details

Defined in Data.SBV.Tools.KDUtils

Methods

pure :: a -> KD a #

(<*>) :: KD (a -> b) -> KD a -> KD b #

liftA2 :: (a -> b -> c) -> KD a -> KD b -> KD c #

(*>) :: KD a -> KD b -> KD b #

(<*) :: KD a -> KD b -> KD a #

Functor KD Source # 
Instance details

Defined in Data.SBV.Tools.KDUtils

Methods

fmap :: (a -> b) -> KD a -> KD b #

(<$) :: a -> KD b -> KD a #

Monad KD Source # 
Instance details

Defined in Data.SBV.Tools.KDUtils

Methods

(>>=) :: KD a -> (a -> KD b) -> KD b #

(>>) :: KD a -> KD b -> KD b #

return :: a -> KD a #

MonadFail KD Source # 
Instance details

Defined in Data.SBV.Tools.KDUtils

Methods

fail :: String -> KD a #

MonadReader SMTConfig KD Source # 
Instance details

Defined in Data.SBV.Tools.KDUtils

Methods

ask :: KD SMTConfig #

local :: (SMTConfig -> SMTConfig) -> KD a -> KD a #

reader :: (SMTConfig -> a) -> KD a #

runKD :: KD a -> IO a Source #

Run a KD proof, using the default configuration.

runKDWith :: SMTConfig -> KD a -> IO a Source #

Run a KD proof, using the given configuration.