{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeAbstractions #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Data.SBV.Tools.KD.KnuckleDragger (
Proposition, Proof, Instantiatable(..), Inst(..)
, axiom
, lemma, lemmaWith
, theorem, theoremWith
, calc, calcWith, calcThm, calcThmWith
, induct, inductWith, inductThm, inductThmWith
, sInduct, sInductWith, sInductThm, sInductThmWith
, sorry
, KD, runKD, runKDWith, use
, (|-), (⊢), (=:), (≡), (??), (⁇), cases, hyp, hprf, qed
) where
import Data.SBV
import Data.SBV.Core.Model (qSaturateSavingObservables)
import Data.SBV.Control hiding (getProof)
import Data.SBV.Core.Data(SolverContext)
import Data.SBV.Tools.KD.Kernel
import Data.SBV.Tools.KD.Utils
import Control.Monad (forM_)
import Control.Monad.Trans (liftIO, MonadIO)
import qualified Data.SBV.List as SL
import Data.Char (isSpace)
import Data.List (isPrefixOf, isSuffixOf)
import Data.Maybe (catMaybes)
import Data.Proxy
import GHC.TypeLits (KnownSymbol, symbolVal, Symbol)
import Data.SBV.Utils.TDiff
import Data.Dynamic
import Data.Time (NominalDiffTime)
use :: IO Proof -> KD Proof
use :: IO Proof -> KD Proof
use = IO Proof -> KD Proof
forall a. IO a -> KD a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
data CalcStrategy = CalcStrategy { CalcStrategy -> SBool
calcIntros :: SBool
, CalcStrategy -> [([Helper], SBool)]
calcProofSteps :: [([Helper], SBool)]
}
proofStepSaturatables :: [([Helper], SBool)] -> [SBool]
proofStepSaturatables :: [([Helper], SBool)] -> [SBool]
proofStepSaturatables = (([Helper], SBool) -> [SBool]) -> [([Helper], SBool)] -> [SBool]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Helper], SBool) -> [SBool]
forall {t :: * -> *}. Foldable t => (t Helper, SBool) -> [SBool]
getS
where getS :: (t Helper, SBool) -> [SBool]
getS (t Helper
hs, SBool
b) = SBool
b SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: (Helper -> [SBool]) -> t Helper -> [SBool]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Helper -> [SBool]
getH t Helper
hs
getH :: Helper -> [SBool]
getH (HelperProof Proof
p) = [Proof -> SBool
getProof Proof
p]
getH (HelperAssum SBool
b) = [SBool
b]
getH (HelperCase String
_ [SBool]
ss) = [SBool]
ss
getCalcStrategySaturatables :: CalcStrategy -> [SBool]
getCalcStrategySaturatables :: CalcStrategy -> [SBool]
getCalcStrategySaturatables (CalcStrategy SBool
calcIntros [([Helper], SBool)]
calcProofSteps) = SBool
calcIntros SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: [([Helper], SBool)] -> [SBool]
proofStepSaturatables [([Helper], SBool)]
calcProofSteps
stepCases :: Int -> [Helper] -> Either (String, SBool) ([(String, SBool)], SBool)
stepCases :: Int
-> [Helper] -> Either (String, SBool) ([(String, SBool)], SBool)
stepCases Int
i [Helper]
helpers
| Bool
hasCase
= ([(String, SBool)], SBool)
-> Either (String, SBool) ([(String, SBool)], SBool)
forall a b. b -> Either a b
Right ([(String, SBool)]
caseSplits, SBool
cover)
| Bool
True
= (String, SBool)
-> Either (String, SBool) ([(String, SBool)], SBool)
forall a b. a -> Either a b
Left (Int -> String
forall a. Show a => a -> String
show Int
i, [SBool] -> SBool
sAnd ((Helper -> SBool) -> [Helper] -> [SBool]
forall a b. (a -> b) -> [a] -> [b]
map Helper -> SBool
getBools [Helper]
helpers))
where join :: [(String, SBool)] -> Helper -> [(String, SBool)]
join :: [(String, SBool)] -> Helper -> [(String, SBool)]
join [(String, SBool)]
sofar (HelperProof Proof
p) = ((String, SBool) -> (String, SBool))
-> [(String, SBool)] -> [(String, SBool)]
forall a b. (a -> b) -> [a] -> [b]
map (\(String
n, SBool
cond) -> (String
n, SBool
cond SBool -> SBool -> SBool
.&& Proof -> SBool
getProof Proof
p)) [(String, SBool)]
sofar
join [(String, SBool)]
sofar (HelperAssum SBool
b) = ((String, SBool) -> (String, SBool))
-> [(String, SBool)] -> [(String, SBool)]
forall a b. (a -> b) -> [a] -> [b]
map (\(String
n, SBool
cond) -> (String
n, SBool
cond SBool -> SBool -> SBool
.&& SBool
b)) [(String, SBool)]
sofar
join [(String, SBool)]
sofar (HelperCase String
cn [SBool]
cs) = ((String, SBool) -> [(String, SBool)])
-> [(String, SBool)] -> [(String, SBool)]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(String
n, SBool
cond) -> [ (String -> String
dotN String
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
cn String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"[" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
j String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]", SBool
cond SBool -> SBool -> SBool
.&& SBool
b)
| (Int
j, SBool
b) <- [Int] -> [SBool] -> [(Int, SBool)]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Int
1::Int)..] [SBool]
cs
]) [(String, SBool)]
sofar
dotN :: String -> String
dotN String
"" = String
""
dotN String
s = String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"."
getBools :: Helper -> SBool
getBools (HelperProof Proof
p) = Proof -> SBool
getProof Proof
p
getBools (HelperAssum SBool
b) = SBool
b
getBools (HelperCase{}) = String -> SBool
forall a. HasCallStack => String -> a
error String
"Unexpected case in stepCases: Wasn't expecting to see a HelperCase here."
caseSplits :: [(String, SBool)]
caseSplits = ([(String, SBool)] -> Helper -> [(String, SBool)])
-> [(String, SBool)] -> [Helper] -> [(String, SBool)]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl [(String, SBool)] -> Helper -> [(String, SBool)]
join [(String
"", SBool
sTrue)] [Helper]
helpers
isCase :: Helper -> Bool
isCase (HelperProof {}) = Bool
False
isCase (HelperAssum {}) = Bool
False
isCase (HelperCase {}) = Bool
True
hasCase :: Bool
hasCase = (Helper -> Bool) -> [Helper] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Helper -> Bool
isCase [Helper]
helpers
regulars :: [SBool]
regulars = (Helper -> [SBool]) -> [Helper] -> [SBool]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Helper -> [SBool]
getHyp [Helper]
helpers
where getHyp :: Helper -> [SBool]
getHyp (HelperProof Proof
p) = [Proof -> SBool
getProof Proof
p]
getHyp (HelperAssum SBool
b) = [SBool
b]
getHyp (HelperCase {}) = []
cover :: SBool
cover = [SBool] -> SBool
sAnd [SBool]
regulars SBool -> SBool -> SBool
.&& SBool -> SBool
sNot ([SBool] -> SBool
sOr [SBool
b | (String
_, SBool
b) <- [(String, SBool)]
caseSplits])
kdMergeCfg :: SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg :: SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cur SMTConfig
top = SMTConfig
cur{kdOptions = kdOptions top}
class CalcLemma a steps where
calc :: Proposition a => String -> a -> steps -> KD Proof
calcThm :: Proposition a => String -> a -> steps -> KD Proof
calcWith :: Proposition a => SMTConfig -> String -> a -> steps -> KD Proof
calcThmWith :: Proposition a => SMTConfig -> String -> a -> steps -> KD Proof
{-# MINIMAL calcSteps #-}
calcSteps :: a -> steps -> Symbolic (SBool, CalcStrategy)
calc String
nm a
p steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg -> SMTConfig -> String -> a -> steps -> KD Proof
forall a steps.
(CalcLemma a steps, Proposition a) =>
SMTConfig -> String -> a -> steps -> KD Proof
calcWith SMTConfig
cfg String
nm a
p steps
steps
calcThm String
nm a
p steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg -> SMTConfig -> String -> a -> steps -> KD Proof
forall a steps.
(CalcLemma a steps, Proposition a) =>
SMTConfig -> String -> a -> steps -> KD Proof
calcThmWith SMTConfig
cfg String
nm a
p steps
steps
calcWith SMTConfig
cfg String
nm a
p steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg' -> Bool -> SMTConfig -> String -> a -> steps -> KD Proof
forall a steps.
(CalcLemma a steps, Proposition a) =>
Bool -> SMTConfig -> String -> a -> steps -> KD Proof
calcGeneric Bool
False (SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cfg SMTConfig
cfg') String
nm a
p steps
steps
calcThmWith SMTConfig
cfg String
nm a
p steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg' -> Bool -> SMTConfig -> String -> a -> steps -> KD Proof
forall a steps.
(CalcLemma a steps, Proposition a) =>
Bool -> SMTConfig -> String -> a -> steps -> KD Proof
calcGeneric Bool
True (SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cfg SMTConfig
cfg') String
nm a
p steps
steps
calcGeneric :: Proposition a => Bool -> SMTConfig -> String -> a -> steps -> KD Proof
calcGeneric Bool
tagTheorem cfg :: SMTConfig
cfg@SMTConfig{kdOptions :: SMTConfig -> KDOptions
kdOptions = KDOptions{Bool
measureTime :: Bool
measureTime :: KDOptions -> Bool
measureTime}} String
nm a
result steps
steps = do
kdSt <- KD KDState
getKDState
liftIO $ runSMTWith cfg $ do
qSaturateSavingObservables result
message cfg $ (if tagTheorem then "Theorem" else "Lemma") ++ ": " ++ nm ++ "\n"
mbStartTime <- getTimeStampIf measureTime
(calcGoal, strategy@CalcStrategy {calcIntros, calcProofSteps}) <- calcSteps result steps
let stepHelpers = (([Helper], SBool) -> [Helper]) -> [([Helper], SBool)] -> [Helper]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Helper], SBool) -> [Helper]
forall a b. (a, b) -> a
fst [([Helper], SBool)]
calcProofSteps
finish [NominalDiffTime]
et [Proof]
helpers (Int, Maybe NominalDiffTime)
d = SMTConfig
-> String
-> (Int, Maybe NominalDiffTime)
-> [NominalDiffTime]
-> IO ()
finishKD SMTConfig
cfg (String
"Q.E.D." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
modulo) (Int, Maybe NominalDiffTime)
d [NominalDiffTime]
et
where (RootOfTrust
_, String
modulo) = String -> [Proof] -> (RootOfTrust, String)
calculateRootOfTrust String
nm [Proof]
helpers
mapM_ qSaturateSavingObservables $ calcIntros : getCalcStrategySaturatables strategy
let go :: Int -> SBool -> [([Helper], SBool)] -> Query Proof
go Int
_ SBool
accum [] = do
[String] -> Query ()
queryDebug [String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": Proof end: proving the result:"]
SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> SBool
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO Proof)
-> Query Proof
forall (m :: * -> *) a r.
(SolverContext m, MonadIO m, MonadQuery m, Proposition a) =>
SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> a
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO r)
-> m r
checkSatThen SMTConfig
cfg KDState
kdSt String
"Result" Bool
True
(SBool -> Maybe SBool
forall a. a -> Maybe a
Just (SBool
calcIntros SBool -> SBool -> SBool
.=> SBool
accum))
SBool
calcGoal
[]
[String
"", String
""]
([String] -> Maybe [String]
forall a. a -> Maybe a
Just [String
nm, String
"Result"])
Maybe (IO ())
forall a. Maybe a
Nothing (((Int, Maybe NominalDiffTime) -> IO Proof) -> Query Proof)
-> ((Int, Maybe NominalDiffTime) -> IO Proof) -> Query Proof
forall a b. (a -> b) -> a -> b
$ \(Int, Maybe NominalDiffTime)
d -> do mbElapsed <- Maybe UTCTime -> IO (Maybe NominalDiffTime)
forall (m :: * -> *).
MonadIO m =>
Maybe UTCTime -> m (Maybe NominalDiffTime)
getElapsedTime Maybe UTCTime
mbStartTime
let (ros, modulo) = calculateRootOfTrust nm (getHelperProofs stepHelpers)
finishKD cfg ("Q.E.D." ++ modulo) d (catMaybes [mbElapsed])
pure Proof { rootOfTrust = ros
, isUserAxiom = False
, getProof = label nm (quantifiedBool result)
, getProp = toDyn result
, proofName = nm
}
go Int
i SBool
accum (([Helper]
by, SBool
s):[([Helper], SBool)]
ss) = do
case [Helper] -> [SBool]
getHelperAssumes [Helper]
by of
[] -> () -> Query ()
forall a. a -> QueryT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[SBool]
as -> SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> SBool
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> Query ()
forall (m :: * -> *) a r.
(SolverContext m, MonadIO m, MonadQuery m, Proposition a) =>
SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> a
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO r)
-> m r
checkSatThen SMTConfig
cfg KDState
kdSt String
"Asms "
Bool
True
(SBool -> Maybe SBool
forall a. a -> Maybe a
Just SBool
calcIntros)
([SBool] -> SBool
sAnd [SBool]
as)
[]
[String
"", Int -> String
forall a. Show a => a -> String
show Int
i]
([String] -> Maybe [String]
forall a. a -> Maybe a
Just [String
nm, Int -> String
forall a. Show a => a -> String
show Int
i, String
"Assumptions"])
Maybe (IO ())
forall a. Maybe a
Nothing
([NominalDiffTime]
-> [Proof] -> (Int, Maybe NominalDiffTime) -> IO ()
finish [] [])
[String] -> Query ()
queryDebug [String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": Proof step: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" to " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"]
Int
-> SMTConfig
-> KDState
-> Either (String, SBool) ([(String, SBool)], SBool)
-> String
-> SBool
-> String
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> Query ()
forall (m :: * -> *) a.
(Monad m, SolverContext m, MonadIO m, MonadQuery m,
Proposition a) =>
Int
-> SMTConfig
-> KDState
-> Either (String, SBool) ([(String, SBool)], SBool)
-> String
-> a
-> String
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> m ()
proveAllCases Int
i SMTConfig
cfg KDState
kdSt (Int
-> [Helper] -> Either (String, SBool) ([(String, SBool)], SBool)
stepCases Int
i [Helper]
by) String
"Step " SBool
s String
nm ([NominalDiffTime]
-> [Proof] -> (Int, Maybe NominalDiffTime) -> IO ()
finish [] ([Helper] -> [Proof]
getHelperProofs [Helper]
by))
Int -> SBool -> [([Helper], SBool)] -> Query Proof
go (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (SBool
s SBool -> SBool -> SBool
.&& SBool
accum) [([Helper], SBool)]
ss
query $ go (1::Int) sTrue calcProofSteps
proveAllCases :: (Monad m, SolverContext m, MonadIO m, MonadQuery m, Proposition a)
=> Int -> SMTConfig -> KDState
-> Either (String, SBool) ([(String, SBool)], SBool)
-> String -> a -> String -> ((Int, Maybe NominalDiffTime) -> IO ()) -> m ()
proveAllCases :: forall (m :: * -> *) a.
(Monad m, SolverContext m, MonadIO m, MonadQuery m,
Proposition a) =>
Int
-> SMTConfig
-> KDState
-> Either (String, SBool) ([(String, SBool)], SBool)
-> String
-> a
-> String
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> m ()
proveAllCases Int
topStep SMTConfig
cfg KDState
kdSt Either (String, SBool) ([(String, SBool)], SBool)
caseInfo String
stepTag a
s String
nm (Int, Maybe NominalDiffTime) -> IO ()
finalize
| Left (String
stepName, SBool
asmp) <- Either (String, SBool) ([(String, SBool)], SBool)
caseInfo
= String -> SBool -> a -> [String] -> Maybe [String] -> m ()
checker String
stepTag SBool
asmp a
s [String
"", String
stepName] ([String] -> Maybe [String]
forall a. a -> Maybe a
Just [String
nm, String
stepName])
| Right ([(String, SBool)]
proofCases, SBool
coverCond) <- Either (String, SBool) ([(String, SBool)], SBool)
caseInfo
= do let len :: Int
len = [(String, SBool)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(String, SBool)]
proofCases
ways :: String
ways = case Int
len of
Int
1 -> String
"one way"
Int
n -> Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ways"
slen :: String
slen = Int -> String
forall a. Show a => a -> String
show Int
len
clen :: Int
clen = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
slen
sh :: Int -> String
sh Int
i = String -> String
forall a. [a] -> [a]
reverse (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
take Int
clen (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ String -> String
forall a. [a] -> [a]
reverse (Int -> String
forall a. Show a => a -> String
show Int
i) String -> String -> String
forall a. [a] -> [a] -> [a]
++ Char -> String
forall a. a -> [a]
repeat Char
' '
_tab <- IO Int -> m Int
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Int -> m Int) -> IO Int -> m Int
forall a b. (a -> b) -> a -> b
$ SMTConfig -> Bool -> String -> [String] -> IO Int
startKD SMTConfig
cfg Bool
True (String
"Step " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
topStep) [String
"", String
"Case split " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
ways String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
":"]
forM_ (zip [(1::Int)..] proofCases) $ \(Int
c, (String
stepName, SBool
asmp)) ->
String -> SBool -> a -> [String] -> Maybe [String] -> m ()
checker (String
"Case [" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
sh Int
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" of " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
len String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"]") SBool
asmp a
s [String
"", String
"", String
stepName] ([String] -> Maybe [String]
forall a. a -> Maybe a
Just [String
nm, String
stepName])
checker "Completeness" coverCond s ["", "", ""] (Just [nm, show topStep, "Completeness"])
where
checker :: String -> SBool -> a -> [String] -> Maybe [String] -> m ()
checker String
tag SBool
caseAsmp a
cond [String]
cnm Maybe [String]
fnm = SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> a
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> m ()
forall (m :: * -> *) a r.
(SolverContext m, MonadIO m, MonadQuery m, Proposition a) =>
SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> a
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO r)
-> m r
checkSatThen SMTConfig
cfg KDState
kdSt String
tag Bool
True (SBool -> Maybe SBool
forall a. a -> Maybe a
Just SBool
caseAsmp) a
cond [] [String]
cnm Maybe [String]
fnm Maybe (IO ())
forall a. Maybe a
Nothing (Int, Maybe NominalDiffTime) -> IO ()
finalize
mkCalcSteps :: EqSymbolic a => (SBool, [ProofStep a]) -> CalcStrategy
mkCalcSteps :: forall a. EqSymbolic a => (SBool, [ProofStep a]) -> CalcStrategy
mkCalcSteps (SBool
intros, [ProofStep a]
xs) = case [ProofStep a] -> [ProofStep a]
forall a. [a] -> [a]
reverse [ProofStep a]
xs of
(SingleStep a
_ (Helper
_:[Helper]
_) : [ProofStep a]
_) -> String -> CalcStrategy
forall a. HasCallStack => String -> a
error (String -> CalcStrategy) -> String -> CalcStrategy
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [ String
""
, String
"*** Incorrect calc/induct lemma calculations."
, String
"***"
, String
"*** The last step in the proof has a helper, which isn't used."
, String
"***"
, String
"*** Perhaps the hint is off-by-one in its placement?"
]
[ProofStep a]
_ -> CalcStrategy { calcIntros :: SBool
calcIntros = SBool
intros
, calcProofSteps :: [([Helper], SBool)]
calcProofSteps = (ProofStep a -> ProofStep a -> ([Helper], SBool))
-> [ProofStep a] -> [ProofStep a] -> [([Helper], SBool)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith ProofStep a -> ProofStep a -> ([Helper], SBool)
forall {a}.
EqSymbolic a =>
ProofStep a -> ProofStep a -> ([Helper], SBool)
merge [ProofStep a]
xs (Int -> [ProofStep a] -> [ProofStep a]
forall a. Int -> [a] -> [a]
drop Int
1 [ProofStep a]
xs)
}
where merge :: ProofStep a -> ProofStep a -> ([Helper], SBool)
merge (SingleStep a
a [Helper]
by) (SingleStep a
b [Helper]
_) = ([Helper]
by, a
a a -> a -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== a
b)
instance EqSymbolic z => CalcLemma SBool (SBool, [ProofStep z]) where
calcSteps :: SBool -> (SBool, [ProofStep z]) -> Symbolic (SBool, CalcStrategy)
calcSteps SBool
result (SBool, [ProofStep z])
steps = (SBool, CalcStrategy) -> Symbolic (SBool, CalcStrategy)
forall a. a -> SymbolicT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SBool
result, (SBool, [ProofStep z]) -> CalcStrategy
forall a. EqSymbolic a => (SBool, [ProofStep a]) -> CalcStrategy
mkCalcSteps (SBool, [ProofStep z])
steps)
instance (KnownSymbol na, SymVal a, EqSymbolic z) => CalcLemma (Forall na a -> SBool) (SBV a -> (SBool, [ProofStep z])) where
calcSteps :: (Forall na a -> SBool)
-> (SBV a -> (SBool, [ProofStep z]))
-> Symbolic (SBool, CalcStrategy)
calcSteps Forall na a -> SBool
result SBV a -> (SBool, [ProofStep z])
steps = do a <- String -> Symbolic (SBV a)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na))
pure (result (Forall a), mkCalcSteps (steps a))
instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, EqSymbolic z)
=> CalcLemma (Forall na a -> Forall nb b -> SBool)
(SBV a -> SBV b -> (SBool, [ProofStep z])) where
calcSteps :: (Forall na a -> Forall nb b -> SBool)
-> (SBV a -> SBV b -> (SBool, [ProofStep z]))
-> Symbolic (SBool, CalcStrategy)
calcSteps Forall na a -> Forall nb b -> SBool
result SBV a -> SBV b -> (SBool, [ProofStep z])
steps = do (a, b) <- (,) (SBV a -> SBV b -> (SBV a, SBV b))
-> SymbolicT IO (SBV a) -> SymbolicT IO (SBV b -> (SBV a, SBV b))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> SymbolicT IO (SBV a)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)) SymbolicT IO (SBV b -> (SBV a, SBV b))
-> SymbolicT IO (SBV b) -> SymbolicT IO (SBV a, SBV b)
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV b)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb))
pure (result (Forall a) (Forall b), mkCalcSteps (steps a b))
instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, EqSymbolic z)
=> CalcLemma (Forall na a -> Forall nb b -> Forall nc c -> SBool)
(SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z])) where
calcSteps :: (Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> (SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z]))
-> Symbolic (SBool, CalcStrategy)
calcSteps Forall na a -> Forall nb b -> Forall nc c -> SBool
result SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z])
steps = do (a, b, c) <- (,,) (SBV a -> SBV b -> SBV c -> (SBV a, SBV b, SBV c))
-> SymbolicT IO (SBV a)
-> SymbolicT IO (SBV b -> SBV c -> (SBV a, SBV b, SBV c))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> SymbolicT IO (SBV a)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)) SymbolicT IO (SBV b -> SBV c -> (SBV a, SBV b, SBV c))
-> SymbolicT IO (SBV b)
-> SymbolicT IO (SBV c -> (SBV a, SBV b, SBV c))
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV b)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)) SymbolicT IO (SBV c -> (SBV a, SBV b, SBV c))
-> SymbolicT IO (SBV c) -> SymbolicT IO (SBV a, SBV b, SBV c)
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV c)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc))
pure (result (Forall a) (Forall b) (Forall c), mkCalcSteps (steps a b c))
instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, EqSymbolic z)
=> CalcLemma (Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
(SBV a -> SBV b -> SBV c -> SBV d -> (SBool, [ProofStep z])) where
calcSteps :: (Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> (SBV a -> SBV b -> SBV c -> SBV d -> (SBool, [ProofStep z]))
-> Symbolic (SBool, CalcStrategy)
calcSteps Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool
result SBV a -> SBV b -> SBV c -> SBV d -> (SBool, [ProofStep z])
steps = do (a, b, c, d) <- (,,,) (SBV a -> SBV b -> SBV c -> SBV d -> (SBV a, SBV b, SBV c, SBV d))
-> SymbolicT IO (SBV a)
-> SymbolicT
IO (SBV b -> SBV c -> SBV d -> (SBV a, SBV b, SBV c, SBV d))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> SymbolicT IO (SBV a)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)) SymbolicT
IO (SBV b -> SBV c -> SBV d -> (SBV a, SBV b, SBV c, SBV d))
-> SymbolicT IO (SBV b)
-> SymbolicT IO (SBV c -> SBV d -> (SBV a, SBV b, SBV c, SBV d))
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV b)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)) SymbolicT IO (SBV c -> SBV d -> (SBV a, SBV b, SBV c, SBV d))
-> SymbolicT IO (SBV c)
-> SymbolicT IO (SBV d -> (SBV a, SBV b, SBV c, SBV d))
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV c)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)) SymbolicT IO (SBV d -> (SBV a, SBV b, SBV c, SBV d))
-> SymbolicT IO (SBV d)
-> SymbolicT IO (SBV a, SBV b, SBV c, SBV d)
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV d)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd))
pure (result (Forall a) (Forall b) (Forall c) (Forall d), mkCalcSteps (steps a b c d))
instance (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, KnownSymbol ne, SymVal e, EqSymbolic z)
=> CalcLemma (Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> Forall ne e -> SBool)
(SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> (SBool, [ProofStep z])) where
calcSteps :: (Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> (SBV a
-> SBV b -> SBV c -> SBV d -> SBV e -> (SBool, [ProofStep z]))
-> Symbolic (SBool, CalcStrategy)
calcSteps Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> (SBool, [ProofStep z])
steps = do (a, b, c, d, e) <- (,,,,) (SBV a
-> SBV b
-> SBV c
-> SBV d
-> SBV e
-> (SBV a, SBV b, SBV c, SBV d, SBV e))
-> SymbolicT IO (SBV a)
-> SymbolicT
IO
(SBV b
-> SBV c -> SBV d -> SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> SymbolicT IO (SBV a)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)) SymbolicT
IO
(SBV b
-> SBV c -> SBV d -> SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
-> SymbolicT IO (SBV b)
-> SymbolicT
IO (SBV c -> SBV d -> SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV b)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)) SymbolicT
IO (SBV c -> SBV d -> SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
-> SymbolicT IO (SBV c)
-> SymbolicT
IO (SBV d -> SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV c)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)) SymbolicT
IO (SBV d -> SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
-> SymbolicT IO (SBV d)
-> SymbolicT IO (SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV d)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd)) SymbolicT IO (SBV e -> (SBV a, SBV b, SBV c, SBV d, SBV e))
-> SymbolicT IO (SBV e)
-> SymbolicT IO (SBV a, SBV b, SBV c, SBV d, SBV e)
forall a b.
SymbolicT IO (a -> b) -> SymbolicT IO a -> SymbolicT IO b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> SymbolicT IO (SBV e)
forall a. SymVal a => String -> Symbolic (SBV a)
free (Proxy ne -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ne))
pure (result (Forall a) (Forall b) (Forall c) (Forall d) (Forall e), mkCalcSteps (steps a b c d e))
data InductionStrategy = InductionStrategy { InductionStrategy -> SBool
inductionIntros :: SBool
, InductionStrategy -> SBool
inductionBaseCase :: SBool
, InductionStrategy -> [([Helper], SBool)]
inductionProofSteps :: [([Helper], SBool)]
, InductionStrategy -> String
inductionBaseFailureMsg :: String
, InductionStrategy -> SBool
inductiveStep :: SBool
}
data InductionStyle = RegularInduction | StrongInduction
getInductionStrategySaturatables :: InductionStrategy -> [SBool]
getInductionStrategySaturatables :: InductionStrategy -> [SBool]
getInductionStrategySaturatables (InductionStrategy SBool
inductionIntros
SBool
inductionBaseCase
[([Helper], SBool)]
inductionProofSteps
String
_inductionBaseFailureMsg
SBool
inductiveStep)
= SBool
inductionIntros SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: SBool
inductionBaseCase SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: SBool
inductiveStep SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: [([Helper], SBool)] -> [SBool]
proofStepSaturatables [([Helper], SBool)]
inductionProofSteps
class Inductive a steps where
induct :: Proposition a => String -> a -> (Proof -> steps) -> KD Proof
sInduct :: Proposition a => String -> a -> (Proof -> steps) -> KD Proof
inductThm :: Proposition a => String -> a -> (Proof -> steps) -> KD Proof
sInductThm :: Proposition a => String -> a -> (Proof -> steps) -> KD Proof
inductWith :: Proposition a => SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
sInductWith :: Proposition a => SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductThmWith :: Proposition a => SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
sInductThmWith :: Proposition a => SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
induct String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductWith SMTConfig
cfg String
nm a
p Proof -> steps
steps
inductThm String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductThmWith SMTConfig
cfg String
nm a
p Proof -> steps
steps
inductWith SMTConfig
cfg String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg' -> InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductGeneric InductionStyle
RegularInduction Bool
False (SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cfg SMTConfig
cfg') String
nm a
p Proof -> steps
steps
inductThmWith SMTConfig
cfg String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg' -> InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductGeneric InductionStyle
RegularInduction Bool
True (SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cfg SMTConfig
cfg') String
nm a
p Proof -> steps
steps
sInduct String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
sInductWith SMTConfig
cfg String
nm a
p Proof -> steps
steps
sInductThm String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
sInductThmWith SMTConfig
cfg String
nm a
p Proof -> steps
steps
sInductWith SMTConfig
cfg String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg' -> InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductGeneric InductionStyle
StrongInduction Bool
False (SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cfg SMTConfig
cfg') String
nm a
p Proof -> steps
steps
sInductThmWith SMTConfig
cfg String
nm a
p Proof -> steps
steps = KD SMTConfig
getKDConfig KD SMTConfig -> (SMTConfig -> KD Proof) -> KD Proof
forall a b. KD a -> (a -> KD b) -> KD b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \SMTConfig
cfg' -> InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
forall a steps.
(Inductive a steps, Proposition a) =>
InductionStyle
-> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductGeneric InductionStyle
StrongInduction Bool
True (SMTConfig -> SMTConfig -> SMTConfig
kdMergeCfg SMTConfig
cfg SMTConfig
cfg') String
nm a
p Proof -> steps
steps
{-# MINIMAL inductionStrategy #-}
inductionStrategy :: Proposition a => InductionStyle -> a -> (Proof -> steps) -> Symbolic InductionStrategy
inductGeneric :: Proposition a => InductionStyle -> Bool -> SMTConfig -> String -> a -> (Proof -> steps) -> KD Proof
inductGeneric InductionStyle
style Bool
tagTheorem cfg :: SMTConfig
cfg@SMTConfig{kdOptions :: SMTConfig -> KDOptions
kdOptions = KDOptions{Bool
measureTime :: KDOptions -> Bool
measureTime :: Bool
measureTime}} String
nm a
result Proof -> steps
steps = do
kdSt <- KD KDState
getKDState
liftIO $ runSMTWith cfg $ do
qSaturateSavingObservables result
let strong = case InductionStyle
style of
InductionStyle
RegularInduction -> String
""
InductionStyle
StrongInduction -> String
" (strong)"
message cfg $ "Inductive " ++ (if tagTheorem then "theorem" else "lemma") ++ strong ++ ": " ++ nm ++ "\n"
mbStartTime <- getTimeStampIf measureTime
strategy@InductionStrategy { inductionIntros
, inductionBaseCase
, inductionProofSteps
, inductionBaseFailureMsg
, inductiveStep
} <- inductionStrategy style result steps
let stepHelpers = (([Helper], SBool) -> [Helper]) -> [([Helper], SBool)] -> [Helper]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Helper], SBool) -> [Helper]
forall a b. (a, b) -> a
fst [([Helper], SBool)]
inductionProofSteps
finish [NominalDiffTime]
et [Proof]
helpers (Int, Maybe NominalDiffTime)
d = SMTConfig
-> String
-> (Int, Maybe NominalDiffTime)
-> [NominalDiffTime]
-> IO ()
finishKD SMTConfig
cfg (String
"Q.E.D." String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
modulo) (Int, Maybe NominalDiffTime)
d [NominalDiffTime]
et
where (RootOfTrust
_, String
modulo) = String -> [Proof] -> (RootOfTrust, String)
calculateRootOfTrust String
nm [Proof]
helpers
mapM_ qSaturateSavingObservables $ getInductionStrategySaturatables strategy
query $ do
queryDebug [nm ++ ": Induction, proving base case:"]
checkSatThen cfg kdSt "Base" True (Just inductionIntros) inductionBaseCase [] [nm, "Base"] Nothing
(Just (liftIO (putStrLn inductionBaseFailureMsg)))
(finish [] [])
let loop Int
i SBool
accum (([Helper]
by, SBool
s):[([Helper], SBool)]
ss) = do
case [Helper] -> [SBool]
getHelperAssumes [Helper]
by of
[] -> () -> Query ()
forall a. a -> QueryT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
[SBool]
as -> SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> SBool
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> Query ()
forall (m :: * -> *) a r.
(SolverContext m, MonadIO m, MonadQuery m, Proposition a) =>
SMTConfig
-> KDState
-> String
-> Bool
-> Maybe SBool
-> a
-> [Proof]
-> [String]
-> Maybe [String]
-> Maybe (IO ())
-> ((Int, Maybe NominalDiffTime) -> IO r)
-> m r
checkSatThen SMTConfig
cfg KDState
kdSt String
"Asms"
Bool
True
(SBool -> Maybe SBool
forall a. a -> Maybe a
Just SBool
inductionIntros)
([SBool] -> SBool
sAnd [SBool]
as)
[]
[String
"", Int -> String
forall a. Show a => a -> String
show Int
i]
([String] -> Maybe [String]
forall a. a -> Maybe a
Just [String
nm, Int -> String
forall a. Show a => a -> String
show Int
i, String
"Assumptions"])
Maybe (IO ())
forall a. Maybe a
Nothing
([NominalDiffTime]
-> [Proof] -> (Int, Maybe NominalDiffTime) -> IO ()
finish [] [])
[String] -> Query ()
queryDebug [String
nm String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": Induction, proving step: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i]
Int
-> SMTConfig
-> KDState
-> Either (String, SBool) ([(String, SBool)], SBool)
-> String
-> SBool
-> String
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> Query ()
forall (m :: * -> *) a.
(Monad m, SolverContext m, MonadIO m, MonadQuery m,
Proposition a) =>
Int
-> SMTConfig
-> KDState
-> Either (String, SBool) ([(String, SBool)], SBool)
-> String
-> a
-> String
-> ((Int, Maybe NominalDiffTime) -> IO ())
-> m ()
proveAllCases Int
i SMTConfig
cfg KDState
kdSt (Int
-> [Helper] -> Either (String, SBool) ([(String, SBool)], SBool)
stepCases Int
i [Helper]
by) String
"Step" SBool
s String
nm ([NominalDiffTime]
-> [Proof] -> (Int, Maybe NominalDiffTime) -> IO ()
finish [] ([Helper] -> [Proof]
getHelperProofs [Helper]
by))
Int -> SBool -> [([Helper], SBool)] -> QueryT IO SBool
loop (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) (SBool
accum SBool -> SBool -> SBool
.&& SBool
s) [([Helper], SBool)]
ss
loop Int
_ SBool
accum [] = SBool -> QueryT IO SBool
forall a. a -> QueryT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SBool
accum
indSchema <- loop (1::Int) sTrue inductionProofSteps
queryDebug [nm ++ ": Induction, proving inductive step:"]
checkSatThen cfg kdSt "Step"
True
(Just (inductionIntros .=> indSchema))
inductiveStep
[]
[nm, "Step"]
Nothing
Nothing $ \(Int, Maybe NominalDiffTime)
d -> do
mbElapsed <- Maybe UTCTime -> IO (Maybe NominalDiffTime)
forall (m :: * -> *).
MonadIO m =>
Maybe UTCTime -> m (Maybe NominalDiffTime)
getElapsedTime Maybe UTCTime
mbStartTime
let (ros, modulo) = calculateRootOfTrust nm (getHelperProofs stepHelpers)
finishKD cfg ("Q.E.D." ++ modulo) d (catMaybes [mbElapsed])
pure $ Proof { rootOfTrust = ros
, isUserAxiom = False
, getProof = label nm $ quantifiedBool result
, getProp = toDyn result
, proofName = nm
}
instance (KnownSymbol nk, EqSymbolic z) => Inductive (Forall nk Integer -> SBool) (SInteger -> (SBool, [ProofStep z])) where
inductionStrategy :: Proposition (Forall nk Integer -> SBool) =>
InductionStyle
-> (Forall nk Integer -> SBool)
-> (Proof -> SInteger -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nk Integer -> SBool
result Proof -> SInteger -> (SBool, [ProofStep z])
steps = do
let predicate :: SInteger -> SBool
predicate SInteger
k = Forall nk Integer -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k)
nk :: String
nk = Proxy nk -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nk)
k <- String -> Symbolic SInteger
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nk
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> SBool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" (SBool -> Proof) -> SBool -> Proof
forall a b. (a -> b) -> a -> b
$ Forall nk Integer -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k)
InductionStyle
StrongInduction -> String -> (Forall nk Integer -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nk Integer -> SBool) -> Proof)
-> (Forall nk Integer -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SInteger
k' :: Forall nk Integer) -> SInteger
k' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k SBool -> SBool -> SBool
.=> Forall nk Integer -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k')
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih k
pure InductionStrategy {
inductionIntros = k .>= 0 .&& calcIntros
, inductionBaseCase = predicate 0
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nk ++ " = 0."
, inductiveStep = observeIf not ("P(" ++ nk ++ "+1)") (predicate (k+1))
}
instance forall na a nk z. (KnownSymbol na, SymVal a, KnownSymbol nk, EqSymbolic z)
=> Inductive (Forall nk Integer -> Forall na a -> SBool)
(SInteger -> SBV a -> (SBool, [ProofStep z])) where
inductionStrategy :: Proposition (Forall nk Integer -> Forall na a -> SBool) =>
InductionStyle
-> (Forall nk Integer -> Forall na a -> SBool)
-> (Proof -> SInteger -> SBV a -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nk Integer -> Forall na a -> SBool
result Proof -> SInteger -> SBV a -> (SBool, [ProofStep z])
steps = do
let predicate :: SInteger -> SBV a -> SBool
predicate SInteger
k SBV a
a = Forall nk Integer -> Forall na a -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a)
nk :: String
nk = Proxy nk -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nk)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
k <- String -> Symbolic SInteger
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nk
a <- free na
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> (Forall na a -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> SBool) -> Proof)
-> (Forall na a -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' -> Forall nk Integer -> Forall na a -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (Forall na a
a' :: Forall na a)
InductionStyle
StrongInduction -> String -> (Forall nk Integer -> Forall na a -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nk Integer -> Forall na a -> SBool) -> Proof)
-> (Forall nk Integer -> Forall na a -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SInteger
k' :: Forall nk Integer) Forall na a
a' -> SInteger
0 SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k' SBool -> SBool -> SBool
.&& SInteger
k' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k SBool -> SBool -> SBool
.=> Forall nk Integer -> Forall na a -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k') (Forall na a
a' :: Forall na a)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih k a
pure InductionStrategy {
inductionIntros = k .>= 0 .&& calcIntros
, inductionBaseCase = predicate 0 a
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nk ++ " = 0."
, inductiveStep = observeIf not ("P(" ++ nk ++ "+1)") (predicate (k+1) a)
}
instance forall na a nb b nk z. (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nk, EqSymbolic z)
=> Inductive (Forall nk Integer -> Forall na a -> Forall nb b -> SBool)
(SInteger -> SBV a -> SBV b -> (SBool, [ProofStep z])) where
inductionStrategy :: Proposition
(Forall nk Integer -> Forall na a -> Forall nb b -> SBool) =>
InductionStyle
-> (Forall nk Integer -> Forall na a -> Forall nb b -> SBool)
-> (Proof -> SInteger -> SBV a -> SBV b -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nk Integer -> Forall na a -> Forall nb b -> SBool
result Proof -> SInteger -> SBV a -> SBV b -> (SBool, [ProofStep z])
steps = do
let predicate :: SInteger -> SBV a -> SBV b -> SBool
predicate SInteger
k SBV a
a SBV b
b = Forall nk Integer -> Forall na a -> Forall nb b -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b)
nk :: String
nk = Proxy nk -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nk)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
k <- String -> Symbolic SInteger
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nk
a <- free na
b <- free nb
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> (Forall na a -> Forall nb b -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> Forall nb b -> SBool) -> Proof)
-> (Forall na a -> Forall nb b -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' -> Forall nk Integer -> Forall na a -> Forall nb b -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b)
InductionStyle
StrongInduction -> String
-> (Forall nk Integer -> Forall na a -> Forall nb b -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nk Integer -> Forall na a -> Forall nb b -> SBool)
-> Proof)
-> (Forall nk Integer -> Forall na a -> Forall nb b -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SInteger
k' :: Forall nk Integer) Forall na a
a' Forall nb b
b' -> SInteger
0 SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k' SBool -> SBool -> SBool
.&& SInteger
k' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k SBool -> SBool -> SBool
.=> Forall nk Integer -> Forall na a -> Forall nb b -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih k a b
pure InductionStrategy {
inductionIntros = k .>= 0 .&& calcIntros
, inductionBaseCase = predicate 0 a b
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nk ++ " = 0."
, inductiveStep = observeIf not ("P(" ++ nk ++ "+1)") (predicate (k+1) a b)
}
instance forall na a nb b nc c nk z. (KnownSymbol na, SymVal a , KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nk, EqSymbolic z)
=> Inductive (Forall nk Integer -> Forall na a -> Forall nb b -> Forall nc c -> SBool)
(SInteger -> SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool) =>
InductionStyle
-> (Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> (Proof
-> SInteger -> SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool
result Proof
-> SInteger -> SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z])
steps = do
let predicate :: SInteger -> SBV a -> SBV b -> SBV c -> SBool
predicate SInteger
k SBV a
a SBV b
b SBV c
c = Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c)
nk :: String
nk = Proxy nk -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nk)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
k <- String -> Symbolic SInteger
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nk
a <- free na
b <- free nb
c <- free nc
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof)
-> (Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' -> Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c)
InductionStyle
StrongInduction -> String
-> (Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> Proof)
-> (Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SInteger
k' :: Forall nk Integer) Forall na a
a' Forall nb b
b' Forall nc c
c' -> SInteger
0 SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k' SBool -> SBool -> SBool
.&& SInteger
k' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k SBool -> SBool -> SBool
.=> Forall nk Integer
-> Forall na a -> Forall nb b -> Forall nc c -> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih k a b c
pure InductionStrategy {
inductionIntros = k .>= 0 .&& calcIntros
, inductionBaseCase = predicate 0 a b c
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nk ++ " = 0."
, inductiveStep = observeIf not ("P(" ++ nk ++ "+1)") (predicate (k+1) a b c)
}
instance forall na a nb b nc c nd d nk z. (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, KnownSymbol nk, EqSymbolic z)
=> Inductive (Forall nk Integer -> Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
(SInteger -> SBV a -> SBV b -> SBV c -> SBV d -> (SBool, [ProofStep z])) where
inductionStrategy :: Proposition
(Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool) =>
InductionStyle
-> (Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> (Proof
-> SInteger
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result Proof
-> SInteger
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> (SBool, [ProofStep z])
steps = do
let predicate :: SInteger -> SBV a -> SBV b -> SBV c -> SBV d -> SBool
predicate SInteger
k SBV a
a SBV b
b SBV c
c SBV d
d = Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d)
nk :: String
nk = Proxy nk -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nk)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
nd :: String
nd = Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd)
k <- String -> Symbolic SInteger
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nk
a <- free na
b <- free nb
c <- free nc
d <- free nd
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof)
-> (Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' -> Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d)
InductionStyle
StrongInduction -> String
-> (Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof)
-> (Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SInteger
k' :: Forall nk Integer) Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' -> SInteger
0 SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k' SBool -> SBool -> SBool
.&& SInteger
k' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
k SBool -> SBool -> SBool
.=> Forall nk Integer
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SInteger -> Forall nk Integer
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SInteger
k') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih k a b c d
pure InductionStrategy {
inductionIntros = k .>= 0 .&& calcIntros
, inductionBaseCase = predicate 0 a b c d
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nk ++ " = 0."
, inductiveStep = observeIf not ("P(" ++ nk ++ "+1)") (predicate (k+1) a b c d)
}
singular :: String -> String
singular :: String -> String
singular String
n = case String -> String
forall a. [a] -> [a]
reverse String
n of
Char
's':Char
_:String
_ -> String -> String
forall a. HasCallStack => [a] -> [a]
init String
n
String
_ -> String
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"Elt"
lexLeq :: SymVal a => SList a -> SList a -> SBool
lexLeq :: forall a. SymVal a => SList a -> SList a -> SBool
lexLeq SList a
xs SList a
ys = SList a -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList a
xs SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SList a -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList a
ys
lexLeq2 :: (SymVal a, SymVal b) => (SList a, SList b) -> (SList a, SList b) -> SBool
lexLeq2 :: forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
lexLeq2 (SList a
xs', SList b
ys') (SList a
xs, SList b
ys) = SInteger
lxs' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
lxs
SBool -> SBool -> SBool
.|| ( SInteger
lxs' SInteger -> SInteger -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SInteger
1 SInteger -> SInteger -> SInteger
forall a. Num a => a -> a -> a
+ SList a -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList a
xs
SBool -> SBool -> SBool
.&& SInteger
lys' SInteger -> SInteger -> SBool
forall a. OrdSymbolic a => a -> a -> SBool
.<= SInteger
lys
)
where lxs :: SInteger
lxs = SList a -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList a
xs
lys :: SInteger
lys = SList b -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList b
ys
lxs' :: SInteger
lxs' = SList a -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList a
xs'
lys' :: SInteger
lys' = SList b -> SInteger
forall a. SymVal a => SList a -> SInteger
SL.length SList b
ys'
instance (KnownSymbol nx, SymVal x, EqSymbolic z)
=> Inductive (Forall nx [x] -> SBool)
(SBV x -> SList x -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition (Forall nx [x] -> SBool) =>
InductionStyle
-> (Forall nx [x] -> SBool)
-> (Proof -> SBV x -> SList x -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x] -> SBool
result Proof -> SBV x -> SList x -> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SBool
predicate SList x
xs = Forall nx [x] -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> SBool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" (SBool -> Proof) -> SBool -> Proof
forall a b. (a -> b) -> a -> b
$ Forall nx [x] -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs)
InductionStyle
StrongInduction -> String -> (Forall nx [x] -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x] -> SBool) -> Proof)
-> (Forall nx [x] -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) -> SList x
xs' SList x -> SList x -> SBool
forall a. SymVal a => SList a -> SList a -> SBool
`lexLeq` SList x
xs SBool -> SBool -> SBool
.=> Forall nx [x] -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs')
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = []."
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ")") (predicate (x SL..: xs))
}
instance forall na a nx x z. (KnownSymbol na, SymVal a, KnownSymbol nx, SymVal x, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall na a -> SBool)
(SBV x -> SList x -> SBV a -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition (Forall nx [x] -> Forall na a -> SBool) =>
InductionStyle
-> (Forall nx [x] -> Forall na a -> SBool)
-> (Proof -> SBV x -> SList x -> SBV a -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x] -> Forall na a -> SBool
result Proof -> SBV x -> SList x -> SBV a -> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SBV a -> SBool
predicate SList x
xs SBV a
a = Forall nx [x] -> Forall na a -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
a <- free na
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> (Forall na a -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> SBool) -> Proof)
-> (Forall na a -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' -> Forall nx [x] -> Forall na a -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (Forall na a
a' :: Forall na a)
InductionStyle
StrongInduction -> String -> (Forall nx [x] -> Forall na a -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x] -> Forall na a -> SBool) -> Proof)
-> (Forall nx [x] -> Forall na a -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) Forall na a
a' -> SList x
xs' SList x -> SList x -> SBool
forall a. SymVal a => SList a -> SList a -> SBool
`lexLeq` SList x
xs SBool -> SBool -> SBool
.=> Forall nx [x] -> Forall na a -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (Forall na a
a' :: Forall na a)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs a
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil a
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = []."
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ")") (predicate (x SL..: xs) a)
}
instance forall na a nb b nx x z. (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nx, SymVal x, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall na a -> Forall nb b -> SBool)
(SBV x -> SList x -> SBV a -> SBV b -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x] -> Forall na a -> Forall nb b -> SBool) =>
InductionStyle
-> (Forall nx [x] -> Forall na a -> Forall nb b -> SBool)
-> (Proof
-> SBV x -> SList x -> SBV a -> SBV b -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x] -> Forall na a -> Forall nb b -> SBool
result Proof
-> SBV x -> SList x -> SBV a -> SBV b -> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SBV a -> SBV b -> SBool
predicate SList x
xs SBV a
a SBV b
b = Forall nx [x] -> Forall na a -> Forall nb b -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
a <- free na
b <- free nb
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> (Forall na a -> Forall nb b -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> Forall nb b -> SBool) -> Proof)
-> (Forall na a -> Forall nb b -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' -> Forall nx [x] -> Forall na a -> Forall nb b -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b)
InductionStyle
StrongInduction -> String
-> (Forall nx [x] -> Forall na a -> Forall nb b -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x] -> Forall na a -> Forall nb b -> SBool) -> Proof)
-> (Forall nx [x] -> Forall na a -> Forall nb b -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) Forall na a
a' Forall nb b
b' -> SList x
xs' SList x -> SList x -> SBool
forall a. SymVal a => SList a -> SList a -> SBool
`lexLeq` SList x
xs SBool -> SBool -> SBool
.=> Forall nx [x] -> Forall na a -> Forall nb b -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs a b
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil a b
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = []."
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ")") (predicate (x SL..: xs) a b)
}
instance forall na a nb b nc c nx x z. (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nx, SymVal x, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> SBool)
(SBV x -> SList x -> SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall na a -> Forall nb b -> Forall nc c -> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV a
-> SBV b
-> SBV c
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> SBool
result Proof
-> SBV x
-> SList x
-> SBV a
-> SBV b
-> SBV c
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SBV a -> SBV b -> SBV c -> SBool
predicate SList x
xs SBV a
a SBV b
b SBV c
c = Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
a <- free na
b <- free nb
c <- free nc
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof)
-> (Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' -> Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) Forall na a
a' Forall nb b
b' Forall nc c
c' -> SList x
xs' SList x -> SList x -> SBool
forall a. SymVal a => SList a -> SList a -> SBool
`lexLeq` SList x
xs SBool -> SBool -> SBool
.=> Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs a b c
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil a b c
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = []."
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ")") (predicate (x SL..: xs) a b c)
}
instance forall na a nb b nc c nd d nx x z. (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, KnownSymbol nx, SymVal x, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
(SBV x -> SList x -> SBV a -> SBV b -> SBV c -> SBV d -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result Proof
-> SBV x
-> SList x
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SBV a -> SBV b -> SBV c -> SBV d -> SBool
predicate SList x
xs SBV a
a SBV b
b SBV c
c SBV d
d = Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
nd :: String
nd = Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
a <- free na
b <- free nb
c <- free nc
d <- free nd
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof)
-> (Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' -> Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' -> SList x
xs' SList x -> SList x -> SBool
forall a. SymVal a => SList a -> SList a -> SBool
`lexLeq` SList x
xs SBool -> SBool -> SBool
.=> Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs a b c d
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil a b c d
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = []."
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ")") (predicate (x SL..: xs) a b c d)
}
instance forall na a nb b nc c nd d ne e nx x z. (KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, KnownSymbol ne, SymVal e, KnownSymbol nx, SymVal x, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> Forall ne e -> SBool)
(SBV x -> SList x -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> SBV e
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result Proof
-> SBV x
-> SList x
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> SBV e
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool
predicate SList x
xs SBV a
a SBV b
b SBV c
c SBV d
d SBV e
e = Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d) (SBV e -> Forall ne e
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV e
e)
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
nd :: String
nd = Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd)
ne :: String
ne = Proxy ne -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ne)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
a <- free na
b <- free nb
c <- free nc
d <- free nd
e <- free ne
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof)
-> (Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' Forall ne e
e' -> Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d) (Forall ne e
e' :: Forall ne e)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' Forall ne e
e' -> SList x
xs' SList x -> SList x -> SBool
forall a. SymVal a => SList a -> SList a -> SBool
`lexLeq` SList x
xs SBool -> SBool -> SBool
.=> Forall nx [x]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d) (Forall ne e
e' :: Forall ne e)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs a b c d e
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil a b c d e
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = []."
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ")") (predicate (x SL..: xs) a b c d e)
}
instance (KnownSymbol nx, SymVal x, KnownSymbol ny, SymVal y, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall ny [y] -> SBool)
(SBV x -> SList x -> SBV y -> SList y -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition (Forall nx [x] -> Forall ny [y] -> SBool) =>
InductionStyle
-> (Forall nx [x] -> Forall ny [y] -> SBool)
-> (Proof
-> SBV x -> SList x -> SBV y -> SList y -> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x] -> Forall ny [y] -> SBool
result Proof
-> SBV x -> SList x -> SBV y -> SList y -> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SList y -> SBool
predicate SList x
xs SList y
ys = Forall nx [x] -> Forall ny [y] -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
nys :: String
nys = Proxy ny -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ny)
ny :: String
ny = String -> String
singular String
nys
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
y <- free ny
ys <- free nys
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> SBool -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" (SBool -> Proof) -> SBool -> Proof
forall a b. (a -> b) -> a -> b
$ Forall nx [x] -> Forall ny [y] -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys)
InductionStyle
StrongInduction -> String -> (Forall nx [x] -> Forall ny [y] -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x] -> Forall ny [y] -> SBool) -> Proof)
-> (Forall nx [x] -> Forall ny [y] -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) (Forall SList y
ys' :: Forall ny [y]) -> (SList x
xs', SList y
ys') (SList x, SList y) -> (SList x, SList y) -> SBool
forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
`lexLeq2` (SList x
xs, SList y
ys) SBool -> SBool -> SBool
.=> Forall nx [x] -> Forall ny [y] -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys')
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs y ys
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil SL.nil .&& predicate SL.nil (y SL..: ys) .&& predicate (x SL..: xs) SL.nil
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = [] OR " ++ nys ++ " = []"
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ", " ++ ny ++ ":" ++ nys ++ ")") (predicate (x SL..: xs) (y SL..: ys))
}
instance (KnownSymbol nx, SymVal x, KnownSymbol ny, SymVal y, KnownSymbol na, SymVal a, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool)
(SBV x -> SList x -> SBV y -> SList y -> SBV a -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool) =>
InductionStyle
-> (Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool
result Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SList y -> SBV a -> SBool
predicate SList x
xs SList y
ys SBV a
a = Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
nys :: String
nys = Proxy ny -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ny)
ny :: String
ny = String -> String
singular String
nys
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
y <- free ny
ys <- free nys
a <- free na
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> (Forall na a -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> SBool) -> Proof)
-> (Forall na a -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' -> Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (Forall na a
a' :: Forall na a)
InductionStyle
StrongInduction -> String
-> (Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool) -> Proof)
-> (Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) (Forall SList y
ys' :: Forall ny [y]) Forall na a
a' -> (SList x
xs', SList y
ys') (SList x, SList y) -> (SList x, SList y) -> SBool
forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
`lexLeq2` (SList x
xs, SList y
ys) SBool -> SBool -> SBool
.=> Forall nx [x] -> Forall ny [y] -> Forall na a -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys') (Forall na a
a' :: Forall na a)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs y ys a
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil SL.nil a .&& predicate SL.nil (y SL..: ys) a .&& predicate (x SL..: xs) SL.nil a
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = [] OR " ++ nys ++ " = []"
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ", " ++ ny ++ ":" ++ nys ++ ")") (predicate (x SL..: xs) (y SL..: ys) a)
}
instance (KnownSymbol nx, SymVal x, KnownSymbol ny, SymVal y, KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall ny [y] -> Forall na a -> Forall nb b -> SBool)
(SBV x -> SList x -> SBV y -> SList y -> SBV a -> SBV b -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool
result Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SList y -> SBV a -> SBV b -> SBool
predicate SList x
xs SList y
ys SBV a
a SBV b
b = Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
nys :: String
nys = Proxy ny -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ny)
ny :: String
ny = String -> String
singular String
nys
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
y <- free ny
ys <- free nys
a <- free na
b <- free nb
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String -> (Forall na a -> Forall nb b -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> Forall nb b -> SBool) -> Proof)
-> (Forall na a -> Forall nb b -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' -> Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) (Forall SList y
ys' :: Forall ny [y]) Forall na a
a' Forall nb b
b' -> (SList x
xs', SList y
ys') (SList x, SList y) -> (SList x, SList y) -> SBool
forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
`lexLeq2` (SList x
xs, SList y
ys) SBool -> SBool -> SBool
.=> Forall nx [x]
-> Forall ny [y] -> Forall na a -> Forall nb b -> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs y ys a b
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil SL.nil a b .&& predicate SL.nil (y SL..: ys) a b .&& predicate (x SL..: xs) SL.nil a b
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = [] OR " ++ nys ++ " = []"
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ", " ++ ny ++ ":" ++ nys ++ ")") (predicate (x SL..: xs) (y SL..: ys) a b)
}
instance (KnownSymbol nx, SymVal x, KnownSymbol ny, SymVal y, KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall ny [y] -> Forall na a -> Forall nb b -> Forall nc c -> SBool)
(SBV x -> SList x -> SBV y -> SList y -> SBV a -> SBV b -> SBV c -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> SBV c
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool
result Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> SBV c
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SList y -> SBV a -> SBV b -> SBV c -> SBool
predicate SList x
xs SList y
ys SBV a
a SBV b
b SBV c
c = Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
nys :: String
nys = Proxy ny -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ny)
ny :: String
ny = String -> String
singular String
nys
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
y <- free ny
ys <- free nys
a <- free na
b <- free nb
c <- free nc
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof)
-> (Forall na a -> Forall nb b -> Forall nc c -> SBool) -> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' -> Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) (Forall SList y
ys' :: Forall ny [y]) Forall na a
a' Forall nb b
b' Forall nc c
c' -> (SList x
xs', SList y
ys') (SList x, SList y) -> (SList x, SList y) -> SBool
forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
`lexLeq2` (SList x
xs, SList y
ys) SBool -> SBool -> SBool
.=> Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs y ys a b c
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil SL.nil a b c .&& predicate SL.nil (y SL..: ys) a b c .&& predicate (x SL..: xs) SL.nil a b c
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = [] OR " ++ nys ++ " = []"
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ", " ++ ny ++ ":" ++ nys ++ ")") (predicate (x SL..: xs) (y SL..: ys) a b c)
}
instance (KnownSymbol nx, SymVal x, KnownSymbol ny, SymVal y, KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall ny [y] -> Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
(SBV x -> SList x -> SBV y -> SList y -> SBV a -> SBV b -> SBV c -> SBV d -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x -> SList y -> SBV a -> SBV b -> SBV c -> SBV d -> SBool
predicate SList x
xs SList y
ys SBV a
a SBV b
b SBV c
c SBV d
d = Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
nys :: String
nys = Proxy ny -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ny)
ny :: String
ny = String -> String
singular String
nys
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
nd :: String
nd = Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd)
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
y <- free ny
ys <- free nys
a <- free na
b <- free nb
c <- free nc
d <- free nd
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof)
-> (Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' -> Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) (Forall SList y
ys' :: Forall ny [y]) Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' -> (SList x
xs', SList y
ys') (SList x, SList y) -> (SList x, SList y) -> SBool
forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
`lexLeq2` (SList x
xs, SList y
ys) SBool -> SBool -> SBool
.=> Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs y ys a b c d
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil SL.nil a b c d .&& predicate SL.nil (y SL..: ys) a b c d .&& predicate (x SL..: xs) SL.nil a b c d
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = [] OR " ++ nys ++ " = []"
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ", " ++ ny ++ ":" ++ nys ++ ")") (predicate (x SL..: xs) (y SL..: ys) a b c d)
}
instance (KnownSymbol nx, SymVal x, KnownSymbol ny, SymVal y, KnownSymbol na, SymVal a, KnownSymbol nb, SymVal b, KnownSymbol nc, SymVal c, KnownSymbol nd, SymVal d, KnownSymbol ne, SymVal e, EqSymbolic z)
=> Inductive (Forall nx [x] -> Forall ny [y] -> Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> Forall ne e -> SBool)
(SBV x -> SList x -> SBV y -> SList y -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> (SBool, [ProofStep z]))
where
inductionStrategy :: Proposition
(Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool) =>
InductionStyle
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> (Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> SBV e
-> (SBool, [ProofStep z]))
-> Symbolic InductionStrategy
inductionStrategy InductionStyle
style Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result Proof
-> SBV x
-> SList x
-> SBV y
-> SList y
-> SBV a
-> SBV b
-> SBV c
-> SBV d
-> SBV e
-> (SBool, [ProofStep z])
steps = do
let predicate :: SList x
-> SList y -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool
predicate SList x
xs SList y
ys SBV a
a SBV b
b SBV c
c SBV d
d SBV e
e = Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d) (SBV e -> Forall ne e
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV e
e)
nxs :: String
nxs = Proxy nx -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nx)
nx :: String
nx = String -> String
singular String
nxs
nys :: String
nys = Proxy ny -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ny)
ny :: String
ny = String -> String
singular String
nys
na :: String
na = Proxy na -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @na)
nb :: String
nb = Proxy nb -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nb)
nc :: String
nc = Proxy nc -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nc)
nd :: String
nd = Proxy nd -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nd)
ne :: String
ne = Proxy ne -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @ne)
x <- String -> Symbolic (SBV x)
forall a. SymVal a => String -> Symbolic (SBV a)
free String
nx
xs <- free nxs
y <- free ny
ys <- free nys
a <- free na
b <- free nb
c <- free nc
d <- free nd
e <- free ne
let ih = case InductionStyle
style of
InductionStyle
RegularInduction -> String
-> (Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof)
-> (Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \ Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' Forall ne e
e' -> Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs) (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys) (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d) (Forall ne e
e' :: Forall ne e)
InductionStyle
StrongInduction -> String
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a. Proposition a => String -> a -> Proof
internalAxiom String
"IH" ((Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof)
-> (Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> Proof
forall a b. (a -> b) -> a -> b
$ \(Forall SList x
xs' :: Forall nx [x]) (Forall SList y
ys' :: Forall ny [y]) Forall na a
a' Forall nb b
b' Forall nc c
c' Forall nd d
d' Forall ne e
e' -> (SList x
xs', SList y
ys') (SList x, SList y) -> (SList x, SList y) -> SBool
forall a b.
(SymVal a, SymVal b) =>
(SList a, SList b) -> (SList a, SList b) -> SBool
`lexLeq2` (SList x
xs, SList y
ys) SBool -> SBool -> SBool
.=> Forall nx [x]
-> Forall ny [y]
-> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
result (SList x -> Forall nx [x]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList x
xs') (SList y -> Forall ny [y]
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SList y
ys') (Forall na a
a' :: Forall na a) (Forall nb b
b' :: Forall nb b) (Forall nc c
c' :: Forall nc c) (Forall nd d
d' :: Forall nd d) (Forall ne e
e' :: Forall ne e)
CalcStrategy { calcIntros, calcProofSteps } = mkCalcSteps $ steps ih x xs y ys a b c d e
pure InductionStrategy {
inductionIntros = calcIntros
, inductionBaseCase = predicate SL.nil SL.nil a b c d e .&& predicate SL.nil (y SL..: ys) a b c d e .&& predicate (x SL..: xs) SL.nil a b c d e
, inductionProofSteps = calcProofSteps
, inductionBaseFailureMsg = "Property fails for " ++ nxs ++ " = [] OR " ++ nys ++ " = []"
, inductiveStep = observeIf not ("P(" ++ nx ++ ":" ++ nxs ++ ", " ++ ny ++ ":" ++ nys ++ ")") (predicate (x SL..: xs) (y SL..: ys) a b c d e)
}
newtype Inst (nm :: Symbol) a = Inst (SBV a)
instance KnownSymbol nm => Show (Inst nm a) where
show :: Inst nm a -> String
show (Inst SBV a
a) = Proxy nm -> String
forall (n :: Symbol) (proxy :: Symbol -> *).
KnownSymbol n =>
proxy n -> String
symbolVal (forall {k} (t :: k). Proxy t
forall (t :: Symbol). Proxy t
Proxy @nm) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" |-> " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SBV a -> String
forall a. Show a => a -> String
show SBV a
a
class Instantiatable a where
at :: Proof -> a -> Proof
instance (KnownSymbol na, HasKind a, Typeable a) => Instantiatable (Inst na a) where
at :: Proof -> Inst na a -> Proof
at = ((Forall na a -> SBool) -> Inst na a -> SBool)
-> Proof -> Inst na a -> Proof
forall f arg.
(Typeable f, Show arg) =>
(f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate (((Forall na a -> SBool) -> Inst na a -> SBool)
-> Proof -> Inst na a -> Proof)
-> ((Forall na a -> SBool) -> Inst na a -> SBool)
-> Proof
-> Inst na a
-> Proof
forall a b. (a -> b) -> a -> b
$ \Forall na a -> SBool
f (Inst SBV a
a) -> Forall na a -> SBool
f (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a :: Forall na a)
instance ( KnownSymbol na, HasKind a, Typeable a
, KnownSymbol nb, HasKind b, Typeable b
) => Instantiatable (Inst na a, Inst nb b) where
at :: Proof -> (Inst na a, Inst nb b) -> Proof
at = ((Forall na a -> Forall nb b -> SBool)
-> (Inst na a, Inst nb b) -> SBool)
-> Proof -> (Inst na a, Inst nb b) -> Proof
forall f arg.
(Typeable f, Show arg) =>
(f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate (((Forall na a -> Forall nb b -> SBool)
-> (Inst na a, Inst nb b) -> SBool)
-> Proof -> (Inst na a, Inst nb b) -> Proof)
-> ((Forall na a -> Forall nb b -> SBool)
-> (Inst na a, Inst nb b) -> SBool)
-> Proof
-> (Inst na a, Inst nb b)
-> Proof
forall a b. (a -> b) -> a -> b
$ \Forall na a -> Forall nb b -> SBool
f (Inst SBV a
a, Inst SBV b
b) -> Forall na a -> Forall nb b -> SBool
f (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a :: Forall na a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b :: Forall nb b)
instance ( KnownSymbol na, HasKind a, Typeable a
, KnownSymbol nb, HasKind b, Typeable b
, KnownSymbol nc, HasKind c, Typeable c
) => Instantiatable (Inst na a, Inst nb b, Inst nc c) where
at :: Proof -> (Inst na a, Inst nb b, Inst nc c) -> Proof
at = ((Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> (Inst na a, Inst nb b, Inst nc c) -> SBool)
-> Proof -> (Inst na a, Inst nb b, Inst nc c) -> Proof
forall f arg.
(Typeable f, Show arg) =>
(f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate (((Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> (Inst na a, Inst nb b, Inst nc c) -> SBool)
-> Proof -> (Inst na a, Inst nb b, Inst nc c) -> Proof)
-> ((Forall na a -> Forall nb b -> Forall nc c -> SBool)
-> (Inst na a, Inst nb b, Inst nc c) -> SBool)
-> Proof
-> (Inst na a, Inst nb b, Inst nc c)
-> Proof
forall a b. (a -> b) -> a -> b
$ \Forall na a -> Forall nb b -> Forall nc c -> SBool
f (Inst SBV a
a, Inst SBV b
b, Inst SBV c
c) -> Forall na a -> Forall nb b -> Forall nc c -> SBool
f (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a :: Forall na a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b :: Forall nb b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c :: Forall nc c)
instance ( KnownSymbol na, HasKind a, Typeable a
, KnownSymbol nb, HasKind b, Typeable b
, KnownSymbol nc, HasKind c, Typeable c
, KnownSymbol nd, HasKind d, Typeable d
) => Instantiatable (Inst na a, Inst nb b, Inst nc c, Inst nd d) where
at :: Proof -> (Inst na a, Inst nb b, Inst nc c, Inst nd d) -> Proof
at = ((Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d) -> SBool)
-> Proof -> (Inst na a, Inst nb b, Inst nc c, Inst nd d) -> Proof
forall f arg.
(Typeable f, Show arg) =>
(f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate (((Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d) -> SBool)
-> Proof -> (Inst na a, Inst nb b, Inst nc c, Inst nd d) -> Proof)
-> ((Forall na a
-> Forall nb b -> Forall nc c -> Forall nd d -> SBool)
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d) -> SBool)
-> Proof
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d)
-> Proof
forall a b. (a -> b) -> a -> b
$ \Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool
f (Inst SBV a
a, Inst SBV b
b, Inst SBV c
c, Inst SBV d
d) -> Forall na a -> Forall nb b -> Forall nc c -> Forall nd d -> SBool
f (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a :: Forall na a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b :: Forall nb b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c :: Forall nc c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d :: Forall nd d)
instance ( KnownSymbol na, HasKind a, Typeable a
, KnownSymbol nb, HasKind b, Typeable b
, KnownSymbol nc, HasKind c, Typeable c
, KnownSymbol nd, HasKind d, Typeable d
, KnownSymbol ne, HasKind e, Typeable e
) => Instantiatable (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e) where
at :: Proof
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e) -> Proof
at = ((Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e)
-> SBool)
-> Proof
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e)
-> Proof
forall f arg.
(Typeable f, Show arg) =>
(f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate (((Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e)
-> SBool)
-> Proof
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e)
-> Proof)
-> ((Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool)
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e)
-> SBool)
-> Proof
-> (Inst na a, Inst nb b, Inst nc c, Inst nd d, Inst ne e)
-> Proof
forall a b. (a -> b) -> a -> b
$ \Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
f (Inst SBV a
a, Inst SBV b
b, Inst SBV c
c, Inst SBV d
d, Inst SBV e
e) -> Forall na a
-> Forall nb b
-> Forall nc c
-> Forall nd d
-> Forall ne e
-> SBool
f (SBV a -> Forall na a
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV a
a :: Forall na a) (SBV b -> Forall nb b
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV b
b :: Forall nb b) (SBV c -> Forall nc c
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV c
c :: Forall nc c) (SBV d -> Forall nd d
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV d
d :: Forall nd d) (SBV e -> Forall ne e
forall (nm :: Symbol) a. SBV a -> Forall nm a
Forall SBV e
e :: Forall ne e)
instantiate :: (Typeable f, Show arg) => (f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate :: forall f arg.
(Typeable f, Show arg) =>
(f -> arg -> SBool) -> Proof -> arg -> Proof
instantiate f -> arg -> SBool
ap p :: Proof
p@Proof{Dynamic
getProp :: Proof -> Dynamic
getProp :: Dynamic
getProp, String
proofName :: Proof -> String
proofName :: String
proofName} arg
a = case Dynamic -> Maybe f
forall a. Typeable a => Dynamic -> Maybe a
fromDynamic Dynamic
getProp of
Maybe f
Nothing -> Proof
cantInstantiate
Just f
f -> let result :: SBool
result = f
f f -> arg -> SBool
`ap` arg
a
nm :: String
nm = String
proofName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" @ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
paren String
sha
in Proof
p { getProof = label nm result
, getProp = toDyn result
, proofName = nm
}
where sha :: String
sha = arg -> String
forall a. Show a => a -> String
show arg
a
cantInstantiate :: Proof
cantInstantiate = String -> Proof
forall a. HasCallStack => String -> a
error (String -> Proof) -> String -> Proof
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [ String
"at: Cannot instantiate proof:"
, String
" Name: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
proofName
, String
" Type: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
trim (Dynamic -> String
forall a. Show a => a -> String
show Dynamic
getProp)
, String
" At : " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
sha
]
trim :: String -> String
trim (Char
'<':Char
'<':String
s) = String -> String
forall a. [a] -> [a]
reverse (String -> String
trimE (String -> String
forall a. [a] -> [a]
reverse String
s))
trim String
s = String
s
trimE :: String -> String
trimE (Char
'>':Char
'>':String
s) = String
s
trimE String
s = String
s
paren :: String -> String
paren String
s | String
"(" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
s Bool -> Bool -> Bool
&& String
")" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
s = String
s
| Bool -> Bool
not ((Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Char -> Bool
isSpace String
s) = String
s
| Bool
True = Char
'(' Char -> String -> String
forall a. a -> [a] -> [a]
: String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
data Helper = HelperProof Proof
| HelperAssum SBool
| HelperCase String [SBool]
getHelperProofs :: [Helper] -> [Proof]
getHelperProofs :: [Helper] -> [Proof]
getHelperProofs = (Helper -> [Proof]) -> [Helper] -> [Proof]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Helper -> [Proof]
get
where get :: Helper -> [Proof]
get (HelperProof Proof
p) = [Proof
p]
get HelperAssum {} = []
get HelperCase {} = []
getHelperAssumes :: [Helper] -> [SBool]
getHelperAssumes :: [Helper] -> [SBool]
getHelperAssumes = (Helper -> [SBool]) -> [Helper] -> [SBool]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap Helper -> [SBool]
get
where get :: Helper -> [SBool]
get HelperProof {} = []
get (HelperAssum SBool
b) = [SBool
b]
get HelperCase {} = []
hyp :: SBool -> Helper
hyp :: SBool -> Helper
hyp = SBool -> Helper
HelperAssum
hprf :: Proof -> Helper
hprf :: Proof -> Helper
hprf = Proof -> Helper
HelperProof
data ProofStep a = SingleStep a [Helper]
class ProofHint a b where
(??) :: a -> b -> ProofStep a
infixl 2 ??
instance ProofHint a Proof where
a
a ?? :: a -> Proof -> ProofStep a
?? Proof
p = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a [Proof -> Helper
HelperProof Proof
p]
instance ProofHint a SBool where
a
a ?? :: a -> SBool -> ProofStep a
?? SBool
p = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a [SBool -> Helper
HelperAssum SBool
p]
instance ProofHint a Helper where
a
a ?? :: a -> Helper -> ProofStep a
?? Helper
h = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a [Helper
h]
instance ProofHint a [Proof] where
a
a ?? :: a -> [Proof] -> ProofStep a
?? [Proof]
ps = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a ((Proof -> Helper) -> [Proof] -> [Helper]
forall a b. (a -> b) -> [a] -> [b]
map Proof -> Helper
HelperProof [Proof]
ps)
instance ProofHint a [SBool] where
a
a ?? :: a -> [SBool] -> ProofStep a
?? [SBool]
ps = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a ((SBool -> Helper) -> [SBool] -> [Helper]
forall a b. (a -> b) -> [a] -> [b]
map SBool -> Helper
HelperAssum [SBool]
ps)
instance ProofHint a [Helper] where
a
a ?? :: a -> [Helper] -> ProofStep a
?? [Helper]
hs = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a [Helper]
hs
instance ProofHint a String where
a
a ?? :: a -> String -> ProofStep a
?? String
_ = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
a []
type family ChainsTo a where
ChainsTo (ProofStep a) = [ProofStep a]
ChainsTo a = [ProofStep a]
(=:) :: ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
=: :: forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
(=:) = a -> ChainsTo a -> ChainsTo a
forall a b. ChainStep a b => a -> b -> b
chain
infixr 1 =:
(≡) :: ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
≡ :: forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
(≡) = a -> ChainsTo a -> ChainsTo a
forall a. ChainStep a (ChainsTo a) => a -> ChainsTo a -> ChainsTo a
(=:)
infixr 1 ≡
class ChainStep a b where
chain :: a -> b -> b
instance ChainStep a [ProofStep a] where
chain :: a -> [ProofStep a] -> [ProofStep a]
chain a
x [ProofStep a]
y = a -> [Helper] -> ProofStep a
forall a. a -> [Helper] -> ProofStep a
SingleStep a
x [] ProofStep a -> [ProofStep a] -> [ProofStep a]
forall a. a -> [a] -> [a]
: [ProofStep a]
y
instance ChainStep (ProofStep a) [ProofStep a] where
chain :: ProofStep a -> [ProofStep a] -> [ProofStep a]
chain ProofStep a
x [ProofStep a]
y = ProofStep a
x ProofStep a -> [ProofStep a] -> [ProofStep a]
forall a. a -> [a] -> [a]
: [ProofStep a]
y
qed :: [ProofStep a]
qed :: forall a. [ProofStep a]
qed = []
(|-) :: [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
[SBool]
bs |- :: forall a. [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
|- [ProofStep a]
ps = ([SBool] -> SBool
sAnd [SBool]
bs, [ProofStep a]
ps)
infixl 0 |-
(⊢) :: [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
⊢ :: forall a. [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
(⊢) = [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
forall a. [SBool] -> [ProofStep a] -> (SBool, [ProofStep a])
(|-)
infixl 0 ⊢
(⁇) :: ProofHint a b => a -> b -> ProofStep a
⁇ :: forall a b. ProofHint a b => a -> b -> ProofStep a
(⁇) = a -> b -> ProofStep a
forall a b. ProofHint a b => a -> b -> ProofStep a
(??)
infixl 2 ⁇
cases :: String -> [SBool] -> Helper
cases :: String -> [SBool] -> Helper
cases = String -> [SBool] -> Helper
HelperCase