{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wall -Werror #-}
module Data.SBV.Tools.Polynomial (
Polynomial(..), crc, crcBV, ites, mdp, addPoly
) where
import Data.Bits (Bits(..))
import Data.List (genericTake)
import Data.Maybe (fromJust, fromMaybe)
import Data.Word (Word8, Word16, Word32, Word64)
import Data.SBV.Core.Data
import Data.SBV.Core.Kind
import Data.SBV.Core.Sized
import Data.SBV.Core.Model
import GHC.TypeLits
class (Num a, Bits a) => Polynomial a where
polynomial :: [Int] -> a
pAdd :: a -> a -> a
pMult :: (a, a, [Int]) -> a
pDiv :: a -> a -> a
pMod :: a -> a -> a
pDivMod :: a -> a -> (a, a)
showPoly :: a -> String
showPolynomial :: Bool -> a -> String
{-# MINIMAL pMult, pDivMod, showPolynomial #-}
polynomial = (Int -> a -> a) -> a -> [Int] -> a
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ((a -> Int -> a) -> Int -> a -> a
forall a b c. (a -> b -> c) -> b -> a -> c
flip a -> Int -> a
forall a. Bits a => a -> Int -> a
setBit) a
0
pAdd = a -> a -> a
forall a. Bits a => a -> a -> a
xor
pDiv a
x a
y = (a, a) -> a
forall a b. (a, b) -> a
fst (a -> a -> (a, a)
forall a. Polynomial a => a -> a -> (a, a)
pDivMod a
x a
y)
pMod a
x a
y = (a, a) -> a
forall a b. (a, b) -> b
snd (a -> a -> (a, a)
forall a. Polynomial a => a -> a -> (a, a)
pDivMod a
x a
y)
showPoly = Bool -> a -> String
forall a. Polynomial a => Bool -> a -> String
showPolynomial Bool
False
instance Polynomial Word8 where {showPolynomial :: Bool -> Word8 -> String
showPolynomial = Bool -> Word8 -> String
forall a. Bits a => Bool -> a -> String
sp; pMult :: (Word8, Word8, [Int]) -> Word8
pMult = ((SBV Word8, SBV Word8, [Int]) -> SBV Word8)
-> (Word8, Word8, [Int]) -> Word8
forall a.
SymVal a =>
((SBV a, SBV a, [Int]) -> SBV a) -> (a, a, [Int]) -> a
lift (SBV Word8, SBV Word8, [Int]) -> SBV Word8
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: Word8 -> Word8 -> (Word8, Word8)
pDivMod = (SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8))
-> Word8 -> Word8 -> (Word8, Word8)
forall a.
SymVal a =>
(SBV a -> SBV a -> (SBV a, SBV a)) -> a -> a -> (a, a)
liftC SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial Word16 where {showPolynomial :: Bool -> Word16 -> String
showPolynomial = Bool -> Word16 -> String
forall a. Bits a => Bool -> a -> String
sp; pMult :: (Word16, Word16, [Int]) -> Word16
pMult = ((SBV Word16, SBV Word16, [Int]) -> SBV Word16)
-> (Word16, Word16, [Int]) -> Word16
forall a.
SymVal a =>
((SBV a, SBV a, [Int]) -> SBV a) -> (a, a, [Int]) -> a
lift (SBV Word16, SBV Word16, [Int]) -> SBV Word16
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: Word16 -> Word16 -> (Word16, Word16)
pDivMod = (SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16))
-> Word16 -> Word16 -> (Word16, Word16)
forall a.
SymVal a =>
(SBV a -> SBV a -> (SBV a, SBV a)) -> a -> a -> (a, a)
liftC SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial Word32 where {showPolynomial :: Bool -> Word32 -> String
showPolynomial = Bool -> Word32 -> String
forall a. Bits a => Bool -> a -> String
sp; pMult :: (Word32, Word32, [Int]) -> Word32
pMult = ((SBV Word32, SBV Word32, [Int]) -> SBV Word32)
-> (Word32, Word32, [Int]) -> Word32
forall a.
SymVal a =>
((SBV a, SBV a, [Int]) -> SBV a) -> (a, a, [Int]) -> a
lift (SBV Word32, SBV Word32, [Int]) -> SBV Word32
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: Word32 -> Word32 -> (Word32, Word32)
pDivMod = (SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32))
-> Word32 -> Word32 -> (Word32, Word32)
forall a.
SymVal a =>
(SBV a -> SBV a -> (SBV a, SBV a)) -> a -> a -> (a, a)
liftC SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial Word64 where {showPolynomial :: Bool -> Word64 -> String
showPolynomial = Bool -> Word64 -> String
forall a. Bits a => Bool -> a -> String
sp; pMult :: (Word64, Word64, [Int]) -> Word64
pMult = ((SBV Word64, SBV Word64, [Int]) -> SBV Word64)
-> (Word64, Word64, [Int]) -> Word64
forall a.
SymVal a =>
((SBV a, SBV a, [Int]) -> SBV a) -> (a, a, [Int]) -> a
lift (SBV Word64, SBV Word64, [Int]) -> SBV Word64
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: Word64 -> Word64 -> (Word64, Word64)
pDivMod = (SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64))
-> Word64 -> Word64 -> (Word64, Word64)
forall a.
SymVal a =>
(SBV a -> SBV a -> (SBV a, SBV a)) -> a -> a -> (a, a)
liftC SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial SWord8 where {showPolynomial :: Bool -> SBV Word8 -> String
showPolynomial Bool
b = (Word8 -> String) -> SBV Word8 -> String
forall a. SymVal a => (a -> String) -> SBV a -> String
liftS (Bool -> Word8 -> String
forall a. Bits a => Bool -> a -> String
sp Bool
b); pMult :: (SBV Word8, SBV Word8, [Int]) -> SBV Word8
pMult = (SBV Word8, SBV Word8, [Int]) -> SBV Word8
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
pDivMod = SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial SWord16 where {showPolynomial :: Bool -> SBV Word16 -> String
showPolynomial Bool
b = (Word16 -> String) -> SBV Word16 -> String
forall a. SymVal a => (a -> String) -> SBV a -> String
liftS (Bool -> Word16 -> String
forall a. Bits a => Bool -> a -> String
sp Bool
b); pMult :: (SBV Word16, SBV Word16, [Int]) -> SBV Word16
pMult = (SBV Word16, SBV Word16, [Int]) -> SBV Word16
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
pDivMod = SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial SWord32 where {showPolynomial :: Bool -> SBV Word32 -> String
showPolynomial Bool
b = (Word32 -> String) -> SBV Word32 -> String
forall a. SymVal a => (a -> String) -> SBV a -> String
liftS (Bool -> Word32 -> String
forall a. Bits a => Bool -> a -> String
sp Bool
b); pMult :: (SBV Word32, SBV Word32, [Int]) -> SBV Word32
pMult = (SBV Word32, SBV Word32, [Int]) -> SBV Word32
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
pDivMod = SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance Polynomial SWord64 where {showPolynomial :: Bool -> SBV Word64 -> String
showPolynomial Bool
b = (Word64 -> String) -> SBV Word64 -> String
forall a. SymVal a => (a -> String) -> SBV a -> String
liftS (Bool -> Word64 -> String
forall a. Bits a => Bool -> a -> String
sp Bool
b); pMult :: (SBV Word64, SBV Word64, [Int]) -> SBV Word64
pMult = (SBV Word64, SBV Word64, [Int]) -> SBV Word64
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
pDivMod = SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
instance (KnownNat n, BVIsNonZero n) => Polynomial (SWord n) where {showPolynomial :: Bool -> SWord n -> String
showPolynomial Bool
b = (WordN n -> String) -> SWord n -> String
forall a. SymVal a => (a -> String) -> SBV a -> String
liftS (Bool -> WordN n -> String
forall a. Bits a => Bool -> a -> String
sp Bool
b); pMult :: (SWord n, SWord n, [Int]) -> SWord n
pMult = (SWord n, SWord n, [Int]) -> SWord n
forall a. SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult; pDivMod :: SWord n -> SWord n -> (SWord n, SWord n)
pDivMod = SWord n -> SWord n -> (SWord n, SWord n)
forall a. SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod}
lift :: SymVal a => ((SBV a, SBV a, [Int]) -> SBV a) -> (a, a, [Int]) -> a
lift :: ((SBV a, SBV a, [Int]) -> SBV a) -> (a, a, [Int]) -> a
lift (SBV a, SBV a, [Int]) -> SBV a
f (a
x, a
y, [Int]
z) = Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe a -> a) -> Maybe a -> a
forall a b. (a -> b) -> a -> b
$ SBV a -> Maybe a
forall a. SymVal a => SBV a -> Maybe a
unliteral (SBV a -> Maybe a) -> SBV a -> Maybe a
forall a b. (a -> b) -> a -> b
$ (SBV a, SBV a, [Int]) -> SBV a
f (a -> SBV a
forall a. SymVal a => a -> SBV a
literal a
x, a -> SBV a
forall a. SymVal a => a -> SBV a
literal a
y, [Int]
z)
liftC :: SymVal a => (SBV a -> SBV a -> (SBV a, SBV a)) -> a -> a -> (a, a)
liftC :: (SBV a -> SBV a -> (SBV a, SBV a)) -> a -> a -> (a, a)
liftC SBV a -> SBV a -> (SBV a, SBV a)
f a
x a
y = let (SBV a
a, SBV a
b) = SBV a -> SBV a -> (SBV a, SBV a)
f (a -> SBV a
forall a. SymVal a => a -> SBV a
literal a
x) (a -> SBV a
forall a. SymVal a => a -> SBV a
literal a
y) in (Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJust (SBV a -> Maybe a
forall a. SymVal a => SBV a -> Maybe a
unliteral SBV a
a), Maybe a -> a
forall a. HasCallStack => Maybe a -> a
fromJust (SBV a -> Maybe a
forall a. SymVal a => SBV a -> Maybe a
unliteral SBV a
b))
liftS :: SymVal a => (a -> String) -> SBV a -> String
liftS :: (a -> String) -> SBV a -> String
liftS a -> String
f SBV a
s
| Just a
x <- SBV a -> Maybe a
forall a. SymVal a => SBV a -> Maybe a
unliteral SBV a
s = a -> String
f a
x
| Bool
True = SBV a -> String
forall a. Show a => a -> String
show SBV a
s
sp :: Bits a => Bool -> a -> String
sp :: Bool -> a -> String
sp Bool
st a
a
| [Int] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Int]
cs = Char
'0' Char -> String -> String
forall a. a -> [a] -> [a]
: String
t
| Bool
True = (Int -> String -> String) -> String -> [Int] -> String
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\Int
x String
y -> Int -> String
forall a. (Eq a, Num a, Show a) => a -> String
sh Int
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" + " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
y) (Int -> String
forall a. (Eq a, Num a, Show a) => a -> String
sh ([Int] -> Int
forall a. [a] -> a
last [Int]
cs)) ([Int] -> [Int]
forall a. [a] -> [a]
init [Int]
cs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
t
where t :: String
t | Bool
st = String
" :: GF(2^" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"
| Bool
True = String
""
n :: Int
n = Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe (String -> Int
forall a. HasCallStack => String -> a
error String
"SBV.Polynomial.sp: Unexpected non-finite usage!") (a -> Maybe Int
forall a. Bits a => a -> Maybe Int
bitSizeMaybe a
a)
is :: [Int]
is = [Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1, Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
2 .. Int
0]
cs :: [Int]
cs = ((Int, Bool) -> Int) -> [(Int, Bool)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Bool) -> Int
forall a b. (a, b) -> a
fst ([(Int, Bool)] -> [Int]) -> [(Int, Bool)] -> [Int]
forall a b. (a -> b) -> a -> b
$ ((Int, Bool) -> Bool) -> [(Int, Bool)] -> [(Int, Bool)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Int, Bool) -> Bool
forall a b. (a, b) -> b
snd ([(Int, Bool)] -> [(Int, Bool)]) -> [(Int, Bool)] -> [(Int, Bool)]
forall a b. (a -> b) -> a -> b
$ [Int] -> [Bool] -> [(Int, Bool)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int]
is ((Int -> Bool) -> [Int] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map (a -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit a
a) [Int]
is)
sh :: a -> String
sh a
0 = String
"1"
sh a
1 = String
"x"
sh a
i = String
"x^" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
i
addPoly :: [SBool] -> [SBool] -> [SBool]
addPoly :: [SBool] -> [SBool] -> [SBool]
addPoly [SBool]
xs [] = [SBool]
xs
addPoly [] [SBool]
ys = [SBool]
ys
addPoly (SBool
x:[SBool]
xs) (SBool
y:[SBool]
ys) = SBool
x SBool -> SBool -> SBool
.<+> SBool
y SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: [SBool] -> [SBool] -> [SBool]
addPoly [SBool]
xs [SBool]
ys
ites :: SBool -> [SBool] -> [SBool] -> [SBool]
ites :: SBool -> [SBool] -> [SBool] -> [SBool]
ites SBool
s [SBool]
xs [SBool]
ys
| Just Bool
t <- SBool -> Maybe Bool
forall a. SymVal a => SBV a -> Maybe a
unliteral SBool
s
= if Bool
t then [SBool]
xs else [SBool]
ys
| Bool
True
= [SBool] -> [SBool] -> [SBool]
go [SBool]
xs [SBool]
ys
where go :: [SBool] -> [SBool] -> [SBool]
go [] [] = []
go [] (SBool
b:[SBool]
bs) = SBool -> SBool -> SBool -> SBool
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
s SBool
sFalse SBool
b SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: [SBool] -> [SBool] -> [SBool]
go [] [SBool]
bs
go (SBool
a:[SBool]
as) [] = SBool -> SBool -> SBool -> SBool
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
s SBool
a SBool
sFalse SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: [SBool] -> [SBool] -> [SBool]
go [SBool]
as []
go (SBool
a:[SBool]
as) (SBool
b:[SBool]
bs) = SBool -> SBool -> SBool -> SBool
forall a. Mergeable a => SBool -> a -> a -> a
ite SBool
s SBool
a SBool
b SBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
: [SBool] -> [SBool] -> [SBool]
go [SBool]
as [SBool]
bs
polyMult :: SFiniteBits a => (SBV a, SBV a, [Int]) -> SBV a
polyMult :: (SBV a, SBV a, [Int]) -> SBV a
polyMult (SBV a
x, SBV a
y, [Int]
red)
| SBV a -> Bool
forall a. HasKind a => a -> Bool
isReal SBV a
x
= String -> SBV a
forall a. HasCallStack => String -> a
error (String -> SBV a) -> String -> SBV a
forall a b. (a -> b) -> a -> b
$ String
"SBV.polyMult: Received a real value: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SBV a -> String
forall a. Show a => a -> String
show SBV a
x
| Bool -> Bool
not (SBV a -> Bool
forall a. HasKind a => a -> Bool
isBounded SBV a
x)
= String -> SBV a
forall a. HasCallStack => String -> a
error (String -> SBV a) -> String -> SBV a
forall a b. (a -> b) -> a -> b
$ String
"SBV.polyMult: Received infinite precision value: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SBV a -> String
forall a. Show a => a -> String
show SBV a
x
| Bool
True
= [SBool] -> SBV a
forall a. SFiniteBits a => [SBool] -> SBV a
fromBitsLE ([SBool] -> SBV a) -> [SBool] -> SBV a
forall a b. (a -> b) -> a -> b
$ Int -> [SBool] -> [SBool]
forall i a. Integral i => i -> [a] -> [a]
genericTake Int
sz ([SBool] -> [SBool]) -> [SBool] -> [SBool]
forall a b. (a -> b) -> a -> b
$ [SBool]
r [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ SBool -> [SBool]
forall a. a -> [a]
repeat SBool
sFalse
where ([SBool]
_, [SBool]
r) = [SBool] -> [SBool] -> ([SBool], [SBool])
mdp [SBool]
ms [SBool]
rs
ms :: [SBool]
ms = Int -> [SBool] -> [SBool]
forall i a. Integral i => i -> [a] -> [a]
genericTake (Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
sz) ([SBool] -> [SBool]) -> [SBool] -> [SBool]
forall a b. (a -> b) -> a -> b
$ [SBool] -> [SBool] -> [SBool] -> [SBool]
mul (SBV a -> [SBool]
forall a. SFiniteBits a => SBV a -> [SBool]
blastLE SBV a
x) (SBV a -> [SBool]
forall a. SFiniteBits a => SBV a -> [SBool]
blastLE SBV a
y) [] [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ SBool -> [SBool]
forall a. a -> [a]
repeat SBool
sFalse
rs :: [SBool]
rs = Int -> [SBool] -> [SBool]
forall i a. Integral i => i -> [a] -> [a]
genericTake (Int
2Int -> Int -> Int
forall a. Num a => a -> a -> a
*Int
sz) ([SBool] -> [SBool]) -> [SBool] -> [SBool]
forall a b. (a -> b) -> a -> b
$ [Bool -> SBool
fromBool (Int
i Int -> [Int] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int]
red) | Int
i <- [Int
0 .. (Int -> Int -> Int) -> Int -> [Int] -> Int
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Int -> Int -> Int
forall a. Ord a => a -> a -> a
max Int
0 [Int]
red] ] [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ SBool -> [SBool]
forall a. a -> [a]
repeat SBool
sFalse
sz :: Int
sz = SBV a -> Int
forall a. HasKind a => a -> Int
intSizeOf SBV a
x
mul :: [SBool] -> [SBool] -> [SBool] -> [SBool]
mul [SBool]
_ [] [SBool]
ps = [SBool]
ps
mul [SBool]
as (SBool
b:[SBool]
bs) [SBool]
ps = [SBool] -> [SBool] -> [SBool] -> [SBool]
mul (SBool
sFalseSBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
:[SBool]
as) [SBool]
bs (SBool -> [SBool] -> [SBool] -> [SBool]
ites SBool
b ([SBool]
as [SBool] -> [SBool] -> [SBool]
`addPoly` [SBool]
ps) [SBool]
ps)
polyDivMod :: SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod :: SBV a -> SBV a -> (SBV a, SBV a)
polyDivMod SBV a
x SBV a
y
| SBV a -> Bool
forall a. HasKind a => a -> Bool
isReal SBV a
x
= String -> (SBV a, SBV a)
forall a. HasCallStack => String -> a
error (String -> (SBV a, SBV a)) -> String -> (SBV a, SBV a)
forall a b. (a -> b) -> a -> b
$ String
"SBV.polyDivMod: Received a real value: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SBV a -> String
forall a. Show a => a -> String
show SBV a
x
| Bool -> Bool
not (SBV a -> Bool
forall a. HasKind a => a -> Bool
isBounded SBV a
x)
= String -> (SBV a, SBV a)
forall a. HasCallStack => String -> a
error (String -> (SBV a, SBV a)) -> String -> (SBV a, SBV a)
forall a b. (a -> b) -> a -> b
$ String
"SBV.polyDivMod: Received infinite precision value: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SBV a -> String
forall a. Show a => a -> String
show SBV a
x
| Bool
True
= SBool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
forall a. Mergeable a => SBool -> a -> a -> a
ite (SBV a
y SBV a -> SBV a -> SBool
forall a. EqSymbolic a => a -> a -> SBool
.== SBV a
0) (SBV a
0, SBV a
x) ([SBool] -> SBV a
adjust [SBool]
d, [SBool] -> SBV a
adjust [SBool]
r)
where adjust :: [SBool] -> SBV a
adjust [SBool]
xs = [SBool] -> SBV a
forall a. SFiniteBits a => [SBool] -> SBV a
fromBitsLE ([SBool] -> SBV a) -> [SBool] -> SBV a
forall a b. (a -> b) -> a -> b
$ Int -> [SBool] -> [SBool]
forall i a. Integral i => i -> [a] -> [a]
genericTake Int
sz ([SBool] -> [SBool]) -> [SBool] -> [SBool]
forall a b. (a -> b) -> a -> b
$ [SBool]
xs [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ SBool -> [SBool]
forall a. a -> [a]
repeat SBool
sFalse
sz :: Int
sz = SBV a -> Int
forall a. HasKind a => a -> Int
intSizeOf SBV a
x
([SBool]
d, [SBool]
r) = [SBool] -> [SBool] -> ([SBool], [SBool])
mdp (SBV a -> [SBool]
forall a. SFiniteBits a => SBV a -> [SBool]
blastLE SBV a
x) (SBV a -> [SBool]
forall a. SFiniteBits a => SBV a -> [SBool]
blastLE SBV a
y)
degree :: [SBool] -> Int
degree :: [SBool] -> Int
degree [SBool]
xs = Int -> [SBool] -> Int
forall t. Num t => t -> [SBool] -> t
walk ([SBool] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SBool]
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ([SBool] -> Int) -> [SBool] -> Int
forall a b. (a -> b) -> a -> b
$ [SBool] -> [SBool]
forall a. [a] -> [a]
reverse [SBool]
xs
where walk :: t -> [SBool] -> t
walk t
n [] = t
n
walk t
n (SBool
b:[SBool]
bs)
| Just Bool
t <- SBool -> Maybe Bool
forall a. SymVal a => SBV a -> Maybe a
unliteral SBool
b
= if Bool
t then t
n else t -> [SBool] -> t
walk (t
nt -> t -> t
forall a. Num a => a -> a -> a
-t
1) [SBool]
bs
| Bool
True
= t
n
mdp :: [SBool] -> [SBool] -> ([SBool], [SBool])
mdp :: [SBool] -> [SBool] -> ([SBool], [SBool])
mdp [SBool]
xs [SBool]
ys = Int -> [SBool] -> ([SBool], [SBool])
go ([SBool] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SBool]
ys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) ([SBool] -> [SBool]
forall a. [a] -> [a]
reverse [SBool]
ys)
where degTop :: Int
degTop = [SBool] -> Int
degree [SBool]
xs
go :: Int -> [SBool] -> ([SBool], [SBool])
go Int
_ [] = String -> ([SBool], [SBool])
forall a. HasCallStack => String -> a
error String
"SBV.Polynomial.mdp: Impossible happened; exhausted ys before hitting 0"
go Int
n (SBool
b:[SBool]
bs)
| Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = ([SBool] -> [SBool]
forall a. [a] -> [a]
reverse [SBool]
qs, [SBool]
rs)
| Bool
True = let ([SBool]
rqs, [SBool]
rrs) = Int -> [SBool] -> ([SBool], [SBool])
go (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [SBool]
bs
in (SBool -> [SBool] -> [SBool] -> [SBool]
ites SBool
b ([SBool] -> [SBool]
forall a. [a] -> [a]
reverse [SBool]
qs) [SBool]
rqs, SBool -> [SBool] -> [SBool] -> [SBool]
ites SBool
b [SBool]
rs [SBool]
rrs)
where degQuot :: Int
degQuot = Int
degTop Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n
ys' :: [SBool]
ys' = Int -> SBool -> [SBool]
forall a. Int -> a -> [a]
replicate Int
degQuot SBool
sFalse [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ [SBool]
ys
([SBool]
qs, [SBool]
rs) = Int -> Int -> [SBool] -> [SBool] -> ([SBool], [SBool])
divx (Int
degQuotInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) Int
degTop [SBool]
xs [SBool]
ys'
idx :: [SBool] -> Int -> SBool
idx :: [SBool] -> Int -> SBool
idx [] Int
_ = SBool
sFalse
idx (SBool
x:[SBool]
_) Int
0 = SBool
x
idx (SBool
_:[SBool]
xs) Int
i = [SBool] -> Int -> SBool
idx [SBool]
xs (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)
divx :: Int -> Int -> [SBool] -> [SBool] -> ([SBool], [SBool])
divx :: Int -> Int -> [SBool] -> [SBool] -> ([SBool], [SBool])
divx Int
n Int
_ [SBool]
xs [SBool]
_ | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0 = ([], [SBool]
xs)
divx Int
n Int
i [SBool]
xs [SBool]
ys' = (SBool
qSBool -> [SBool] -> [SBool]
forall a. a -> [a] -> [a]
:[SBool]
qs, [SBool]
rs)
where q :: SBool
q = [SBool]
xs [SBool] -> Int -> SBool
`idx` Int
i
xs' :: [SBool]
xs' = SBool -> [SBool] -> [SBool] -> [SBool]
ites SBool
q ([SBool]
xs [SBool] -> [SBool] -> [SBool]
`addPoly` [SBool]
ys') [SBool]
xs
([SBool]
qs, [SBool]
rs) = Int -> Int -> [SBool] -> [SBool] -> ([SBool], [SBool])
divx (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [SBool]
xs' ([SBool] -> [SBool]
forall a. [a] -> [a]
tail [SBool]
ys')
crcBV :: Int -> [SBool] -> [SBool] -> [SBool]
crcBV :: Int -> [SBool] -> [SBool] -> [SBool]
crcBV Int
n [SBool]
m [SBool]
p = Int -> [SBool] -> [SBool]
forall a. Int -> [a] -> [a]
take Int
n ([SBool] -> [SBool]) -> [SBool] -> [SBool]
forall a b. (a -> b) -> a -> b
$ [SBool] -> [SBool] -> [SBool]
go (Int -> SBool -> [SBool]
forall a. Int -> a -> [a]
replicate Int
n SBool
sFalse) ([SBool]
m [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ Int -> SBool -> [SBool]
forall a. Int -> a -> [a]
replicate Int
n SBool
sFalse)
where mask :: [SBool]
mask = Int -> [SBool] -> [SBool]
forall a. Int -> [a] -> [a]
drop ([SBool] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [SBool]
p Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [SBool]
p
go :: [SBool] -> [SBool] -> [SBool]
go [SBool]
c [] = [SBool]
c
go [SBool]
c (SBool
b:[SBool]
bs) = [SBool] -> [SBool] -> [SBool]
go [SBool]
next [SBool]
bs
where c' :: [SBool]
c' = Int -> [SBool] -> [SBool]
forall a. Int -> [a] -> [a]
drop Int
1 [SBool]
c [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ [SBool
b]
next :: [SBool]
next = SBool -> [SBool] -> [SBool] -> [SBool]
forall a. Mergeable a => SBool -> a -> a -> a
ite ([SBool] -> SBool
forall a. [a] -> a
head [SBool]
c) ((SBool -> SBool -> SBool) -> [SBool] -> [SBool] -> [SBool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith SBool -> SBool -> SBool
(.<+>) [SBool]
c' [SBool]
mask) [SBool]
c'
crc :: (SFiniteBits a, SFiniteBits b) => Int -> SBV a -> SBV b -> SBV b
crc :: Int -> SBV a -> SBV b -> SBV b
crc Int
n SBV a
m SBV b
p
| SBV a -> Bool
forall a. HasKind a => a -> Bool
isReal SBV a
m Bool -> Bool -> Bool
|| SBV b -> Bool
forall a. HasKind a => a -> Bool
isReal SBV b
p
= String -> SBV b
forall a. HasCallStack => String -> a
error (String -> SBV b) -> String -> SBV b
forall a b. (a -> b) -> a -> b
$ String
"SBV.crc: Received a real value: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (SBV a, SBV b) -> String
forall a. Show a => a -> String
show (SBV a
m, SBV b
p)
| Bool -> Bool
not (SBV a -> Bool
forall a. HasKind a => a -> Bool
isBounded SBV a
m) Bool -> Bool -> Bool
|| Bool -> Bool
not (SBV b -> Bool
forall a. HasKind a => a -> Bool
isBounded SBV b
p)
= String -> SBV b
forall a. HasCallStack => String -> a
error (String -> SBV b) -> String -> SBV b
forall a b. (a -> b) -> a -> b
$ String
"SBV.crc: Received an infinite precision value: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (SBV a, SBV b) -> String
forall a. Show a => a -> String
show (SBV a
m, SBV b
p)
| Bool
True
= [SBool] -> SBV b
forall a. SFiniteBits a => [SBool] -> SBV a
fromBitsBE ([SBool] -> SBV b) -> [SBool] -> SBV b
forall a b. (a -> b) -> a -> b
$ Int -> SBool -> [SBool]
forall a. Int -> a -> [a]
replicate (Int
sz Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) SBool
sFalse [SBool] -> [SBool] -> [SBool]
forall a. [a] -> [a] -> [a]
++ Int -> [SBool] -> [SBool] -> [SBool]
crcBV Int
n (SBV a -> [SBool]
forall a. SFiniteBits a => SBV a -> [SBool]
blastBE SBV a
m) (SBV b -> [SBool]
forall a. SFiniteBits a => SBV a -> [SBool]
blastBE SBV b
p)
where sz :: Int
sz = SBV b -> Int
forall a. HasKind a => a -> Int
intSizeOf SBV b
p