{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.ProofTools.AddHorn where
import Data.SBV
#ifndef HADDOCK
#endif
type Inv = (SInteger, SInteger, SInteger, SInteger) -> SBool
type VC = Forall "x" Integer -> Forall "y" Integer -> Forall "z" Integer -> Forall "i" Integer -> SBool
quantify :: Inv -> VC
quantify :: Inv -> VC
quantify Inv
f = \(Forall SInteger
x) (Forall SInteger
y) (Forall SInteger
z) (Forall SInteger
i) -> Inv
f (SInteger
x, SInteger
y, SInteger
z, SInteger
i)
vc1 :: Inv -> VC
vc1 :: Inv -> VC
vc1 Inv
inv = Inv -> VC
quantify (Inv -> VC) -> Inv -> VC
forall a b. (a -> b) -> a -> b
$ \(SInteger
x, SInteger
y, SInteger
z, SInteger
i) -> SInteger
z SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
x SBool -> SBool -> SBool
.&& SInteger
i SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
0 SBool -> SBool -> SBool
.&& SInteger
y SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.> SInteger
0 SBool -> SBool -> SBool
.=> Inv
inv (SInteger
x, SInteger
y, SInteger
z, SInteger
i)
vc2 :: Inv -> VC
vc2 :: Inv -> VC
vc2 Inv
inv = Inv -> VC
quantify (Inv -> VC) -> Inv -> VC
forall a b. (a -> b) -> a -> b
$ \(SInteger
x, SInteger
y, SInteger
z, SInteger
i) -> Inv
inv (SInteger
x, SInteger
y, SInteger
z, SInteger
i) SBool -> SBool -> SBool
.&& SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< SInteger
y SBool -> SBool -> SBool
.=> Inv
inv (SInteger
x, SInteger
y, SInteger
zSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1, SInteger
iSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1)
vc3 :: Inv -> VC
vc3 :: Inv -> VC
vc3 Inv
inv = Inv -> VC
quantify (Inv -> VC) -> Inv -> VC
forall a b. (a -> b) -> a -> b
$ \(SInteger
x, SInteger
y, SInteger
z, SInteger
i) -> Inv
inv (SInteger
x, SInteger
y, SInteger
z, SInteger
i) SBool -> SBool -> SBool
.&& SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
y SBool -> SBool -> SBool
.=> SInteger
z SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
x SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
y
synthesize :: IO SatResult
synthesize :: IO SatResult
synthesize = ConstraintSet -> IO SatResult
forall a. Satisfiable a => a -> IO SatResult
sat ConstraintSet
vcs
where invariant :: Inv
invariant :: Inv
invariant = String -> [String] -> Inv
forall a. SMTDefinable a => String -> [String] -> a
uninterpretWithArgs String
"invariant" [String
"x", String
"y", String
"z", String
"i"]
vcs :: ConstraintSet
vcs :: ConstraintSet
vcs = do Logic -> ConstraintSet
forall (m :: * -> *). SolverContext m => Logic -> m ()
setLogic (Logic -> ConstraintSet) -> Logic -> ConstraintSet
forall a b. (a -> b) -> a -> b
$ String -> Logic
CustomLogic String
"HORN"
VC -> ConstraintSet
forall a. QuantifiedBool a => a -> ConstraintSet
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain (VC -> ConstraintSet) -> VC -> ConstraintSet
forall a b. (a -> b) -> a -> b
$ Inv -> VC
vc1 Inv
invariant
VC -> ConstraintSet
forall a. QuantifiedBool a => a -> ConstraintSet
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain (VC -> ConstraintSet) -> VC -> ConstraintSet
forall a b. (a -> b) -> a -> b
$ Inv -> VC
vc2 Inv
invariant
VC -> ConstraintSet
forall a. QuantifiedBool a => a -> ConstraintSet
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain (VC -> ConstraintSet) -> VC -> ConstraintSet
forall a b. (a -> b) -> a -> b
$ Inv -> VC
vc3 Inv
invariant
verify :: IO ThmResult
verify :: IO ThmResult
verify = SBool -> IO ThmResult
forall a. Provable a => a -> IO ThmResult
prove SBool
vcs
where invariant :: Inv
invariant :: Inv
invariant (SInteger
x, SInteger
y, SInteger
z, SInteger
i) = SInteger
x SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ (-SInteger
z) SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.> (-SInteger
1) SBool -> SBool -> SBool
.&& SInteger
x SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ (-SInteger
z) SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
i SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.< SInteger
1 SBool -> SBool -> SBool
.&& SInteger
x SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
y SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ (-SInteger
z) SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.> (-SInteger
1)
vcs :: SBool
vcs :: SBool
vcs = VC -> SBool
forall a. QuantifiedBool a => a -> SBool
quantifiedBool (Inv -> VC
vc1 Inv
invariant)
SBool -> SBool -> SBool
.&& VC -> SBool
forall a. QuantifiedBool a => a -> SBool
quantifiedBool (Inv -> VC
vc3 Inv
invariant)
SBool -> SBool -> SBool
.&& VC -> SBool
forall a. QuantifiedBool a => a -> SBool
quantifiedBool (Inv -> VC
vc3 Inv
invariant)