-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | k-induction for Copilot. -- -- Some tools to prove properties on Copilot programs with k-induction -- model checking. -- -- Copilot is a stream (i.e., infinite lists) domain-specific language -- (DSL) in Haskell that compiles into embedded C. Copilot contains an -- interpreter, multiple back-end compilers, and other verification -- tools. -- -- A tutorial, examples, and other information are available at -- https://copilot-language.github.io. @package copilot-theorem @version 3.20 -- | Connection to theorem provers. module Copilot.Theorem.Prove -- | Output produced by a prover, containing the Status of the proof -- and additional information. data Output Output :: Status -> [String] -> Output -- | Status returned by a prover when given a specification and a property -- to prove. data Status Sat :: Status Valid :: Status Invalid :: Status Unknown :: Status Error :: Status -- | A connection to a prover able to check the satisfiability of -- specifications. -- -- The most important is askProver, which takes 3 arguments : -- -- data Prover Prover :: String -> (Spec -> IO r) -> (r -> [PropId] -> [PropId] -> IO Output) -> (r -> IO ()) -> Prover [proverName] :: Prover -> String [startProver] :: Prover -> Spec -> IO r [askProver] :: Prover -> r -> [PropId] -> [PropId] -> IO Output [closeProver] :: Prover -> r -> IO () -- | A unique property identifier type PropId = String -- | Reference to a property. data PropRef a [PropRef] :: PropId -> PropRef a -- | A proof scheme with unit result. type Proof a = ProofScheme a () -- | A sequence of computations that generate a trace of required prover -- Actions. type UProof = Writer [Action] () -- | A proof scheme is a sequence of computations that compute a result and -- generate a trace of required prover Actions. data ProofScheme a b [Proof] :: Writer [Action] b -> ProofScheme a b -- | Prover actions. data Action [Check] :: Prover -> Action [Assume] :: PropId -> Action [Admit] :: Action -- | Empty datatype to mark proofs of universally quantified predicates. data Universal -- | Empty datatype to mark proofs of existentially quantified predicates. data Existential -- | Record a requirement for satisfiability checking. check :: Prover -> Proof a -- | Try to prove a property in a specification with a given proof scheme. -- -- Return True if a proof of satisfiability or validity is found, -- false otherwise. prove :: Spec -> PropId -> UProof -> IO Bool -- | Combine two provers producing a new prover that will run both provers -- in parallel and combine their outputs. -- -- The results produced by the provers must be consistent. For example, -- if one of the provers indicates that a property is Valid while -- another indicates that it is Invalid, the combination of both -- provers will return an Error. combine :: Prover -> Prover -> Prover instance GHC.Base.Functor (Copilot.Theorem.Prove.ProofScheme a) instance GHC.Base.Applicative (Copilot.Theorem.Prove.ProofScheme a) instance GHC.Base.Monad (Copilot.Theorem.Prove.ProofScheme a) -- | Connections to various SMT solvers and theorem provers. module Copilot.Theorem.Prover.SMT -- | Backend to an SMT solver or theorem prover. data Backend a -- | Format of SMT-Lib commands. class Show a => SmtFormat a -- | Type used to represent SMT-lib commands. -- -- Use the interface in SmtFormat to create such commands. data SmtLib -- | Type used to represent TPTP expressions. -- -- Although this type implements the SmtFormat interface, only -- assert is actually used. data Tptp -- | Backend to the Yices 2 SMT solver. -- -- It enables non-linear arithmetic (QF_NRA), which means MCSat -- will be used. -- -- The command yices-smt2 must be in the user's PATH. yices :: Backend SmtLib -- | Backend to the dReal SMT solver. -- -- It enables non-linear arithmetic (QF_NRA). -- -- The libraries for dReal must be installed and perl must be in -- the user's PATH. dReal :: Backend SmtLib -- | Backend to the Alt-Ergo SMT solver. -- -- It enables support for uninterpreted functions and mixed nonlinear -- arithmetic (QF_NIRA). -- -- The command alt-ergo.opt must be in the user's PATH. altErgo :: Backend SmtLib -- | Backend to the MetiTaski theorem prover. -- -- The command metit must be in the user's PATH. -- -- The argument string is the path to the tptp subdirectory of -- the metitarski install location. metit :: String -> Backend Tptp -- | Backend to the Z3 theorem prover. -- -- The command z3 must be in the user's PATH. z3 :: Backend SmtLib -- | Backend to the cvc4 SMT solver. -- -- It enables support for uninterpreted functions and mixed nonlinear -- arithmetic (QF_NIRA). -- -- The command cvc4 must be in the user's PATH. cvc4 :: Backend SmtLib -- | Backend to the Mathsat SMT solver. -- -- It enables non-linear arithmetic (QF_NRA). -- -- The command mathsat must be in the user's PATH. mathsat :: Backend SmtLib -- | Options to configure the provers. data Options Options :: Word32 -> Word32 -> Bool -> Options -- | Initial k for the k-induction algorithm. [startK] :: Options -> Word32 -- | The maximum number of steps of the k-induction algorithm the prover -- runs before giving up. [maxK] :: Options -> Word32 -- | If debug is set to True, the SMTLib/TPTP queries -- produced by the prover are displayed in the standard output. [debug] :: Options -> Bool -- | Tactic to find a proof by standard 1-induction. -- -- The values for startK and maxK in the options are -- ignored. induction :: SmtFormat a => Options -> Backend a -> Proof Universal -- | Tactic to find a proof by k-induction. kInduction :: SmtFormat a => Options -> Backend a -> Proof Universal -- | Tactic to find only a proof of satisfiability. onlySat :: SmtFormat a => Options -> Backend a -> Proof Existential -- | Tactic to find only a proof of validity. onlyValidity :: SmtFormat a => Options -> Backend a -> Proof Universal -- | A class for types with a default value. class () => Default a -- | The default value for this type. def :: Default a => a instance GHC.Classes.Eq Copilot.Theorem.Prover.SMT.SolverId instance GHC.Classes.Ord Copilot.Theorem.Prover.SMT.SolverId instance GHC.Show.Show Copilot.Theorem.Prover.SMT.SolverId instance Data.Default.Class.Default Copilot.Theorem.Prover.SMT.Options -- | Highly automated proof techniques are a necessary step for the -- widespread adoption of formal methods in the software industry. -- Moreover, it could provide a partial answer to one of its main issue -- which is scalability. -- -- Copilot-theorem is a Copilot library aimed at checking automatically -- some safety properties on Copilot programs. It includes: -- -- module Copilot.Theorem -- | Instantiate a universal proof into an existential proof. instantiate :: Proof Universal -> Proof Existential -- | Assume that a property, given by reference, holds. assume :: PropRef Universal -> Proof a -- | Assume that the current goal holds. admit :: Proof a -- | A proof scheme with unit result. type Proof a = ProofScheme a () -- | A unique property identifier type PropId = String -- | Reference to a property. data PropRef a -- | Empty datatype to mark proofs of universally quantified predicates. data Universal -- | Empty datatype to mark proofs of existentially quantified predicates. data Existential -- | A prover backend based on Kind2. module Copilot.Theorem.Kind2.Prover -- | Options for Kind2 data Options Options :: Int -> Options -- | Upper bound on the number of unrolling that base and step will -- perform. A value of 0 means unlimited. [bmcMax] :: Options -> Int -- | A prover backend based on Kind2. -- -- The executable kind2 must exist and its location be in the -- PATH. kind2Prover :: Options -> Prover instance Data.Default.Class.Default Copilot.Theorem.Kind2.Prover.Options -- | Copilot backend for the Kind 2 SMT based model checker. module Copilot.Theorem.Kind2 -- | Pretty print a Kind2 file. prettyPrint :: File -> String -- | Produce a Kind2 file that checks the properties specified. toKind2 :: Style -> [PropId] -> [PropId] -> TransSys -> File -- | Style of the Kind2 files produced: modular (with multiple separate -- nodes), or all inlined (with only one node). -- -- In the modular style, the graph is simplified to remove cycles by -- collapsing all nodes participating in a strongly connected components. -- -- In the inlined style, the structure of the modular transition system -- is discarded and the graph is first turned into a non-modular -- transition system with only one node, which can be then -- converted into a Kind2 file. data Style Inlined :: Style Modular :: Style -- | A file is a sequence of predicates and propositions. data File File :: [PredDef] -> [Prop] -> File [filePreds] :: File -> [PredDef] [fileProps] :: File -> [Prop] -- | A proposition is defined by a term. data Prop Prop :: String -> Term -> Prop [propName] :: Prop -> String [propTerm] :: Prop -> Term -- | A predicate definition. data PredDef PredDef :: String -> [StateVarDef] -> Term -> Term -> PredDef -- | Identifier for the predicate. [predId] :: PredDef -> String -- | Variables identifying the states in the underlying state transition -- system. [predStateVars] :: PredDef -> [StateVarDef] -- | Predicate that holds for initial states. [predInit] :: PredDef -> Term -- | Predicate that holds for two states, if there is state transition -- between them. [predTrans] :: PredDef -> Term -- | A definition of a state variable. data StateVarDef StateVarDef :: String -> Type -> [StateVarFlag] -> StateVarDef -- | Name of the variable. [varId] :: StateVarDef -> String -- | Type of the variable. [varType] :: StateVarDef -> Type -- | Flags for the variable. [varFlags] :: StateVarDef -> [StateVarFlag] -- | Types used in Kind2 files to represent Copilot types. -- -- The Kind2 backend provides functions to, additionally, constrain the -- range of numeric values depending on their Copilot type -- (Int8, Int16, etc.). data Type Int :: Type Real :: Type Bool :: Type -- | Possible flags for a state variable. data StateVarFlag FConst :: StateVarFlag -- | Type of the predicate, either belonging to an initial state or a pair -- of states with a transition. data PredType Init :: PredType Trans :: PredType -- | Datatype to describe a term in the Kind language. data Term ValueLiteral :: String -> Term PrimedStateVar :: String -> Term StateVar :: String -> Term FunApp :: String -> [Term] -> Term PredApp :: String -> PredType -> [Term] -> Term -- | Spec properties are translated into the language of SMT solvers using -- What4. A backend solver is then used to prove the property is -- true. The technique is sound, but incomplete. If a property is proved -- true by this technique, then it can be guaranteed to be true. However, -- if a property is not proved true, that does not mean it isn't true; -- the proof may fail because the given property is not inductive. -- -- We perform k-induction on all the properties in a given -- specification where k is chosen to be the maximum amount of -- delay on any of the involved streams. This is a heuristic choice, but -- often effective. module Copilot.Theorem.What4 -- | Attempt to prove all of the properties in a spec via an SMT solver -- (which must be installed locally on the host). Return an association -- list mapping the names of each property to the result returned by the -- solver. prove :: Solver -> Spec -> IO [(Name, SatResult)] -- | The solvers supported by the what4 backend. data Solver CVC4 :: Solver DReal :: Solver Yices :: Solver Z3 :: Solver -- | The prove function returns results of this form for each -- property in a spec. data SatResult Valid :: SatResult Invalid :: SatResult Unknown :: SatResult -- | Given a Copilot specification, compute all of the symbolic states -- necessary to carry out a bisimulation proof that establishes a -- correspondence between the states of the Copilot stream program and -- the C code that copilot-c99 would generate for that Copilot -- program. computeBisimulationProofBundle :: IsInterpretedFloatSymExprBuilder sym => sym -> [String] -> Spec -> IO (BisimulationProofBundle sym) -- | A collection of all of the symbolic states necessary to carry out a -- bisimulation proof. data BisimulationProofBundle sym BisimulationProofBundle :: BisimulationProofState sym -> BisimulationProofState sym -> BisimulationProofState sym -> [(Name, Some Type, XExpr sym)] -> [(Name, Pred sym, [(Some Type, XExpr sym)])] -> [Pred sym] -> [Pred sym] -> BisimulationProofBundle sym -- | The state of the global variables at program startup [initialStreamState] :: BisimulationProofBundle sym -> BisimulationProofState sym -- | The stream state prior to invoking the step function [preStreamState] :: BisimulationProofBundle sym -> BisimulationProofState sym -- | The stream state after invoking the step function [postStreamState] :: BisimulationProofBundle sym -> BisimulationProofState sym -- | A list of external streams, where each tuple contains: -- --
    --
  1. The name of the stream
  2. --
  3. The type of the stream
  4. --
  5. The value of the stream represented as a fresh constant
  6. --
