module Data.SBV.Examples.PrefixSum.PrefixSum where
import Data.SBV
type PowerList a = [a]
tiePL :: PowerList a -> PowerList a -> PowerList a
tiePL = (++)
zipPL :: PowerList a -> PowerList a -> PowerList a
zipPL [] [] = []
zipPL (x:xs) (y:ys) = x : y : zipPL xs ys
zipPL _ _ = error "zipPL: nonsimilar powerlists received"
unzipPL :: PowerList a -> (PowerList a, PowerList a)
unzipPL = unzip . chunk2
where chunk2 [] = []
chunk2 (x:y:xs) = (x,y) : chunk2 xs
chunk2 _ = error "fl.unzipPL: malformed powerlist"
ps :: (a, a -> a -> a) -> PowerList a -> PowerList a
ps (_, f) = scanl1 f
fl :: (a, a -> a -> a) -> PowerList a -> PowerList a
fl _ [] = error "fl: malformed (empty) powerlist"
fl _ [x] = [x]
fl (zero, f) pl = zipPL (zipWith f (rsh flpq) p) flpq
where (p, q) = unzipPL pl
pq = zipWith f p q
flpq = fl (zero, f) pq
rsh xs = zero : init xs
flIsCorrect :: Int -> (forall a. (OrdSymbolic a, Bits a) => (a, a -> a -> a)) -> Symbolic SBool
flIsCorrect n zf = do
args :: PowerList SWord32 <- mapM (const free_) [1..n]
output $ ps zf args .== fl zf args
thm1, thm2 :: IO ThmResult
thm1 = prove $ flIsCorrect 8 (0, (+))
thm2 = prove $ flIsCorrect 16 (0, smax)