{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedLists #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Documentation.SBV.Examples.TP.Kadane where
import Prelude hiding (length, maximum, null, head, tail, (++))
import Data.SBV
import Data.SBV.List
import Data.SBV.TP
#ifdef DOCTEST
#endif
mss :: SList Integer -> SInteger
mss :: SList Integer -> SInteger
mss = String -> (SList Integer -> SInteger) -> SList Integer -> SInteger
forall a.
(SMTDefinable a, Typeable a, Lambda Symbolic a) =>
String -> a -> a
smtFunction String
"mss" ((SList Integer -> SInteger) -> SList Integer -> SInteger)
-> (SList Integer -> SInteger) -> SList Integer -> SInteger
forall a b. (a -> b) -> a -> b
$ \SList Integer
xs -> SBool -> SInteger -> SInteger -> SInteger
forall a. Mergeable a => SBool -> a -> a -> a
ite (SList Integer -> SBool
forall a. SymVal a => SList a -> SBool
null SList Integer
xs) SInteger
0 (SList Integer -> SInteger
mssBegin SList Integer
xs SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SList Integer -> SInteger
mss (SList Integer -> SList Integer
forall a. SymVal a => SList a -> SList a
tail SList Integer
xs))
mssBegin :: SList Integer -> SInteger
mssBegin :: SList Integer -> SInteger
mssBegin = String -> (SList Integer -> SInteger) -> SList Integer -> SInteger
forall a.
(SMTDefinable a, Typeable a, Lambda Symbolic a) =>
String -> a -> a
smtFunction String
"mssBegin" ((SList Integer -> SInteger) -> SList Integer -> SInteger)
-> (SList Integer -> SInteger) -> SList Integer -> SInteger
forall a b. (a -> b) -> a -> b
$ \SList Integer
xs -> SBool -> SInteger -> SInteger -> SInteger
forall a. Mergeable a => SBool -> a -> a -> a
ite (SList Integer -> SBool
forall a. SymVal a => SList a -> SBool
null SList Integer
xs) SInteger
0
(SInteger -> SInteger) -> SInteger -> SInteger
forall a b. (a -> b) -> a -> b
$ let (SInteger
h, SList Integer
t) = SList Integer -> (SInteger, SList Integer)
forall a. SymVal a => SList a -> (SBV a, SList a)
uncons SList Integer
xs
in SInteger
0 SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
h SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
h SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SList Integer -> SInteger
mssBegin SList Integer
t))
kadane :: SList Integer -> SInteger
kadane :: SList Integer -> SInteger
kadane SList Integer
xs = SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper SList Integer
xs SInteger
0 SInteger
0
kadaneHelper :: SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper :: SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper = String
-> (SList Integer -> SInteger -> SInteger -> SInteger)
-> SList Integer
-> SInteger
-> SInteger
-> SInteger
forall a.
(SMTDefinable a, Typeable a, Lambda Symbolic a) =>
String -> a -> a
smtFunction String
"kadaneHelper" ((SList Integer -> SInteger -> SInteger -> SInteger)
-> SList Integer -> SInteger -> SInteger -> SInteger)
-> (SList Integer -> SInteger -> SInteger -> SInteger)
-> SList Integer
-> SInteger
-> SInteger
-> SInteger
forall a b. (a -> b) -> a -> b
$ \SList Integer
xs SInteger
maxEndingHere SInteger
maxSoFar ->
SBool -> SInteger -> SInteger -> SInteger
forall a. Mergeable a => SBool -> a -> a -> a
ite (SList Integer -> SBool
forall a. SymVal a => SList a -> SBool
null SList Integer
xs)
SInteger
maxSoFar
(SInteger -> SInteger) -> SInteger -> SInteger
forall a b. (a -> b) -> a -> b
$ let (SInteger
h, SList Integer
t) = SList Integer -> (SInteger, SList Integer)
forall a. SymVal a => SList a -> (SBV a, SList a)
uncons SList Integer
xs
newMaxEndingHere :: SInteger
newMaxEndingHere = SInteger
0 SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
h SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
maxEndingHere)
newMaxSofar :: SInteger
newMaxSofar = SInteger
maxSoFar SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SInteger
newMaxEndingHere
in SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper SList Integer
t SInteger
newMaxEndingHere SInteger
newMaxSofar
correctness :: TP (Proof (Forall "xs" [Integer] -> SBool))
correctness :: TP (Proof (Forall "xs" [Integer] -> SBool))
correctness = do
Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
invariant <- String
-> (Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> (Proof
(IHType
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
-> IHArg
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> IStepArgs
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
Integer)
-> TP
(Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
forall t.
(Proposition
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool),
SymVal t, EqSymbolic (SBV t)) =>
String
-> (Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> (Proof
(IHType
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
-> IHArg
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> IStepArgs
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
t)
-> TP
(Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
forall a t.
(Inductive a, Proposition a, SymVal t, EqSymbolic (SBV t)) =>
String
-> a
-> (Proof (IHType a) -> IHArg a -> IStepArgs a t)
-> TP (Proof a)
induct String
"kadaneHelperInvariant"
(\(Forall SList Integer
xs) (Forall SInteger
meh) (Forall SInteger
msf) ->
(SInteger
meh SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
0 SBool -> SBool -> SBool
.&& SInteger
msf SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
meh) SBool -> SBool -> SBool
.=> SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper SList Integer
xs SInteger
meh SInteger
msf SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== (SInteger
msf SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SList Integer -> SInteger
mss SList Integer
xs SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
meh SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SList Integer -> SInteger
mssBegin SList Integer
xs))) ((Proof
(IHType
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
-> IHArg
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> IStepArgs
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
Integer)
-> TP
(Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)))
-> (Proof
(IHType
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
-> IHArg
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> IStepArgs
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
Integer)
-> TP
(Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
forall a b. (a -> b) -> a -> b
$
\Proof
(IHType
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
ih (SInteger
a, SList Integer
as) SInteger
meh SInteger
msf ->
[SInteger
meh SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
0, SInteger
msf SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.>= SInteger
meh] [SBool] -> TPProofRaw SInteger -> (SBool, TPProofRaw SInteger)
forall a. [SBool] -> TPProofRaw a -> (SBool, TPProofRaw a)
|- let newMeh :: SInteger
newMeh = SInteger
0 SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
a SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SInteger
meh)
newMsf :: SInteger
newMsf = SInteger
msf SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SInteger
newMeh
in SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper (SInteger
a SInteger -> SList Integer -> SList Integer
forall a. SymVal a => SBV a -> SList a -> SList a
.: SList Integer
as) SInteger
meh SInteger
msf
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper SList Integer
as SInteger
newMeh SInteger
newMsf
SInteger -> Proof Bool -> Hinted SInteger
forall a b. HintsTo a b => a -> b -> Hinted a
?? Proof
(IHType
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool))
Proof (Forall "meh" Integer -> Forall "msf" Integer -> SBool)
ih Proof (Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> IArgs (Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> Proof Bool
forall a. Instantiatable a => Proof a -> IArgs a -> Proof Bool
`at` (forall (nm :: Symbol) a. SBV a -> Inst nm a
Inst @"meh" SInteger
newMeh, forall (nm :: Symbol) a. SBV a -> Inst nm a
Inst @"msf" SInteger
newMsf)
TPProofRaw SInteger
-> ChainsTo (TPProofRaw SInteger) -> ChainsTo (TPProofRaw SInteger)
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SInteger
newMsf SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SList Integer -> SInteger
mss SList Integer
as SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
newMeh SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SList Integer -> SInteger
mssBegin SList Integer
as)
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: ChainsTo SInteger
TPProofRaw SInteger
forall a. TPProofRaw a
qed
String
-> (Forall "xs" [Integer] -> SBool)
-> StepArgs (Forall "xs" [Integer] -> SBool) Integer
-> TP (Proof (Forall "xs" [Integer] -> SBool))
forall t.
(Proposition (Forall "xs" [Integer] -> SBool), SymVal t,
EqSymbolic (SBV t)) =>
String
-> (Forall "xs" [Integer] -> SBool)
-> StepArgs (Forall "xs" [Integer] -> SBool) t
-> TP (Proof (Forall "xs" [Integer] -> SBool))
forall a t.
(Calc a, Proposition a, SymVal t, EqSymbolic (SBV t)) =>
String -> a -> StepArgs a t -> TP (Proof a)
calc String
"correctness"
(\(Forall SList Integer
xs) -> SList Integer -> SInteger
mss SList Integer
xs SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SList Integer -> SInteger
kadane SList Integer
xs) (StepArgs (Forall "xs" [Integer] -> SBool) Integer
-> TP (Proof (Forall "xs" [Integer] -> SBool)))
-> StepArgs (Forall "xs" [Integer] -> SBool) Integer
-> TP (Proof (Forall "xs" [Integer] -> SBool))
forall a b. (a -> b) -> a -> b
$
\SList Integer
xs -> [] [SBool] -> TPProofRaw SInteger -> (SBool, TPProofRaw SInteger)
forall a. [SBool] -> TPProofRaw a -> (SBool, TPProofRaw a)
|- SList Integer -> SInteger
kadane SList Integer
xs
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SList Integer -> SInteger -> SInteger -> SInteger
kadaneHelper SList Integer
xs SInteger
0 SInteger
0
SInteger -> Proof Bool -> Hinted SInteger
forall a b. HintsTo a b => a -> b -> Hinted a
?? Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
invariant Proof
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> IArgs
(Forall "xs" [Integer]
-> Forall "meh" Integer -> Forall "msf" Integer -> SBool)
-> Proof Bool
forall a. Instantiatable a => Proof a -> IArgs a -> Proof Bool
`at` (forall (nm :: Symbol) a. SBV a -> Inst nm a
Inst @"xs" SList Integer
xs, forall (nm :: Symbol) a. SBV a -> Inst nm a
Inst @"meh" (SInteger
0 :: SInteger), forall (nm :: Symbol) a. SBV a -> Inst nm a
Inst @"msf" (SInteger
0 :: SInteger))
TPProofRaw SInteger
-> ChainsTo (TPProofRaw SInteger) -> ChainsTo (TPProofRaw SInteger)
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SInteger
0 SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SList Integer -> SInteger
mss SList Integer
xs SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` (SInteger
0 SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SList Integer -> SInteger
mssBegin SList Integer
xs)
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SList Integer -> SInteger
mss SList Integer
xs SInteger -> SInteger -> SInteger
forall a. OrdSymbolic a => a -> a -> a
`smax` SList Integer -> SInteger
mssBegin SList Integer
xs
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: SList Integer -> SInteger
mss SList Integer
xs
SInteger -> ChainsTo SInteger -> ChainsTo SInteger
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: ChainsTo SInteger
TPProofRaw SInteger
forall a. TPProofRaw a
qed