{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Data.SBV.Tools.KDKernel (
Proposition, Proof
, axiom
, lemma, lemmaWith, lemmaGen
, theorem, theoremWith
, Induction(..)
, sorry
) where
import Control.Monad.Trans (liftIO)
import Control.Monad.Reader (ask)
import Data.List (intercalate, sort, nub)
import Data.SBV
import Data.SBV.Core.Data (Constraint)
import Data.SBV.Tools.KDUtils
import qualified Data.SBV.List as SL
type Proposition a = ( QuantifiedBool a
, QNot a
, Skolemize (NegatesTo a)
, Satisfiable (Symbolic (SkolemsTo (NegatesTo a)))
, Constraint Symbolic (SkolemsTo (NegatesTo a))
)
data RootOfTrust = None
| Self
| Prop String
data Proof = Proof { Proof -> RootOfTrust
rootOfTrust :: RootOfTrust
, Proof -> Bool
isUserAxiom :: Bool
, Proof -> SBV Bool
getProof :: SBool
, Proof -> String
proofName :: String
}
instance Show Proof where
show :: Proof -> String
show Proof{RootOfTrust
rootOfTrust :: Proof -> RootOfTrust
rootOfTrust :: RootOfTrust
rootOfTrust, Bool
isUserAxiom :: Proof -> Bool
isUserAxiom :: Bool
isUserAxiom, String
proofName :: Proof -> String
proofName :: String
proofName} = Char
'[' Char -> ShowS
forall a. a -> [a] -> [a]
: String
tag String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"] " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
proofName
where tag :: String
tag | Bool
isUserAxiom = String
"Axiom"
| Bool
True = case RootOfTrust
rootOfTrust of
RootOfTrust
None -> String
"Proven"
RootOfTrust
Self -> String
"Sorry"
Prop String
s -> String
"Modulo: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
s
axiom :: Proposition a => String -> a -> KD Proof
axiom :: forall a. Proposition a => String -> a -> KD Proof
axiom String
nm a
p = do Bool -> String -> [String] -> KD Int
start Bool
False String
"Axiom" [String
nm] KD Int -> (Int -> KD ()) -> KD ()
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> Int -> KD ()
finish String
"Axiom."
Proof -> KD Proof
forall a. a -> KD a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> a -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
nm a
p) { isUserAxiom = True }
internalAxiom :: Proposition a => String -> a -> Proof
internalAxiom :: forall a. Proposition a => String -> a -> Proof
internalAxiom String
nm a
p = Proof { rootOfTrust :: RootOfTrust
rootOfTrust = RootOfTrust
None
, isUserAxiom :: Bool
isUserAxiom = Bool
False
, getProof :: SBV Bool
getProof = String -> SBV Bool -> SBV Bool
forall a. SymVal a => String -> SBV a -> SBV a
label String
nm (a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
p)
, proofName :: String
proofName = String
nm
}
sorry :: Proof
sorry :: Proof
sorry = Proof { rootOfTrust :: RootOfTrust
rootOfTrust = RootOfTrust
Self
, isUserAxiom :: Bool
isUserAxiom = Bool
False
, getProof :: SBV Bool
getProof = String -> SBV Bool -> SBV Bool
forall a. SymVal a => String -> SBV a -> SBV a
label String
"sorry" ((Forall Any Bool -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool Forall Any Bool -> SBV Bool
forall {nm :: Symbol}. Forall nm Bool -> SBV Bool
p)
, proofName :: String
proofName = String
"sorry"
}
where
p :: Forall nm Bool -> SBV Bool
p (Forall (SBV Bool
x :: SBool)) = String -> SBV Bool -> SBV Bool
forall a. SymVal a => String -> SBV a -> SBV a
label String
"SORRY: KnuckleDragger, proof uses \"sorry\"" SBV Bool
x
lemmaGen :: Proposition a => SMTConfig -> String -> [String] -> a -> [Proof] -> KD Proof
lemmaGen :: forall a.
Proposition a =>
SMTConfig -> String -> [String] -> a -> [Proof] -> KD Proof
lemmaGen cfg :: SMTConfig
cfg@SMTConfig{Bool
verbose :: Bool
verbose :: SMTConfig -> Bool
verbose} String
what [String]
nms a
inputProp [Proof]
by = do
tab <- Bool -> String -> [String] -> KD Int
start Bool
verbose String
what [String]
nms
let nm = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"." [String]
nms
good = do String -> Int -> KD ()
finish (String
"Q.E.D." String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
modulo) Int
tab
Proof -> KD Proof
forall a. a -> KD a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Proof { rootOfTrust :: RootOfTrust
rootOfTrust = RootOfTrust
ros
, isUserAxiom :: Bool
isUserAxiom = Bool
False
, getProof :: SBV Bool
getProof = String -> SBV Bool -> SBV Bool
forall a. SymVal a => String -> SBV a -> SBV a
label String
nm (a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
inputProp)
, proofName :: String
proofName = String
nm
}
where parentRoots :: [RootOfTrust]
parentRoots = (Proof -> RootOfTrust) -> [Proof] -> [RootOfTrust]
forall a b. (a -> b) -> [a] -> [b]
map Proof -> RootOfTrust
rootOfTrust [Proof]
by
hasSelf :: Bool
hasSelf = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [()] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [() | RootOfTrust
Self <- [RootOfTrust]
parentRoots]
depNames :: [String]
depNames = [String] -> [String]
forall a. Eq a => [a] -> [a]
nub ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
forall a. Ord a => [a] -> [a]
sort [String
p | Prop String
p <- [RootOfTrust]
parentRoots]
(RootOfTrust
ros, String
modulo)
| Bool -> Bool
not Bool
hasSelf Bool -> Bool -> Bool
&& [String] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
depNames = (RootOfTrust
None, String
"")
| Bool
True = (String -> RootOfTrust
Prop String
nm, String
" [Modulo: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
why String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"]")
where why :: String
why | Bool
hasSelf = String
"sorry"
| Bool
True = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [String]
depNames
cex = IO a -> KD a
forall a. IO a -> KD a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> KD a) -> IO a -> KD a
forall a b. (a -> b) -> a -> b
$ do String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"\n*** Failed to prove " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
nm String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"."
SatResult res <- SMTConfig -> Symbolic (SkolemsTo (NegatesTo a)) -> IO SatResult
forall a. Satisfiable a => SMTConfig -> a -> IO SatResult
satWith SMTConfig
cfg (Symbolic (SkolemsTo (NegatesTo a)) -> IO SatResult)
-> Symbolic (SkolemsTo (NegatesTo a)) -> IO SatResult
forall a b. (a -> b) -> a -> b
$ do
(SBV Bool -> SymbolicT IO ()) -> [SBV Bool] -> SymbolicT IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ SBV Bool -> SymbolicT IO ()
forall a. QuantifiedBool a => a -> SymbolicT IO ()
forall (m :: * -> *) a.
(SolverContext m, QuantifiedBool a) =>
a -> m ()
constrain [SBV Bool
getProof | Proof{Bool
isUserAxiom :: Proof -> Bool
isUserAxiom :: Bool
isUserAxiom, SBV Bool
getProof :: Proof -> SBV Bool
getProof :: SBV Bool
getProof} <- [Proof]
by, Bool
isUserAxiom] :: Symbolic ()
SkolemsTo (NegatesTo a) -> Symbolic (SkolemsTo (NegatesTo a))
forall a. a -> SymbolicT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SkolemsTo (NegatesTo a) -> Symbolic (SkolemsTo (NegatesTo a)))
-> SkolemsTo (NegatesTo a) -> Symbolic (SkolemsTo (NegatesTo a))
forall a b. (a -> b) -> a -> b
$ NegatesTo a -> SkolemsTo (NegatesTo a)
forall a.
(Skolemize a, Constraint Symbolic (SkolemsTo a), Skolemize a) =>
a -> SkolemsTo a
skolemize (a -> NegatesTo a
forall a. QNot a => a -> NegatesTo a
qNot a
inputProp)
print $ ThmResult res
error "Failed"
failed a
r = IO a -> m a
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO a -> m a) -> IO a -> m a
forall a b. (a -> b) -> a -> b
$ do String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"\n*** Failed to prove " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
nm String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
"."
a -> IO ()
forall a. Show a => a -> IO ()
print a
r
String -> IO a
forall a. HasCallStack => String -> a
error String
"Failed"
pRes <- liftIO $ proveWith cfg $ do
mapM_ (constrain . getProof) by :: Symbolic ()
pure $ skolemize (quantifiedBool inputProp)
case pRes of
ThmResult Unsatisfiable{} -> KD Proof
good
ThmResult Satisfiable{} -> KD Proof
forall {a}. KD a
cex
ThmResult DeltaSat{} -> KD Proof
forall {a}. KD a
cex
ThmResult SatExtField{} -> KD Proof
forall {a}. KD a
cex
ThmResult Unknown{} -> ThmResult -> KD Proof
forall {m :: * -> *} {a} {a}. (MonadIO m, Show a) => a -> m a
failed ThmResult
pRes
ThmResult ProofError{} -> ThmResult -> KD Proof
forall {m :: * -> *} {a} {a}. (MonadIO m, Show a) => a -> m a
failed ThmResult
pRes
lemma :: Proposition a => String -> a -> [Proof] -> KD Proof
lemma :: forall a. Proposition a => String -> a -> [Proof] -> KD Proof
lemma String
nm a
f [Proof]
by = do cfg <- KD SMTConfig
forall r (m :: * -> *). MonadReader r m => m r
ask
lemmaWith cfg nm f by
lemmaWith :: Proposition a => SMTConfig -> String -> a -> [Proof] -> KD Proof
lemmaWith :: forall a.
Proposition a =>
SMTConfig -> String -> a -> [Proof] -> KD Proof
lemmaWith SMTConfig
cfg String
nm = SMTConfig -> String -> [String] -> a -> [Proof] -> KD Proof
forall a.
Proposition a =>
SMTConfig -> String -> [String] -> a -> [Proof] -> KD Proof
lemmaGen SMTConfig
cfg String
"Lemma" [String
nm]
theorem :: Proposition a => String -> a -> [Proof] -> KD Proof
theorem :: forall a. Proposition a => String -> a -> [Proof] -> KD Proof
theorem String
nm a
f [Proof]
by = do cfg <- KD SMTConfig
forall r (m :: * -> *). MonadReader r m => m r
ask
theoremWith cfg nm f by
theoremWith :: Proposition a => SMTConfig -> String -> a -> [Proof] -> KD Proof
theoremWith :: forall a.
Proposition a =>
SMTConfig -> String -> a -> [Proof] -> KD Proof
theoremWith SMTConfig
cfg String
nm = SMTConfig -> String -> [String] -> a -> [Proof] -> KD Proof
forall a.
Proposition a =>
SMTConfig -> String -> [String] -> a -> [Proof] -> KD Proof
lemmaGen SMTConfig
cfg String
"Theorem" [String
nm]
class Induction a where
induct :: a -> Proof
inductAlt1 :: a -> Proof
inductAlt2 :: a -> Proof
inductAlt1 = a -> Proof
forall a. Induction a => a -> Proof
induct
inductAlt2 = a -> Proof
forall a. Induction a => a -> Proof
induct
instance Induction (SInteger -> SBool) where
induct :: (SInteger -> SBV Bool) -> Proof
induct SInteger -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"Nat.induct" SBV Bool
principle
where qb :: (Forall Any Integer -> SBV Bool) -> SBV Bool
qb = (Forall Any Integer -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool
principle :: SBV Bool
principle = SInteger -> SBV Bool
p SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any Integer -> SBV Bool) -> SBV Bool
qb (\(Forall SInteger
n) -> (SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.&& SInteger -> SBV Bool
p SInteger
n) SBV Bool -> SBV Bool -> SBV Bool
.=> SInteger -> SBV Bool
p (SInteger
nSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any Integer -> SBV Bool) -> SBV Bool
qb
(\(Forall SInteger
n) -> SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.=> SInteger -> SBV Bool
p SInteger
n)
inductAlt1 :: (SInteger -> SBV Bool) -> Proof
inductAlt1 SInteger -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"Integer.inductAlt1" SBV Bool
principle
where qb :: (Forall Any Integer -> SBV Bool) -> SBV Bool
qb = (Forall Any Integer -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool
principle :: SBV Bool
principle = SInteger -> SBV Bool
p SInteger
0
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any Integer -> SBV Bool) -> SBV Bool
qb (\(Forall SInteger
i) -> SInteger -> SBV Bool
p SInteger
i SBV Bool -> SBV Bool -> SBV Bool
forall a. EqSymbolic a => a -> a -> SBV Bool
.== SInteger -> SBV Bool
p (SInteger
iSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any Integer -> SBV Bool) -> SBV Bool
qb
(\(Forall SInteger
i) -> SInteger -> SBV Bool
p SInteger
i)
inductAlt2 :: (SInteger -> SBV Bool) -> Proof
inductAlt2 SInteger -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"Integer.inductAlt2" SBV Bool
principle
where qb :: (Forall Any Integer -> SBV Bool) -> SBV Bool
qb = (Forall Any Integer -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool
principle :: SBV Bool
principle = SInteger -> SBV Bool
p SInteger
0
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any Integer -> SBV Bool) -> SBV Bool
qb (\(Forall SInteger
i) -> SInteger -> SBV Bool
p SInteger
i SBV Bool -> SBV Bool -> SBV Bool
.=> SInteger -> SBV Bool
p (SInteger
iSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1) SBV Bool -> SBV Bool -> SBV Bool
.&& SInteger -> SBV Bool
p (SInteger
iSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
-SInteger
1))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any Integer -> SBV Bool) -> SBV Bool
qb
(\(Forall SInteger
i) -> SInteger -> SBV Bool
p SInteger
i)
instance SymVal a => Induction (SBV a -> SInteger -> SBool) where
induct :: (SBV a -> SInteger -> SBV Bool) -> Proof
induct SBV a -> SInteger -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"Nat.induct2" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = (Forall Any a -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) -> SBV a -> SInteger -> SBV Bool
p SBV a
a SInteger
0)
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a -> Forall Any Integer -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SInteger
n) -> (SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.&& SBV a -> SInteger -> SBV Bool
p SBV a
a SInteger
n) SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SInteger -> SBV Bool
p SBV a
a (SInteger
nSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any a -> Forall Any Integer -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SBV a
a) (Forall SInteger
n) -> SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SInteger -> SBV Bool
p SBV a
a SInteger
n)
instance (SymVal a, SymVal b) => Induction (SBV a -> SBV b -> SInteger -> SBool) where
induct :: (SBV a -> SBV b -> SInteger -> SBV Bool) -> Proof
induct SBV a -> SBV b -> SInteger -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"Nat.induct3" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = (Forall Any a -> Forall Any b -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) -> SBV a -> SBV b -> SInteger -> SBV Bool
p SBV a
a SBV b
b SInteger
0)
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a -> Forall Any b -> Forall Any Integer -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) (Forall SInteger
n) -> (SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.&& SBV a -> SBV b -> SInteger -> SBV Bool
p SBV a
a SBV b
b SInteger
n) SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SBV b -> SInteger -> SBV Bool
p SBV a
a SBV b
b (SInteger
nSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any a -> Forall Any b -> Forall Any Integer -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SBV a
a) (Forall SBV b
b) (Forall SInteger
n) -> SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SBV b -> SInteger -> SBV Bool
p SBV a
a SBV b
b SInteger
n)
instance (SymVal a, SymVal b, SymVal c) => Induction (SBV a -> SBV b -> SBV c -> SInteger -> SBool) where
induct :: (SBV a -> SBV b -> SBV c -> SInteger -> SBV Bool) -> Proof
induct SBV a -> SBV b -> SBV c -> SInteger -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"Nat.induct4" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = (Forall Any a -> Forall Any b -> Forall Any c -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV c
c) -> SBV a -> SBV b -> SBV c -> SInteger -> SBV Bool
p SBV a
a SBV b
b SBV c
c SInteger
0)
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a
-> Forall Any b -> Forall Any c -> Forall Any Integer -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV c
c) (Forall SInteger
n) -> (SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.&& SBV a -> SBV b -> SBV c -> SInteger -> SBV Bool
p SBV a
a SBV b
b SBV c
c SInteger
n) SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SBV b -> SBV c -> SInteger -> SBV Bool
p SBV a
a SBV b
b SBV c
c (SInteger
nSInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+SInteger
1))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any a
-> Forall Any b -> Forall Any c -> Forall Any Integer -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV c
c) (Forall SInteger
n) -> SInteger
n SInteger -> SInteger -> SBV Bool
forall a. OrdSymbolic a => a -> a -> SBV Bool
.>= SInteger
0 SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SBV b -> SBV c -> SInteger -> SBV Bool
p SBV a
a SBV b
b SBV c
c SInteger
n)
instance SymVal a => Induction (SList a -> SBool) where
induct :: (SList a -> SBV Bool) -> Proof
induct SList a -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"List(a).induct" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = SList a -> SBV Bool
p SList a
forall a. SymVal a => SList a
SL.nil
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a -> Forall Any [a] -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
x) (Forall SList a
xs) -> SList a -> SBV Bool
p SList a
xs SBV Bool -> SBV Bool -> SBV Bool
.=> SList a -> SBV Bool
p (SBV a
x SBV a -> SList a -> SList a
forall a. SymVal a => SBV a -> SList a -> SList a
SL..: SList a
xs))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any [a] -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SList a
xs) -> SList a -> SBV Bool
p SList a
xs)
instance (SymVal a, SymVal e) => Induction (SBV a -> SList e -> SBool) where
induct :: (SBV a -> SList e -> SBV Bool) -> Proof
induct SBV a -> SList e -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"List(a).induct2" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = (Forall Any a -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) -> SBV a -> SList e -> SBV Bool
p SBV a
a SList e
forall a. SymVal a => SList a
SL.nil)
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a -> Forall Any e -> Forall Any [e] -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV e
e) (Forall SList e
es) -> SBV a -> SList e -> SBV Bool
p SBV a
a SList e
es SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SList e -> SBV Bool
p SBV a
a (SBV e
e SBV e -> SList e -> SList e
forall a. SymVal a => SBV a -> SList a -> SList a
SL..: SList e
es))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any a -> Forall Any [e] -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SBV a
a) (Forall SList e
es) -> SBV a -> SList e -> SBV Bool
p SBV a
a SList e
es)
instance (SymVal a, SymVal b, SymVal e) => Induction (SBV a -> SBV b -> SList e -> SBool) where
induct :: (SBV a -> SBV b -> SList e -> SBV Bool) -> Proof
induct SBV a -> SBV b -> SList e -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"List(a).induct3" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = (Forall Any a -> Forall Any b -> SBV Bool) -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) -> SBV a -> SBV b -> SList e -> SBV Bool
p SBV a
a SBV b
b SList e
forall a. SymVal a => SList a
SL.nil)
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a
-> Forall Any b -> Forall Any e -> Forall Any [e] -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV e
e) (Forall SList e
es) -> SBV a -> SBV b -> SList e -> SBV Bool
p SBV a
a SBV b
b SList e
es SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SBV b -> SList e -> SBV Bool
p SBV a
a SBV b
b (SBV e
e SBV e -> SList e -> SList e
forall a. SymVal a => SBV a -> SList a -> SList a
SL..: SList e
es))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any a -> Forall Any b -> Forall Any [e] -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SBV a
a) (Forall SBV b
b) (Forall SList e
xs) -> SBV a -> SBV b -> SList e -> SBV Bool
p SBV a
a SBV b
b SList e
xs)
instance (SymVal a, SymVal b, SymVal c, SymVal e) => Induction (SBV a -> SBV b -> SBV c -> SList e -> SBool) where
induct :: (SBV a -> SBV b -> SBV c -> SList e -> SBV Bool) -> Proof
induct SBV a -> SBV b -> SBV c -> SList e -> SBV Bool
p = String -> SBV Bool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"List(a).induct4" SBV Bool
principle
where qb :: a -> SBV Bool
qb a
a = a -> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
quantifiedBool a
a
principle :: SBV Bool
principle = (Forall Any a -> Forall Any b -> Forall Any c -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV c
c) -> SBV a -> SBV b -> SBV c -> SList e -> SBV Bool
p SBV a
a SBV b
b SBV c
c SList e
forall a. SymVal a => SList a
SL.nil)
SBV Bool -> SBV Bool -> SBV Bool
.&& (Forall Any a
-> Forall Any b
-> Forall Any c
-> Forall Any e
-> Forall Any [e]
-> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb (\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV c
c) (Forall SBV e
e) (Forall SList e
es) -> SBV a -> SBV b -> SBV c -> SList e -> SBV Bool
p SBV a
a SBV b
b SBV c
c SList e
es SBV Bool -> SBV Bool -> SBV Bool
.=> SBV a -> SBV b -> SBV c -> SList e -> SBV Bool
p SBV a
a SBV b
b SBV c
c (SBV e
e SBV e -> SList e -> SList e
forall a. SymVal a => SBV a -> SList a -> SList a
SL..: SList e
es))
SBV Bool -> SBV Bool -> SBV Bool
.=> (Forall Any a
-> Forall Any b -> Forall Any c -> Forall Any [e] -> SBV Bool)
-> SBV Bool
forall a. QuantifiedBool a => a -> SBV Bool
qb
(\(Forall SBV a
a) (Forall SBV b
b) (Forall SBV c
c) (Forall SList e
xs) -> SBV a -> SBV b -> SBV c -> SList e -> SBV Bool
p SBV a
a SBV b
b SBV c
c SList e
xs)