sbv-13.2: SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.
LicenseBSD3
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Documentation.SBV.Examples.Uninterpreted.EUFLogic

Description

Demonstrates the ability to generate uninterpreted functions of arbitrarily many arguments, whose types are generated programmatically. The high-level idea of this module is to provide a strongly-typed representation, using a GADT, of a logic that includes uninterpreted functions. This module then defines an interpretation of this logic into SBV, which it uses to perform SMT queries in the logic.

Synopsis

Types of the EUF Logic

data EUFType Source #

The datakind for the types in our EUF logic.

Constructors

Tp_Bool 
Tp_BV Natural 

Instances

Instances details
TestEquality TypeRepr Source #

TestEquality instance for Type representations

Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

testEquality :: forall (a :: EUFType) (b :: EUFType). TypeRepr a -> TypeRepr b -> Maybe (a :~: b) #

KnownEUFTypes ('[] :: [EUFType]) Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

knownEUFTypes :: TypeReprs ('[] :: [EUFType]) Source #

TestEquality TypeReprs Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

testEquality :: forall (a :: [EUFType]) (b :: [EUFType]). TypeReprs a -> TypeReprs b -> Maybe (a :~: b) #

(KnownEUFType tp, KnownEUFTypes tps) => KnownEUFTypes (tp ': tps) Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

knownEUFTypes :: TypeReprs (tp ': tps) Source #

data BVWidth (w :: Nat) Source #

A singleton type for natural numbers that can be used as the widths of bitvectors.

Constructors

(KnownNat w, BVIsNonZero w) => BVWidth (SNat w) 

Instances

Instances details
TestEquality BVWidth Source #

TestEquality instance for BVWidth.

Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

testEquality :: forall (a :: Nat) (b :: Nat). BVWidth a -> BVWidth b -> Maybe (a :~: b) #

knownBVWidth :: forall (w :: Nat). (KnownNat w, BVIsNonZero w) => BVWidth w Source #

Create a BVWidth object for a KnownNat that is non-zero

data TypeRepr (tp :: EUFType) where Source #

A singleton type that represents type-level EUFTypes at the object level

Constructors

Repr_Bool :: TypeRepr 'Tp_Bool 
Repr_BV :: forall (w :: Natural). BVWidth w -> TypeRepr ('Tp_BV w) 

Instances

Instances details
TestEquality TypeRepr Source #

TestEquality instance for Type representations

Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

testEquality :: forall (a :: EUFType) (b :: EUFType). TypeRepr a -> TypeRepr b -> Maybe (a :~: b) #

data TypeReprs (tps :: [EUFType]) where Source #

A list of TypeReprs for each type in a type-level list

Constructors

Repr_Nil :: TypeReprs ('[] :: [EUFType]) 
Repr_Cons :: forall (tp :: EUFType) (tps1 :: [EUFType]). TypeRepr tp -> TypeReprs tps1 -> TypeReprs (tp ': tps1) 

Instances

Instances details
TestEquality TypeReprs Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

testEquality :: forall (a :: [EUFType]) (b :: [EUFType]). TypeReprs a -> TypeReprs b -> Maybe (a :~: b) #

class KnownEUFType (tp :: EUFType) where Source #

An EUFType with a known TypeRepr representation

Instances

Instances details
KnownEUFType 'Tp_Bool Source #

Mapping from Tp_Bool

Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

(KnownNat w, BVIsNonZero w) => KnownEUFType ('Tp_BV w) Source #

Mapping from Tp_BV

Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

class KnownEUFTypes (tps :: [EUFType]) where Source #

A sequence of types EUFType with a known TypeReprs representation

Instances

Instances details
KnownEUFTypes ('[] :: [EUFType]) Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

knownEUFTypes :: TypeReprs ('[] :: [EUFType]) Source #

(KnownEUFType tp, KnownEUFTypes tps) => KnownEUFTypes (tp ': tps) Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

knownEUFTypes :: TypeReprs (tp ': tps) Source #

Operations of the EUF Logic

data UnintOp (ins :: [EUFType]) (out :: EUFType) Source #

An uninterpreted function in our EUF logic, which is a string name plus the input and output types.

Constructors

UnintOp 

data Op (ins :: [EUFType]) (out :: EUFType) where Source #

The operations of our EUF logic, which are indexed by a list of 0 or more input types and a single output type.

Constructors

Op_Unint :: forall (ins :: [EUFType]) (out :: EUFType). UnintOp ins out -> Op ins out 
Op_And :: Op '['Tp_Bool, 'Tp_Bool] 'Tp_Bool 
Op_Or :: Op '['Tp_Bool, 'Tp_Bool] 'Tp_Bool 
Op_Not :: Op '['Tp_Bool] 'Tp_Bool 
Op_BoolLit :: Bool -> Op ('[] :: [EUFType]) 'Tp_Bool 
Op_IfThenElse :: forall (out :: EUFType). TypeRepr out -> Op '['Tp_Bool, out, out] out 
Op_Plus :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w, 'Tp_BV w] ('Tp_BV w) 
Op_Minus :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w, 'Tp_BV w] ('Tp_BV w) 
Op_Times :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w, 'Tp_BV w] ('Tp_BV w) 
Op_Abs :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w] ('Tp_BV w) 
Op_Signum :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w] ('Tp_BV w) 
Op_BVLit :: forall (w :: Natural). BVWidth w -> Integer -> Op ('[] :: [EUFType]) ('Tp_BV w) 
Op_BVEq :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w, 'Tp_BV w] 'Tp_Bool 
Op_BVLt :: forall (w :: Natural). BVWidth w -> Op '['Tp_BV w, 'Tp_BV w] 'Tp_Bool 

mkUnintOp :: forall (ins :: [EUFType]) (out :: EUFType). (KnownEUFTypes ins, KnownEUFType out) => String -> Op ins out Source #

Create an uninterpreted Op of known type

opInsOut :: forall (ins :: [EUFType]) (out :: EUFType). Op ins out -> (TypeReprs ins, TypeRepr out) Source #

Get the input types and output type of an Op

opIns :: forall (ins :: [EUFType]) (out :: EUFType). Op ins out -> TypeReprs ins Source #

Get the input types of an Op

Expressions of the EUF Logic

data EUFExpr (tp :: EUFType) where Source #

The expressions of our EUF logic, which are just operations applied to argument expressions.

Constructors

EUFExpr :: forall (ins :: [EUFType]) (tp :: EUFType). Op ins tp -> EUFExprs ins -> EUFExpr tp 

Instances

Instances details
(KnownNat w, BVIsNonZero w) => Num (EUFExpr ('Tp_BV w)) Source # 
Instance details

Defined in Documentation.SBV.Examples.Uninterpreted.EUFLogic

Methods

(+) :: EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) #

(-) :: EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) #

(*) :: EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) #

negate :: EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) #

abs :: EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) #

signum :: EUFExpr ('Tp_BV w) -> EUFExpr ('Tp_BV w) #

fromInteger :: Integer -> EUFExpr ('Tp_BV w) #

data EUFExprs (tps :: [EUFType]) where Source #

A sequence of expressions for each type in a type-level list

Constructors

EUFExprsNil :: EUFExprs ('[] :: [EUFType]) 
EUFExprsCons :: forall (tp :: EUFType) (tps1 :: [EUFType]). EUFExpr tp -> EUFExprs tps1 -> EUFExprs (tp ': tps1) 

type family EUFExprFun (ins :: [EUFType]) (out :: EUFType) where ... Source #

Build the type EUFExpr in1 -> ... -> EUFExpr inn -> out

Equations

EUFExprFun ('[] :: [EUFType]) out = EUFExpr out 
EUFExprFun (tp ': tps) out = EUFExpr tp -> EUFExprFun tps out 

lambdaEUFExprFun :: forall (ins :: [EUFType]) (out :: EUFType). TypeReprs ins -> (EUFExprs ins -> EUFExpr out) -> EUFExprFun ins out Source #

Build an EUFExprFun from a function on EUFExprs

applyOp :: forall (ins :: [EUFType]) (out :: EUFType). Op ins out -> EUFExprFun ins out Source #

Apply an Op to EUFExprs for its input types, returning an EUFExpr for its output type

mkUnintExpr :: forall (tp :: EUFType). KnownEUFType tp => String -> EUFExpr tp Source #

Build an expression from an uninterpreted operation of a known type

Interpreting the EUF Logic into SBV

type family Type2SBV (tp :: EUFType) where ... Source #

Convert an EUFType to a type of SBV expressions

Equations

Type2SBV 'Tp_Bool = SBool 
Type2SBV ('Tp_BV w) = SBV (WordN w) 

type family OpTypes2SBV (ins :: [EUFType]) (out :: EUFType) where ... Source #

Convert the type inputs plus output of an Op to a function over SBV values

Equations

OpTypes2SBV ('[] :: [EUFType]) out = Type2SBV out 
OpTypes2SBV (tp ': tps) out = Type2SBV tp -> OpTypes2SBV tps out 

withSMTDefOpTypes :: forall (ins :: [EUFType]) (out :: EUFType) a. TypeReprs ins -> TypeRepr out -> (SMTDefinable (OpTypes2SBV ins out) => a) -> a Source #

Create an SMTDefinable instance for the type returned by OpTypes2SBV and pass it to a local function

data ResolvedUnintOp Source #

An uninterpreted function that has been resolved to an SBV function

Constructors

ResolvedUnintOp (UnintOp ins out) (OpTypes2SBV ins out) 

type UnintMap = Map String ResolvedUnintOp Source #

A Map for resolving uninterpreted operations

unintEnsure :: forall (ins :: [EUFType]) (out :: EUFType). UnintOp ins out -> UnintMap -> (OpTypes2SBV ins out, UnintMap) Source #

Look up the uninterpreted op associated with a String in an UnintMap at a particular type, raising an error if that String is associated with a different type. If the String is not associated with any uninterpreted function, create one and return it, updating the UnintMap.

type InterpM = State UnintMap Source #

The monad for interpreting EUFExprs into SBV, which is just a state monad over an UnintMap

runInterpM :: InterpM a -> a Source #

Run an InterpM computation starting with the empty UnintMap

interpOp :: forall (ins :: [EUFType]) (out :: EUFType). Op ins out -> InterpM (OpTypes2SBV ins out) Source #

Interpret an Op into a function over SBV values

interpEUFExpr :: forall (tp :: EUFType). EUFExpr tp -> InterpM (Type2SBV tp) Source #

Interpret an EUFExpr into an SBV value.

interpApplyEUFExprs :: forall ghost (out :: EUFType) (ins :: [EUFType]). ghost out -> OpTypes2SBV ins out -> EUFExprs ins -> InterpM (Type2SBV out) Source #

Apply an interpretation of an operator to the interpretations of a sequence of arguments for it.

interpEUF :: forall (a :: EUFType). EUFExpr a -> Type2SBV a Source #

Top-level call to interpret an EUFExpr to an SBV value

Examples

example :: EUFExpr 'Tp_Bool Source #

Example EUF problem

f (f (a) - f (b)) /= f (c), b >= a, a >= b + c, c >= 0

from https://goto.ucsd.edu/~rjhala/classes/sp13/cse291/slides/lec-smt.markdown.pdf noting that x >= y is the same as not (x < y). We have:

>>> sat $ interpEUF example
Satisfiable. Model:
  a =  996506182 :: Word32
  b = 3298461113 :: Word32
  c = 1445036292 :: Word32

  f :: Word32 -> Word32
  f 0          = 4188219399
  f 1445036292 = 285239361
  f 3298461113 = 4054018119
  f 996506182  = 4054018119
  f _          = 0

Note that the original example is unsatisfiable over integers. It is however satisfiable over 32-bit words, hence the model above.