[externalInputs] :: BisimulationProofBundle sym -> [(Name, Some Type, XExpr sym)] -- | A list of trigger functions, where each tuple contains: -- --
    --
  1. The name of the function
  2. --
  3. A formula representing the guarded condition
  4. --
  5. The arguments to the function, where each argument is represented -- as a type-value pair
  6. --
[triggerState] :: BisimulationProofBundle sym -> [(Name, Pred sym, [(Some Type, XExpr sym)])] -- | User-provided property assumptions [assumptions] :: BisimulationProofBundle sym -> [Pred sym] -- | Side conditions related to partial operations [sideConds] :: BisimulationProofBundle sym -> [Pred sym] -- | The state of a bisimulation proof at a particular step. newtype BisimulationProofState sym BisimulationProofState :: [(Id, Some Type, [XExpr sym])] -> BisimulationProofState sym -- | A list of tuples containing: -- --
    --
  1. The name of a stream
  2. --
  3. The type of the stream
  4. --
  5. The list of values in the stream description
  6. --
[streamState] :: BisimulationProofState sym -> [(Id, Some Type, [XExpr sym])] -- | The What4 representation of a copilot expression. We do not attempt to -- track the type of the inner expression at the type level, but instead -- lump everything together into the XExpr sym type. The only -- reason this is a GADT is for the array case; we need to know that the -- array length is strictly positive. data XExpr sym [XBool] :: SymExpr sym BaseBoolType -> XExpr sym [XInt8] :: SymExpr sym (BaseBVType 8) -> XExpr sym [XInt16] :: SymExpr sym (BaseBVType 16) -> XExpr sym [XInt32] :: SymExpr sym (BaseBVType 32) -> XExpr sym [XInt64] :: SymExpr sym (BaseBVType 64) -> XExpr sym [XWord8] :: SymExpr sym (BaseBVType 8) -> XExpr sym [XWord16] :: SymExpr sym (BaseBVType 16) -> XExpr sym [XWord32] :: SymExpr sym (BaseBVType 32) -> XExpr sym [XWord64] :: SymExpr sym (BaseBVType 64) -> XExpr sym [XFloat] :: SymExpr sym (SymInterpretedFloatType sym SingleFloat) -> XExpr sym [XDouble] :: SymExpr sym (SymInterpretedFloatType sym DoubleFloat) -> XExpr sym [XEmptyArray] :: XExpr sym [XArray] :: 1 <= n => Vector n (XExpr sym) -> XExpr sym [XStruct] :: [XExpr sym] -> XExpr sym instance GHC.Show.Show Copilot.Theorem.What4.SatResult