    -----------------------------------------------------------------------------
    -- |
    -- Module    : Data.SBV.Core.Model
    -- Copyright : (c) Levent Erkok
    -- License   : BSD3
    -- Maintainer: erkokl@gmail.com
    -- Stability : experimental
    --
    -- Instance declarations for our symbolic world
    -----------------------------------------------------------------------------

    {-# LANGUAGE BangPatterns        #-}
    {-# LANGUAGE DefaultSignatures   #-}
    {-# LANGUAGE FlexibleContexts    #-}
    {-# LANGUAGE FlexibleInstances   #-}
    {-# LANGUAGE Rank2Types          #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TypeApplications    #-}
    {-# LANGUAGE TypeFamilies        #-}
    {-# LANGUAGE TypeOperators       #-}

    {-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}

    module Data.SBV.Core.Model (
        Mergeable(..), Equality(..), EqSymbolic(..), OrdSymbolic(..), SDivisible(..), Uninterpreted(..), Metric(..), minimize, maximize, assertWithPenalty, SIntegral, SFiniteBits(..)
      , ite, iteLazy, sFromIntegral, sShiftLeft, sShiftRight, sRotateLeft, sBarrelRotateLeft, sRotateRight, sBarrelRotateRight, sSignedShiftArithRight, (.^)
      , oneIf, genVar, genVar_, forall, forall_, exists, exists_
      , pbAtMost, pbAtLeast, pbExactly, pbLe, pbGe, pbEq, pbMutexed, pbStronglyMutexed
      , sBool, sBool_, sBools, sWord8, sWord8_, sWord8s, sWord16, sWord16_, sWord16s, sWord32, sWord32_, sWord32s
      , sWord64, sWord64_, sWord64s, sInt8, sInt8_, sInt8s, sInt16, sInt16_, sInt16s, sInt32, sInt32_, sInt32s, sInt64, sInt64_
      , sInt64s, sInteger, sInteger_, sIntegers, sReal, sReal_, sReals, sFloat, sFloat_, sFloats, sDouble, sDouble_, sDoubles
      , sChar, sChar_, sChars, sString, sString_, sStrings, sList, sList_, sLists
      , SymTuple, sTuple, sTuple_, sTuples
      , sEither, sEither_, sEithers, sMaybe, sMaybe_, sMaybes
      , sSet, sSet_, sSets
      , solve
      , slet
      , sRealToSInteger, label, observe, observeIf, sObserve
      , sAssert
      , liftQRem, liftDMod, symbolicMergeWithKind
      , genLiteral, genFromCV, genMkSymVar
      , sbvQuickCheck
      )
      where

    import Control.Applicative    (ZipList(ZipList))
    import Control.Monad          (when, unless, mplus)
    import Control.Monad.Trans    (liftIO)
    import Control.Monad.IO.Class (MonadIO)

    import GHC.Generics (U1(..), M1(..), (:*:)(..), K1(..))
    import qualified GHC.Generics as G

    import GHC.Stack

    import Data.Array  (Array, Ix, listArray, elems, bounds, rangeSize)
    import Data.Bits   (Bits(..))
    import Data.Char   (toLower, isDigit)
    import Data.Int    (Int8, Int16, Int32, Int64)
    import Data.List   (genericLength, genericIndex, genericTake, unzip4, unzip5, unzip6, unzip7, intercalate, isPrefixOf)
    import Data.Maybe  (fromMaybe, mapMaybe)
    import Data.String (IsString(..))
    import Data.Word   (Word8, Word16, Word32, Word64)

    import qualified Data.Set as Set

    import Data.Proxy
    import Data.Dynamic (fromDynamic, toDyn)

    import Test.QuickCheck                         (Testable(..), Arbitrary(..))
    import qualified Test.QuickCheck.Test    as QC (isSuccess)
    import qualified Test.QuickCheck         as QC (quickCheckResult, counterexample)
    import qualified Test.QuickCheck.Monadic as QC (monadicIO, run, assert, pre, monitor)

    import qualified Data.Foldable as F (toList)

    import Data.SBV.Core.AlgReals
    import Data.SBV.Core.Data
    import Data.SBV.Core.Symbolic
    import Data.SBV.Core.Operations

    import Data.SBV.Provers.Prover (defaultSMTCfg, SafeResult(..), prove)
    import Data.SBV.SMT.SMT        (ThmResult, showModel)

    import Data.SBV.Utils.Lib      (isKString)

    -- Symbolic-Word class instances

    -- | Generate a finite symbolic bitvector, named
    genVar :: MonadSymbolic m => Maybe Quantifier -> Kind -> String -> m (SBV a)
    genVar :: Maybe Quantifier -> Kind -> String -> m (SBV a)
    genVar q :: Maybe Quantifier
    q k :: Kind
    k = Maybe Quantifier -> Kind -> Maybe String -> m (SBV a)
    forall a (m :: * -> *).
    MonadSymbolic m =>
    Maybe Quantifier -> Kind -> Maybe String -> m (SBV a)
    mkSymSBV Maybe Quantifier
    q Kind
    k (Maybe String -> m (SBV a))
    -> (String -> Maybe String) -> String -> m (SBV a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Maybe String
    forall a. a -> Maybe a
    Just

    -- | Generate a finite symbolic bitvector, unnamed
    genVar_ :: MonadSymbolic m => Maybe Quantifier -> Kind -> m (SBV a)
    genVar_ :: Maybe Quantifier -> Kind -> m (SBV a)
    genVar_ q :: Maybe Quantifier
    q k :: Kind
    k = Maybe Quantifier -> Kind -> Maybe String -> m (SBV a)
    forall a (m :: * -> *).
    MonadSymbolic m =>
    Maybe Quantifier -> Kind -> Maybe String -> m (SBV a)
    mkSymSBV Maybe Quantifier
    q Kind
    k Maybe String
    forall a. Maybe a
    Nothing

    -- | Generate a finite constant bitvector
    genLiteral :: Integral a => Kind -> a -> SBV b
    genLiteral :: Kind -> a -> SBV b
    genLiteral k :: Kind
    k = SVal -> SBV b
    forall a. SVal -> SBV a
    SBV (SVal -> SBV b) -> (a -> SVal) -> a -> SBV b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal)
    -> (a -> Either CV (Cached SV)) -> a -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (a -> CV) -> a -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> a -> CV
    forall a. Integral a => Kind -> a -> CV
    mkConstCV Kind
    k

    -- | Convert a constant to an integral value
    genFromCV :: Integral a => CV -> a
    genFromCV :: CV -> a
    genFromCV (CV _ (CInteger x :: Integer
    x)) = Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    x
    genFromCV c :: CV
    c                   = String -> a
    forall a. HasCallStack => String -> a
    error (String -> a) -> String -> a
    forall a b. (a -> b) -> a -> b
    $ "genFromCV: Unsupported non-integral value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    c

    -- | Generalization of 'Data.SBV.genMkSymVar'
    genMkSymVar :: MonadSymbolic m => Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar :: Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar k :: Kind
    k mbq :: Maybe Quantifier
    mbq Nothing  = Maybe Quantifier -> Kind -> m (SBV a)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Maybe Quantifier -> Kind -> m (SBV a)
    genVar_ Maybe Quantifier
    mbq Kind
    k
    genMkSymVar k :: Kind
    k mbq :: Maybe Quantifier
    mbq (Just s :: String
    s) = Maybe Quantifier -> Kind -> String -> m (SBV a)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Maybe Quantifier -> Kind -> String -> m (SBV a)
    genVar  Maybe Quantifier
    mbq Kind
    k String
    s

    instance SymVal Bool where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Bool)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Bool)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KBool
      literal :: Bool -> SBV Bool
    literal  = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Bool) -> (Bool -> SVal) -> Bool -> SBV Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Bool -> SVal
    svBool
      fromCV :: CV -> Bool
    fromCV   = CV -> Bool
    cvToBool

    instance SymVal Word8 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Word8)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Word8)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False 8)
      literal :: Word8 -> SBV Word8
    literal  = Kind -> Word8 -> SBV Word8
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    False 8)
      fromCV :: CV -> Word8
    fromCV   = CV -> Word8
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int8 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Int8)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Int8)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True 8)
      literal :: Int8 -> SBV Int8
    literal  = Kind -> Int8 -> SBV Int8
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    True 8)
      fromCV :: CV -> Int8
    fromCV   = CV -> Int8
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Word16 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Word16)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Word16)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False 16)
      literal :: Word16 -> SBV Word16
    literal  = Kind -> Word16 -> SBV Word16
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    False 16)
      fromCV :: CV -> Word16
    fromCV   = CV -> Word16
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int16 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Int16)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Int16)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True 16)
      literal :: Int16 -> SBV Int16
    literal  = Kind -> Int16 -> SBV Int16
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    True 16)
      fromCV :: CV -> Int16
    fromCV   = CV -> Int16
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Word32 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Word32)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Word32)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False 32)
      literal :: Word32 -> SBV Word32
    literal  = Kind -> Word32 -> SBV Word32
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    False 32)
      fromCV :: CV -> Word32
    fromCV   = CV -> Word32
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int32 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Int32)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Int32)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True 32)
      literal :: Int32 -> SBV Int32
    literal  = Kind -> Int32 -> SBV Int32
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    True 32)
      fromCV :: CV -> Int32
    fromCV   = CV -> Int32
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Word64 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Word64)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Word64)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False 64)
      literal :: Word64 -> SBV Word64
    literal  = Kind -> Word64 -> SBV Word64
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    False 64)
      fromCV :: CV -> Word64
    fromCV   = CV -> Word64
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int64 where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Int64)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Int64)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True 64)
      literal :: Int64 -> SBV Int64
    literal  = Kind -> Int64 -> SBV Int64
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral  (Bool -> Int -> Kind
    KBounded Bool
    True 64)
      fromCV :: CV -> Int64
    fromCV   = CV -> Int64
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Integer where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Integer)
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Integer)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KUnbounded
      literal :: Integer -> SBV Integer
    literal  = SVal -> SBV Integer
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Integer)
    -> (Integer -> SVal) -> Integer -> SBV Integer
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KUnbounded (Either CV (Cached SV) -> SVal)
    -> (Integer -> Either CV (Cached SV)) -> Integer -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (Integer -> CV) -> Integer -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Integer -> CV
    forall a. Integral a => Kind -> a -> CV
    mkConstCV Kind
    KUnbounded
      fromCV :: CV -> Integer
    fromCV   = CV -> Integer
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal AlgReal where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV AlgReal)
    mkSymVal                   = Kind -> Maybe Quantifier -> Maybe String -> m (SBV AlgReal)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KReal
      literal :: AlgReal -> SBV AlgReal
    literal                    = SVal -> SBV AlgReal
    forall a. SVal -> SBV a
    SBV (SVal -> SBV AlgReal)
    -> (AlgReal -> SVal) -> AlgReal -> SBV AlgReal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KReal (Either CV (Cached SV) -> SVal)
    -> (AlgReal -> Either CV (Cached SV)) -> AlgReal -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (AlgReal -> CV) -> AlgReal -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KReal (CVal -> CV) -> (AlgReal -> CVal) -> AlgReal -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . AlgReal -> CVal
    CAlgReal
      fromCV :: CV -> AlgReal
    fromCV (CV _ (CAlgReal a :: AlgReal
    a)) = AlgReal
    a
      fromCV c :: CV
    c                   = String -> AlgReal
    forall a. HasCallStack => String -> a
    error (String -> AlgReal) -> String -> AlgReal
    forall a b. (a -> b) -> a -> b
    $ "SymVal.AlgReal: Unexpected non-real value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    c

      -- AlgReal needs its own definition of isConcretely
      -- to make sure we avoid using unimplementable Haskell functions
      isConcretely :: SBV AlgReal -> (AlgReal -> Bool) -> Bool
    isConcretely (SBV (SVal KReal (Left (CV KReal (CAlgReal v :: AlgReal
    v))))) p :: AlgReal -> Bool
    p
         | AlgReal -> Bool
    isExactRational AlgReal
    v = AlgReal -> Bool
    p AlgReal
    v
      isConcretely _ _       = Bool
    False

    instance SymVal Float where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Float)
    mkSymVal                 = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Float)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KFloat
      literal :: Float -> SBV Float
    literal                  = SVal -> SBV Float
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Float) -> (Float -> SVal) -> Float -> SBV Float
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KFloat (Either CV (Cached SV) -> SVal)
    -> (Float -> Either CV (Cached SV)) -> Float -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (Float -> CV) -> Float -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KFloat (CVal -> CV) -> (Float -> CVal) -> Float -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Float -> CVal
    CFloat
      fromCV :: CV -> Float
    fromCV (CV _ (CFloat a :: Float
    a)) = Float
    a
      fromCV c :: CV
    c                 = String -> Float
    forall a. HasCallStack => String -> a
    error (String -> Float) -> String -> Float
    forall a b. (a -> b) -> a -> b
    $ "SymVal.Float: Unexpected non-float value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    c

      -- For Float, we conservatively return 'False' for isConcretely. The reason is that
      -- this function is used for optimizations when only one of the argument is concrete,
      -- and in the presence of NaN's it would be incorrect to do any optimization
      isConcretely :: SBV Float -> (Float -> Bool) -> Bool
    isConcretely _ _ = Bool
    False

    instance SymVal Double where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Double)
    mkSymVal                  = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Double)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KDouble
      literal :: Double -> SBV Double
    literal                   = SVal -> SBV Double
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Double) -> (Double -> SVal) -> Double -> SBV Double
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KDouble (Either CV (Cached SV) -> SVal)
    -> (Double -> Either CV (Cached SV)) -> Double -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (Double -> CV) -> Double -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KDouble (CVal -> CV) -> (Double -> CVal) -> Double -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> CVal
    CDouble
      fromCV :: CV -> Double
    fromCV (CV _ (CDouble a :: Double
    a)) = Double
    a
      fromCV c :: CV
    c                  = String -> Double
    forall a. HasCallStack => String -> a
    error (String -> Double) -> String -> Double
    forall a b. (a -> b) -> a -> b
    $ "SymVal.Double: Unexpected non-double value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    c

      -- For Double, we conservatively return 'False' for isConcretely. The reason is that
      -- this function is used for optimizations when only one of the argument is concrete,
      -- and in the presence of NaN's it would be incorrect to do any optimization
      isConcretely :: SBV Double -> (Double -> Bool) -> Bool
    isConcretely _ _ = Bool
    False

    instance SymVal Char where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV Char)
    mkSymVal                = Kind -> Maybe Quantifier -> Maybe String -> m (SBV Char)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KChar
      literal :: Char -> SBV Char
    literal c :: Char
    c               = SVal -> SBV Char
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Char) -> (CVal -> SVal) -> CVal -> SBV Char
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KChar (Either CV (Cached SV) -> SVal)
    -> (CVal -> Either CV (Cached SV)) -> CVal -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (CVal -> CV) -> CVal -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KChar (CVal -> SBV Char) -> CVal -> SBV Char
    forall a b. (a -> b) -> a -> b
    $ Char -> CVal
    CChar Char
    c
      fromCV :: CV -> Char
    fromCV (CV _ (CChar a :: Char
    a)) = Char
    a
      fromCV c :: CV
    c                = String -> Char
    forall a. HasCallStack => String -> a
    error (String -> Char) -> String -> Char
    forall a b. (a -> b) -> a -> b
    $ "SymVal.String: Unexpected non-char value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    c

    instance SymVal a => SymVal [a] where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV [a])
    mkSymVal
        | [a] -> Bool
    forall a. Typeable a => a -> Bool
    isKString @[a] [a]
    forall a. HasCallStack => a
    undefined = Kind -> Maybe Quantifier -> Maybe String -> m (SBV [a])
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar Kind
    KString
        | Bool
    True                     = Kind -> Maybe Quantifier -> Maybe String -> m (SBV [a])
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Kind -> Kind
    KList (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)))

      literal :: [a] -> SBV [a]
    literal as :: [a]
    as
        | [a] -> Bool
    forall a. Typeable a => a -> Bool
    isKString @[a] [a]
    forall a. HasCallStack => a
    undefined = case Dynamic -> Maybe String
    forall a. Typeable a => Dynamic -> Maybe a
    fromDynamic ([a] -> Dynamic
    forall a. Typeable a => a -> Dynamic
    toDyn [a]
    as) of
                                       Just s :: String
    s  -> SVal -> SBV [a]
    forall a. SVal -> SBV a
    SBV (SVal -> SBV [a]) -> (String -> SVal) -> String -> SBV [a]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KString (Either CV (Cached SV) -> SVal)
    -> (String -> Either CV (Cached SV)) -> String -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (String -> CV) -> String -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KString (CVal -> CV) -> (String -> CVal) -> String -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> CVal
    CString (String -> SBV [a]) -> String -> SBV [a]
    forall a b. (a -> b) -> a -> b
    $ String
    s
                                       Nothing -> String -> SBV [a]
    forall a. HasCallStack => String -> a
    error "SString: Cannot construct literal string!"
        | Bool
    True                     = let k :: Kind
    k = Kind -> Kind
    KList (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a))
                                     in SVal -> SBV [a]
    forall a. SVal -> SBV a
    SBV (SVal -> SBV [a]) -> SVal -> SBV [a]
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV)) -> CV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ Kind -> CVal -> CV
    CV Kind
    k (CVal -> CV) -> CVal -> CV
    forall a b. (a -> b) -> a -> b
    $ [CVal] -> CVal
    CList ([CVal] -> CVal) -> [CVal] -> CVal
    forall a b. (a -> b) -> a -> b
    $ (a -> CVal) -> [a] -> [CVal]
    forall a b. (a -> b) -> [a] -> [b]
    map a -> CVal
    forall a. SymVal a => a -> CVal
    toCV [a]
    as

      fromCV :: CV -> [a]
    fromCV (CV _ (CString a :: String
    a)) = [a] -> Maybe [a] -> [a]
    forall a. a -> Maybe a -> a
    fromMaybe (String -> [a]
    forall a. HasCallStack => String -> a
    error "SString: Cannot extract a literal string!")
                                            (Dynamic -> Maybe [a]
    forall a. Typeable a => Dynamic -> Maybe a
    fromDynamic (String -> Dynamic
    forall a. Typeable a => a -> Dynamic
    toDyn String
    a))
      fromCV (CV _ (CList a :: [CVal]
    a))   = CV -> a
    forall a. SymVal a => CV -> a
    fromCV (CV -> a) -> (CVal -> CV) -> CVal -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)) (CVal -> a) -> [CVal] -> [a]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> [CVal]
    a
      fromCV c :: CV
    c                  = String -> [a]
    forall a. HasCallStack => String -> a
    error (String -> [a]) -> String -> [a]
    forall a b. (a -> b) -> a -> b
    $ "SymVal.fromCV: Unexpected non-list value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    c

    toCV :: SymVal a => a -> CVal
    toCV :: a -> CVal
    toCV a :: a
    a = case a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal a
    a of
               SBV (SVal _ (Left cv :: CV
    cv)) -> CV -> CVal
    cvVal CV
    cv
               _                      -> String -> CVal
    forall a. HasCallStack => String -> a
    error "SymVal.toCV: Impossible happened, couldn't produce a concrete value"

    mkCVTup :: Int -> Kind -> [CVal] -> SBV a
    mkCVTup :: Int -> Kind -> [CVal] -> SBV a
    mkCVTup i :: Int
    i k :: Kind
    k@(KTuple ks :: [Kind]
    ks) cs :: [CVal]
    cs
      | Int
    lks Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    lcs Bool -> Bool -> Bool
    && Int
    lks Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    i
      = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV)) -> CV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ Kind -> CVal -> CV
    CV Kind
    k (CVal -> CV) -> CVal -> CV
    forall a b. (a -> b) -> a -> b
    $ [CVal] -> CVal
    CTuple [CVal]
    cs
      | Bool
    True
      = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "SymVal.mkCVTup: Impossible happened. Malformed tuple received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, Kind) -> String
    forall a. Show a => a -> String
    show (Int
    i, Kind
    k)
       where lks :: Int
    lks = [Kind] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Kind]
    ks
             lcs :: Int
    lcs = [CVal] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [CVal]
    cs
    mkCVTup i :: Int
    i k :: Kind
    k _
      = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "SymVal.mkCVTup: Impossible happened. Non-tuple received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, Kind) -> String
    forall a. Show a => a -> String
    show (Int
    i, Kind
    k)

    fromCVTup :: Int -> CV -> [CV]
    fromCVTup :: Int -> CV -> [CV]
    fromCVTup i :: Int
    i inp :: CV
    inp@(CV (KTuple ks :: [Kind]
    ks) (CTuple cs :: [CVal]
    cs))
       | Int
    lks Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    lcs Bool -> Bool -> Bool
    && Int
    lks Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    i
       = (Kind -> CVal -> CV) -> [Kind] -> [CVal] -> [CV]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith Kind -> CVal -> CV
    CV [Kind]
    ks [CVal]
    cs
       | Bool
    True
       = String -> [CV]
    forall a. HasCallStack => String -> a
    error (String -> [CV]) -> String -> [CV]
    forall a b. (a -> b) -> a -> b
    $ "SymVal.fromCTup: Impossible happened. Malformed tuple received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, CV) -> String
    forall a. Show a => a -> String
    show (Int
    i, CV
    inp)
       where lks :: Int
    lks = [Kind] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Kind]
    ks
             lcs :: Int
    lcs = [CVal] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [CVal]
    cs
    fromCVTup i :: Int
    i inp :: CV
    inp = String -> [CV]
    forall a. HasCallStack => String -> a
    error (String -> [CV]) -> String -> [CV]
    forall a b. (a -> b) -> a -> b
    $ "SymVal.fromCVTup: Impossible happened. Non-tuple received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, CV) -> String
    forall a. Show a => a -> String
    show (Int
    i, CV
    inp)

    instance (SymVal a, SymVal b) => SymVal (Either a b) where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (Either a b))
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (Either a b))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (Either a b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (Either a b)
    forall k (t :: k). Proxy t
    Proxy @(Either a b)))

      literal :: Either a b -> SBV (Either a b)
    literal s :: Either a b
    s
        | Left  a :: a
    a <- Either a b
    s = Either CVal CVal -> SBV (Either a b)
    mk (Either CVal CVal -> SBV (Either a b))
    -> Either CVal CVal -> SBV (Either a b)
    forall a b. (a -> b) -> a -> b
    $ CVal -> Either CVal CVal
    forall a b. a -> Either a b
    Left  (a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    a)
        | Right b :: b
    b <- Either a b
    s = Either CVal CVal -> SBV (Either a b)
    mk (Either CVal CVal -> SBV (Either a b))
    -> Either CVal CVal -> SBV (Either a b)
    forall a b. (a -> b) -> a -> b
    $ CVal -> Either CVal CVal
    forall a b. b -> Either a b
    Right (b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    b)
        where k :: Kind
    k  = Proxy (Either a b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (Either a b)
    forall k (t :: k). Proxy t
    Proxy @(Either a b))

              mk :: Either CVal CVal -> SBV (Either a b)
    mk = SVal -> SBV (Either a b)
    forall a. SVal -> SBV a
    SBV (SVal -> SBV (Either a b))
    -> (Either CVal CVal -> SVal)
    -> Either CVal CVal
    -> SBV (Either a b)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal)
    -> (Either CVal CVal -> Either CV (Cached SV))
    -> Either CVal CVal
    -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (Either CVal CVal -> CV)
    -> Either CVal CVal
    -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    k (CVal -> CV)
    -> (Either CVal CVal -> CVal) -> Either CVal CVal -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Either CVal CVal -> CVal
    CEither

      fromCV :: CV -> Either a b
    fromCV (CV (KEither k1 :: Kind
    k1 _ ) (CEither (Left c :: CVal
    c)))  = a -> Either a b
    forall a b. a -> Either a b
    Left  (a -> Either a b) -> a -> Either a b
    forall a b. (a -> b) -> a -> b
    $ CV -> a
    forall a. SymVal a => CV -> a
    fromCV (CV -> a) -> CV -> a
    forall a b. (a -> b) -> a -> b
    $ Kind -> CVal -> CV
    CV Kind
    k1 CVal
    c
      fromCV (CV (KEither _  k2 :: Kind
    k2) (CEither (Right c :: CVal
    c))) = b -> Either a b
    forall a b. b -> Either a b
    Right (b -> Either a b) -> b -> Either a b
    forall a b. (a -> b) -> a -> b
    $ CV -> b
    forall a. SymVal a => CV -> a
    fromCV (CV -> b) -> CV -> b
    forall a b. (a -> b) -> a -> b
    $ Kind -> CVal -> CV
    CV Kind
    k2 CVal
    c
      fromCV bad :: CV
    bad                                   = String -> Either a b
    forall a. HasCallStack => String -> a
    error (String -> Either a b) -> String -> Either a b
    forall a b. (a -> b) -> a -> b
    $ "SymVal.fromCV (Either): Malformed either received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    bad

    instance SymVal a => SymVal (Maybe a) where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (Maybe a))
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (Maybe a))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (Maybe a) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (Maybe a)
    forall k (t :: k). Proxy t
    Proxy @(Maybe a)))

      literal :: Maybe a -> SBV (Maybe a)
    literal s :: Maybe a
    s
        | Maybe a
    Nothing <- Maybe a
    s = Maybe CVal -> SBV (Maybe a)
    mk Maybe CVal
    forall a. Maybe a
    Nothing
        | Just  a :: a
    a <- Maybe a
    s = Maybe CVal -> SBV (Maybe a)
    mk (Maybe CVal -> SBV (Maybe a)) -> Maybe CVal -> SBV (Maybe a)
    forall a b. (a -> b) -> a -> b
    $ CVal -> Maybe CVal
    forall a. a -> Maybe a
    Just (a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    a)
        where k :: Kind
    k = Proxy (Maybe a) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (Maybe a)
    forall k (t :: k). Proxy t
    Proxy @(Maybe a))

              mk :: Maybe CVal -> SBV (Maybe a)
    mk = SVal -> SBV (Maybe a)
    forall a. SVal -> SBV a
    SBV (SVal -> SBV (Maybe a))
    -> (Maybe CVal -> SVal) -> Maybe CVal -> SBV (Maybe a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal)
    -> (Maybe CVal -> Either CV (Cached SV)) -> Maybe CVal -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV))
    -> (Maybe CVal -> CV) -> Maybe CVal -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    k (CVal -> CV) -> (Maybe CVal -> CVal) -> Maybe CVal -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Maybe CVal -> CVal
    CMaybe

      fromCV :: CV -> Maybe a
    fromCV (CV (KMaybe _) (CMaybe Nothing))  = Maybe a
    forall a. Maybe a
    Nothing
      fromCV (CV (KMaybe k :: Kind
    k) (CMaybe (Just x :: CVal
    x))) = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ CV -> a
    forall a. SymVal a => CV -> a
    fromCV (CV -> a) -> CV -> a
    forall a b. (a -> b) -> a -> b
    $ Kind -> CVal -> CV
    CV Kind
    k CVal
    x
      fromCV bad :: CV
    bad                               = String -> Maybe a
    forall a. HasCallStack => String -> a
    error (String -> Maybe a) -> String -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ "SymVal.fromCV (Maybe): Malformed sum received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    bad

    instance (Ord a, SymVal a) => SymVal (RCSet a) where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (RCSet a))
    mkSymVal = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (RCSet a))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (RCSet a) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (RCSet a)
    forall k (t :: k). Proxy t
    Proxy @(RCSet a)))

      literal :: RCSet a -> SBV (RCSet a)
    literal eur :: RCSet a
    eur = SVal -> SBV (RCSet a)
    forall a. SVal -> SBV a
    SBV (SVal -> SBV (RCSet a)) -> SVal -> SBV (RCSet a)
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left (CV -> Either CV (Cached SV)) -> CV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ Kind -> CVal -> CV
    CV Kind
    k (CVal -> CV) -> CVal -> CV
    forall a b. (a -> b) -> a -> b
    $ RCSet CVal -> CVal
    CSet (RCSet CVal -> CVal) -> RCSet CVal -> CVal
    forall a b. (a -> b) -> a -> b
    $ Set CVal -> RCSet CVal
    dir (Set CVal -> RCSet CVal) -> Set CVal -> RCSet CVal
    forall a b. (a -> b) -> a -> b
    $ (a -> CVal) -> Set a -> Set CVal
    forall b a. Ord b => (a -> b) -> Set a -> Set b
    Set.map a -> CVal
    forall a. SymVal a => a -> CVal
    toCV Set a
    s
        where (dir :: Set CVal -> RCSet CVal
    dir, s :: Set a
    s) = case RCSet a
    eur of
                          RegularSet x :: Set a
    x    -> (Set CVal -> RCSet CVal
    forall a. Set a -> RCSet a
    RegularSet,    Set a
    x)
                          ComplementSet x :: Set a
    x -> (Set CVal -> RCSet CVal
    forall a. Set a -> RCSet a
    ComplementSet, Set a
    x)
              k :: Kind
    k        = Proxy (RCSet a) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (RCSet a)
    forall k (t :: k). Proxy t
    Proxy @(RCSet a))

      fromCV :: CV -> RCSet a
    fromCV (CV (KSet a :: Kind
    a) (CSet (RegularSet    s :: Set CVal
    s))) = Set a -> RCSet a
    forall a. Set a -> RCSet a
    RegularSet    (Set a -> RCSet a) -> Set a -> RCSet a
    forall a b. (a -> b) -> a -> b
    $ (CVal -> a) -> Set CVal -> Set a
    forall b a. Ord b => (a -> b) -> Set a -> Set b
    Set.map (CV -> a
    forall a. SymVal a => CV -> a
    fromCV (CV -> a) -> (CVal -> CV) -> CVal -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    a) Set CVal
    s
      fromCV (CV (KSet a :: Kind
    a) (CSet (ComplementSet s :: Set CVal
    s))) = Set a -> RCSet a
    forall a. Set a -> RCSet a
    ComplementSet (Set a -> RCSet a) -> Set a -> RCSet a
    forall a b. (a -> b) -> a -> b
    $ (CVal -> a) -> Set CVal -> Set a
    forall b a. Ord b => (a -> b) -> Set a -> Set b
    Set.map (CV -> a
    forall a. SymVal a => CV -> a
    fromCV (CV -> a) -> (CVal -> CV) -> CVal -> a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    a) Set CVal
    s
      fromCV bad :: CV
    bad                                    = String -> RCSet a
    forall a. HasCallStack => String -> a
    error (String -> RCSet a) -> String -> RCSet a
    forall a b. (a -> b) -> a -> b
    $ "SymVal.fromCV (Set): Malformed set received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ CV -> String
    forall a. Show a => a -> String
    show CV
    bad

    -- | SymVal for 0-tuple (i.e., unit)
    instance SymVal () where
      mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV ())
    mkSymVal   = Kind -> Maybe Quantifier -> Maybe String -> m (SBV ())
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar ([Kind] -> Kind
    KTuple [])
      literal :: () -> SBV ()
    literal () = Int -> Kind -> [CVal] -> SBV ()
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 0   (Proxy () -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy ()
    forall k (t :: k). Proxy t
    Proxy @())) []
      fromCV :: CV -> ()
    fromCV cv :: CV
    cv  = Int -> CV -> [CV]
    fromCVTup 0 CV
    cv [CV] -> () -> ()
    forall a b. a -> b -> b
    `seq` ()

    -- | SymVal for 2-tuples
    instance (SymVal a, SymVal b) => SymVal (a, b) where
       mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (a, b))
    mkSymVal         = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (a, b))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b)
    forall k (t :: k). Proxy t
    Proxy @(a, b)))
       literal :: (a, b) -> SBV (a, b)
    literal (v1 :: a
    v1, v2 :: b
    v2) = Int -> Kind -> [CVal] -> SBV (a, b)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 2   (Proxy (a, b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b)
    forall k (t :: k). Proxy t
    Proxy @(a, b))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2]
       fromCV :: CV -> (a, b)
    fromCV  cv :: CV
    cv       = let ~[v1 :: CV
    v1, v2 :: CV
    v2] = Int -> CV -> [CV]
    fromCVTup 2 CV
    cv
                          in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2)

    -- | SymVal for 3-tuples
    instance (SymVal a, SymVal b, SymVal c) => SymVal (a, b, c) where
       mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (a, b, c))
    mkSymVal             = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (a, b, c))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b, c) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c)))
       literal :: (a, b, c) -> SBV (a, b, c)
    literal (v1 :: a
    v1, v2 :: b
    v2, v3 :: c
    v3) = Int -> Kind -> [CVal] -> SBV (a, b, c)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 3   (Proxy (a, b, c) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2, c -> CVal
    forall a. SymVal a => a -> CVal
    toCV c
    v3]
       fromCV :: CV -> (a, b, c)
    fromCV  cv :: CV
    cv           = let ~[v1 :: CV
    v1, v2 :: CV
    v2, v3 :: CV
    v3] = Int -> CV -> [CV]
    fromCVTup 3 CV
    cv
                              in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2, CV -> c
    forall a. SymVal a => CV -> a
    fromCV CV
    v3)

    -- | SymVal for 4-tuples
    instance (SymVal a, SymVal b, SymVal c, SymVal d) => SymVal (a, b, c, d) where
       mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d))
    mkSymVal                 = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d)))
       literal :: (a, b, c, d) -> SBV (a, b, c, d)
    literal (v1 :: a
    v1, v2 :: b
    v2, v3 :: c
    v3, v4 :: d
    v4) = Int -> Kind -> [CVal] -> SBV (a, b, c, d)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 4   (Proxy (a, b, c, d) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2, c -> CVal
    forall a. SymVal a => a -> CVal
    toCV c
    v3, d -> CVal
    forall a. SymVal a => a -> CVal
    toCV d
    v4]
       fromCV :: CV -> (a, b, c, d)
    fromCV  cv :: CV
    cv               = let ~[v1 :: CV
    v1, v2 :: CV
    v2, v3 :: CV
    v3, v4 :: CV
    v4] = Int -> CV -> [CV]
    fromCVTup 4 CV
    cv
                                  in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2, CV -> c
    forall a. SymVal a => CV -> a
    fromCV CV
    v3, CV -> d
    forall a. SymVal a => CV -> a
    fromCV CV
    v4)

    -- | SymVal for 5-tuples
    instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e) => SymVal (a, b, c, d, e) where
       mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d, e))
    mkSymVal                     = Kind -> Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d, e))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e)))
       literal :: (a, b, c, d, e) -> SBV (a, b, c, d, e)
    literal (v1 :: a
    v1, v2 :: b
    v2, v3 :: c
    v3, v4 :: d
    v4, v5 :: e
    v5) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 5   (Proxy (a, b, c, d, e) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2, c -> CVal
    forall a. SymVal a => a -> CVal
    toCV c
    v3, d -> CVal
    forall a. SymVal a => a -> CVal
    toCV d
    v4, e -> CVal
    forall a. SymVal a => a -> CVal
    toCV e
    v5]
       fromCV :: CV -> (a, b, c, d, e)
    fromCV  cv :: CV
    cv                   = let ~[v1 :: CV
    v1, v2 :: CV
    v2, v3 :: CV
    v3, v4 :: CV
    v4, v5 :: CV
    v5] = Int -> CV -> [CV]
    fromCVTup 5 CV
    cv
                                      in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2, CV -> c
    forall a. SymVal a => CV -> a
    fromCV CV
    v3, CV -> d
    forall a. SymVal a => CV -> a
    fromCV CV
    v4, CV -> e
    forall a. SymVal a => CV -> a
    fromCV CV
    v5)

    -- | SymVal for 6-tuples
    instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f) => SymVal (a, b, c, d, e, f) where
       mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d, e, f))
    mkSymVal                         = Kind
    -> Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d, e, f))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e, f) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e, f)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e, f)))
       literal :: (a, b, c, d, e, f) -> SBV (a, b, c, d, e, f)
    literal (v1 :: a
    v1, v2 :: b
    v2, v3 :: c
    v3, v4 :: d
    v4, v5 :: e
    v5, v6 :: f
    v6) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e, f)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 6   (Proxy (a, b, c, d, e, f) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e, f)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e, f))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2, c -> CVal
    forall a. SymVal a => a -> CVal
    toCV c
    v3, d -> CVal
    forall a. SymVal a => a -> CVal
    toCV d
    v4, e -> CVal
    forall a. SymVal a => a -> CVal
    toCV e
    v5, f -> CVal
    forall a. SymVal a => a -> CVal
    toCV f
    v6]
       fromCV :: CV -> (a, b, c, d, e, f)
    fromCV  cv :: CV
    cv                       = let ~[v1 :: CV
    v1, v2 :: CV
    v2, v3 :: CV
    v3, v4 :: CV
    v4, v5 :: CV
    v5, v6 :: CV
    v6] = Int -> CV -> [CV]
    fromCVTup 6 CV
    cv
                                          in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2, CV -> c
    forall a. SymVal a => CV -> a
    fromCV CV
    v3, CV -> d
    forall a. SymVal a => CV -> a
    fromCV CV
    v4, CV -> e
    forall a. SymVal a => CV -> a
    fromCV CV
    v5, CV -> f
    forall a. SymVal a => CV -> a
    fromCV CV
    v6)

    -- | SymVal for 7-tuples
    instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g) => SymVal (a, b, c, d, e, f, g) where
       mkSymVal :: Maybe Quantifier -> Maybe String -> m (SBV (a, b, c, d, e, f, g))
    mkSymVal                             = Kind
    -> Maybe Quantifier
    -> Maybe String
    -> m (SBV (a, b, c, d, e, f, g))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e, f, g) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e, f, g)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e, f, g)))
       literal :: (a, b, c, d, e, f, g) -> SBV (a, b, c, d, e, f, g)
    literal (v1 :: a
    v1, v2 :: b
    v2, v3 :: c
    v3, v4 :: d
    v4, v5 :: e
    v5, v6 :: f
    v6, v7 :: g
    v7) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e, f, g)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 7   (Proxy (a, b, c, d, e, f, g) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e, f, g)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e, f, g))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2, c -> CVal
    forall a. SymVal a => a -> CVal
    toCV c
    v3, d -> CVal
    forall a. SymVal a => a -> CVal
    toCV d
    v4, e -> CVal
    forall a. SymVal a => a -> CVal
    toCV e
    v5, f -> CVal
    forall a. SymVal a => a -> CVal
    toCV f
    v6, g -> CVal
    forall a. SymVal a => a -> CVal
    toCV g
    v7]
       fromCV :: CV -> (a, b, c, d, e, f, g)
    fromCV  cv :: CV
    cv                           = let ~[v1 :: CV
    v1, v2 :: CV
    v2, v3 :: CV
    v3, v4 :: CV
    v4, v5 :: CV
    v5, v6 :: CV
    v6, v7 :: CV
    v7] = Int -> CV -> [CV]
    fromCVTup 7 CV
    cv
                                              in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2, CV -> c
    forall a. SymVal a => CV -> a
    fromCV CV
    v3, CV -> d
    forall a. SymVal a => CV -> a
    fromCV CV
    v4, CV -> e
    forall a. SymVal a => CV -> a
    fromCV CV
    v5, CV -> f
    forall a. SymVal a => CV -> a
    fromCV CV
    v6, CV -> g
    forall a. SymVal a => CV -> a
    fromCV CV
    v7)

    -- | SymVal for 8-tuples
    instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, SymVal h) => SymVal (a, b, c, d, e, f, g, h) where
       mkSymVal :: Maybe Quantifier
    -> Maybe String -> m (SBV (a, b, c, d, e, f, g, h))
    mkSymVal                                 = Kind
    -> Maybe Quantifier
    -> Maybe String
    -> m (SBV (a, b, c, d, e, f, g, h))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> Maybe Quantifier -> Maybe String -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e, f, g, h) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e, f, g, h)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e, f, g, h)))
       literal :: (a, b, c, d, e, f, g, h) -> SBV (a, b, c, d, e, f, g, h)
    literal (v1 :: a
    v1, v2 :: b
    v2, v3 :: c
    v3, v4 :: d
    v4, v5 :: e
    v5, v6 :: f
    v6, v7 :: g
    v7, v8 :: h
    v8) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e, f, g, h)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup 8   (Proxy (a, b, c, d, e, f, g, h) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy (a, b, c, d, e, f, g, h)
    forall k (t :: k). Proxy t
    Proxy @(a, b, c, d, e, f, g, h))) [a -> CVal
    forall a. SymVal a => a -> CVal
    toCV a
    v1, b -> CVal
    forall a. SymVal a => a -> CVal
    toCV b
    v2, c -> CVal
    forall a. SymVal a => a -> CVal
    toCV c
    v3, d -> CVal
    forall a. SymVal a => a -> CVal
    toCV d
    v4, e -> CVal
    forall a. SymVal a => a -> CVal
    toCV e
    v5, f -> CVal
    forall a. SymVal a => a -> CVal
    toCV f
    v6, g -> CVal
    forall a. SymVal a => a -> CVal
    toCV g
    v7, h -> CVal
    forall a. SymVal a => a -> CVal
    toCV h
    v8]
       fromCV :: CV -> (a, b, c, d, e, f, g, h)
    fromCV  cv :: CV
    cv                               = let ~[v1 :: CV
    v1, v2 :: CV
    v2, v3 :: CV
    v3, v4 :: CV
    v4, v5 :: CV
    v5, v6 :: CV
    v6, v7 :: CV
    v7, v8 :: CV
    v8] = Int -> CV -> [CV]
    fromCVTup 8 CV
    cv
                                                  in (CV -> a
    forall a. SymVal a => CV -> a
    fromCV CV
    v1, CV -> b
    forall a. SymVal a => CV -> a
    fromCV CV
    v2, CV -> c
    forall a. SymVal a => CV -> a
    fromCV CV
    v3, CV -> d
    forall a. SymVal a => CV -> a
    fromCV CV
    v4, CV -> e
    forall a. SymVal a => CV -> a
    fromCV CV
    v5, CV -> f
    forall a. SymVal a => CV -> a
    fromCV CV
    v6, CV -> g
    forall a. SymVal a => CV -> a
    fromCV CV
    v7, CV -> h
    forall a. SymVal a => CV -> a
    fromCV CV
    v8)

    instance IsString SString where
      fromString :: String -> SString
    fromString = String -> SString
    forall a. SymVal a => a -> SBV a
    literal

    ------------------------------------------------------------------------------------
    -- * Smart constructors for creating symbolic values. These are not strictly
    -- necessary, as they are mere aliases for 'symbolic' and 'symbolics', but
    -- they nonetheless make programming easier.
    ------------------------------------------------------------------------------------

    -- | Generalization of 'Data.SBV.sBool'
    sBool :: MonadSymbolic m => String -> m SBool
    sBool :: String -> m (SBV Bool)
    sBool = String -> m (SBV Bool)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sBool_'
    sBool_ :: MonadSymbolic m => m SBool
    sBool_ :: m (SBV Bool)
    sBool_ = m (SBV Bool)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sBools'
    sBools :: MonadSymbolic m => [String] -> m [SBool]
    sBools :: [String] -> m [SBV Bool]
    sBools = [String] -> m [SBV Bool]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sWord8'
    sWord8 :: MonadSymbolic m => String -> m SWord8
    sWord8 :: String -> m (SBV Word8)
    sWord8 = String -> m (SBV Word8)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sWord8_'
    sWord8_ :: MonadSymbolic m => m SWord8
    sWord8_ :: m (SBV Word8)
    sWord8_ = m (SBV Word8)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sWord8s'
    sWord8s :: MonadSymbolic m => [String] -> m [SWord8]
    sWord8s :: [String] -> m [SBV Word8]
    sWord8s = [String] -> m [SBV Word8]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sWord16'
    sWord16 :: MonadSymbolic m => String -> m SWord16
    sWord16 :: String -> m (SBV Word16)
    sWord16 = String -> m (SBV Word16)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sWord16_'
    sWord16_ :: MonadSymbolic m => m SWord16
    sWord16_ :: m (SBV Word16)
    sWord16_ = m (SBV Word16)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sWord16s'
    sWord16s :: MonadSymbolic m => [String] -> m [SWord16]
    sWord16s :: [String] -> m [SBV Word16]
    sWord16s = [String] -> m [SBV Word16]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sWord32'
    sWord32 :: MonadSymbolic m => String -> m SWord32
    sWord32 :: String -> m (SBV Word32)
    sWord32 = String -> m (SBV Word32)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sWord32_'
    sWord32_ :: MonadSymbolic m => m SWord32
    sWord32_ :: m (SBV Word32)
    sWord32_ = m (SBV Word32)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sWord32s'
    sWord32s :: MonadSymbolic m => [String] -> m [SWord32]
    sWord32s :: [String] -> m [SBV Word32]
    sWord32s = [String] -> m [SBV Word32]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sWord64'
    sWord64 :: MonadSymbolic m => String -> m SWord64
    sWord64 :: String -> m (SBV Word64)
    sWord64 = String -> m (SBV Word64)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sWord64_'
    sWord64_ :: MonadSymbolic m => m SWord64
    sWord64_ :: m (SBV Word64)
    sWord64_ = m (SBV Word64)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sWord64s'
    sWord64s :: MonadSymbolic m => [String] -> m [SWord64]
    sWord64s :: [String] -> m [SBV Word64]
    sWord64s = [String] -> m [SBV Word64]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sInt8'
    sInt8 :: MonadSymbolic m => String -> m SInt8
    sInt8 :: String -> m (SBV Int8)
    sInt8 = String -> m (SBV Int8)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sInt8_'
    sInt8_ :: MonadSymbolic m => m SInt8
    sInt8_ :: m (SBV Int8)
    sInt8_ = m (SBV Int8)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sInt8s'
    sInt8s :: MonadSymbolic m => [String] -> m [SInt8]
    sInt8s :: [String] -> m [SBV Int8]
    sInt8s = [String] -> m [SBV Int8]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sInt16'
    sInt16 :: MonadSymbolic m => String -> m SInt16
    sInt16 :: String -> m (SBV Int16)
    sInt16 = String -> m (SBV Int16)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sInt16_'
    sInt16_ :: MonadSymbolic m => m SInt16
    sInt16_ :: m (SBV Int16)
    sInt16_ = m (SBV Int16)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sInt16s'
    sInt16s :: MonadSymbolic m => [String] -> m [SInt16]
    sInt16s :: [String] -> m [SBV Int16]
    sInt16s = [String] -> m [SBV Int16]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sInt32'
    sInt32 :: MonadSymbolic m => String -> m SInt32
    sInt32 :: String -> m (SBV Int32)
    sInt32 = String -> m (SBV Int32)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sInt32_'
    sInt32_ :: MonadSymbolic m => m SInt32
    sInt32_ :: m (SBV Int32)
    sInt32_ = m (SBV Int32)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sInt32s'
    sInt32s :: MonadSymbolic m => [String] -> m [SInt32]
    sInt32s :: [String] -> m [SBV Int32]
    sInt32s = [String] -> m [SBV Int32]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sInt64'
    sInt64 :: MonadSymbolic m => String -> m SInt64
    sInt64 :: String -> m (SBV Int64)
    sInt64 = String -> m (SBV Int64)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sInt64_'
    sInt64_ :: MonadSymbolic m => m SInt64
    sInt64_ :: m (SBV Int64)
    sInt64_ = m (SBV Int64)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sInt64s'
    sInt64s :: MonadSymbolic m => [String] -> m [SInt64]
    sInt64s :: [String] -> m [SBV Int64]
    sInt64s = [String] -> m [SBV Int64]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sInteger'
    sInteger:: MonadSymbolic m => String -> m SInteger
    sInteger :: String -> m (SBV Integer)
    sInteger = String -> m (SBV Integer)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sInteger_'
    sInteger_:: MonadSymbolic m => m SInteger
    sInteger_ :: m (SBV Integer)
    sInteger_ = m (SBV Integer)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sIntegers'
    sIntegers :: MonadSymbolic m => [String] -> m [SInteger]
    sIntegers :: [String] -> m [SBV Integer]
    sIntegers = [String] -> m [SBV Integer]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sReal'
    sReal:: MonadSymbolic m => String -> m SReal
    sReal :: String -> m (SBV AlgReal)
    sReal = String -> m (SBV AlgReal)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sReal_'
    sReal_:: MonadSymbolic m => m SReal
    sReal_ :: m (SBV AlgReal)
    sReal_ = m (SBV AlgReal)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sReals'
    sReals :: MonadSymbolic m => [String] -> m [SReal]
    sReals :: [String] -> m [SBV AlgReal]
    sReals = [String] -> m [SBV AlgReal]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sFloat'
    sFloat :: MonadSymbolic m => String -> m SFloat
    sFloat :: String -> m (SBV Float)
    sFloat = String -> m (SBV Float)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sFloat_'
    sFloat_ :: MonadSymbolic m => m SFloat
    sFloat_ :: m (SBV Float)
    sFloat_ = m (SBV Float)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sFloats'
    sFloats :: MonadSymbolic m => [String] -> m [SFloat]
    sFloats :: [String] -> m [SBV Float]
    sFloats = [String] -> m [SBV Float]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sDouble'
    sDouble :: MonadSymbolic m => String -> m SDouble
    sDouble :: String -> m (SBV Double)
    sDouble = String -> m (SBV Double)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sDouble_'
    sDouble_ :: MonadSymbolic m => m SDouble
    sDouble_ :: m (SBV Double)
    sDouble_ = m (SBV Double)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sDoubles'
    sDoubles :: MonadSymbolic m => [String] -> m [SDouble]
    sDoubles :: [String] -> m [SBV Double]
    sDoubles = [String] -> m [SBV Double]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sChar'
    sChar :: MonadSymbolic m => String -> m SChar
    sChar :: String -> m (SBV Char)
    sChar = String -> m (SBV Char)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sChar_'
    sChar_ :: MonadSymbolic m => m SChar
    sChar_ :: m (SBV Char)
    sChar_ = m (SBV Char)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sChars'
    sChars :: MonadSymbolic m => [String] -> m [SChar]
    sChars :: [String] -> m [SBV Char]
    sChars = [String] -> m [SBV Char]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sString'
    sString :: MonadSymbolic m => String -> m SString
    sString :: String -> m SString
    sString = String -> m SString
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sString_'
    sString_ :: MonadSymbolic m => m SString
    sString_ :: m SString
    sString_ = m SString
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sStrings'
    sStrings :: MonadSymbolic m => [String] -> m [SString]
    sStrings :: [String] -> m [SString]
    sStrings = [String] -> m [SString]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sList'
    sList :: (SymVal a, MonadSymbolic m) => String -> m (SList a)
    sList :: String -> m (SList a)
    sList = String -> m (SList a)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sList_'
    sList_ :: (SymVal a, MonadSymbolic m) => m (SList a)
    sList_ :: m (SList a)
    sList_ = m (SList a)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sLists'
    sLists :: (SymVal a, MonadSymbolic m) => [String] -> m [SList a]
    sLists :: [String] -> m [SList a]
    sLists = [String] -> m [SList a]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Identify tuple like things. Note that there are no methods, just instances to control type inference
    class SymTuple a
    instance SymTuple ()
    instance SymTuple (a, b)
    instance SymTuple (a, b, c)
    instance SymTuple (a, b, c, d)
    instance SymTuple (a, b, c, d, e)
    instance SymTuple (a, b, c, d, e, f)
    instance SymTuple (a, b, c, d, e, f, g)
    instance SymTuple (a, b, c, d, e, f, g, h)

    -- | Generalization of 'Data.SBV.sTuple'
    sTuple :: (SymTuple tup, SymVal tup, MonadSymbolic m) => String -> m (SBV tup)
    sTuple :: String -> m (SBV tup)
    sTuple = String -> m (SBV tup)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sTuple_'
    sTuple_ :: (SymTuple tup, SymVal tup, MonadSymbolic m) => m (SBV tup)
    sTuple_ :: m (SBV tup)
    sTuple_ = m (SBV tup)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sTuples'
    sTuples :: (SymTuple tup, SymVal tup, MonadSymbolic m) => [String] -> m [SBV tup]
    sTuples :: [String] -> m [SBV tup]
    sTuples = [String] -> m [SBV tup]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sEither'
    sEither :: (SymVal a, SymVal b, MonadSymbolic m) => String -> m (SEither a b)
    sEither :: String -> m (SEither a b)
    sEither = String -> m (SEither a b)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sEither_'
    sEither_ :: (SymVal a, SymVal b, MonadSymbolic m) => m (SEither a b)
    sEither_ :: m (SEither a b)
    sEither_ = m (SEither a b)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sEithers'
    sEithers :: (SymVal a, SymVal b, MonadSymbolic m) => [String] -> m [SEither a b]
    sEithers :: [String] -> m [SEither a b]
    sEithers = [String] -> m [SEither a b]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sMaybe'
    sMaybe :: (SymVal a, MonadSymbolic m) => String -> m (SMaybe a)
    sMaybe :: String -> m (SMaybe a)
    sMaybe = String -> m (SMaybe a)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sMaybe_'
    sMaybe_ :: (SymVal a, MonadSymbolic m) => m (SMaybe a)
    sMaybe_ :: m (SMaybe a)
    sMaybe_ = m (SMaybe a)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sMaybes'
    sMaybes :: (SymVal a, MonadSymbolic m) => [String] -> m [SMaybe a]
    sMaybes :: [String] -> m [SMaybe a]
    sMaybes = [String] -> m [SMaybe a]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.sSet'
    sSet :: (Ord a, SymVal a, MonadSymbolic m) => String -> m (SSet a)
    sSet :: String -> m (SSet a)
    sSet = String -> m (SSet a)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    String -> m (SBV a)
    symbolic

    -- | Generalization of 'Data.SBV.sMaybe_'
    sSet_ :: (Ord a, SymVal a, MonadSymbolic m) => m (SSet a)
    sSet_ :: m (SSet a)
    sSet_ = m (SSet a)
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    free_

    -- | Generalization of 'Data.SBV.sMaybes'
    sSets :: (Ord a, SymVal a, MonadSymbolic m) => [String] -> m [SSet a]
    sSets :: [String] -> m [SSet a]
    sSets = [String] -> m [SSet a]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [String] -> m [SBV a]
    symbolics

    -- | Generalization of 'Data.SBV.solve'
    solve :: MonadSymbolic m => [SBool] -> m SBool
    solve :: [SBV Bool] -> m (SBV Bool)
    solve = SBV Bool -> m (SBV Bool)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SBV Bool -> m (SBV Bool))
    -> ([SBV Bool] -> SBV Bool) -> [SBV Bool] -> m (SBV Bool)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [SBV Bool] -> SBV Bool
    sAnd

    -- | Convert an SReal to an SInteger. That is, it computes the
    -- largest integer @n@ that satisfies @sIntegerToSReal n <= r@
    -- essentially giving us the @floor@.
    --
    -- For instance, @1.3@ will be @1@, but @-1.3@ will be @-2@.
    sRealToSInteger :: SReal -> SInteger
    sRealToSInteger :: SBV AlgReal -> SBV Integer
    sRealToSInteger x :: SBV AlgReal
    x
      | Just i :: AlgReal
    i <- SBV AlgReal -> Maybe AlgReal
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV AlgReal
    x, AlgReal -> Bool
    isExactRational AlgReal
    i
      = Integer -> SBV Integer
    forall a. SymVal a => a -> SBV a
    literal (Integer -> SBV Integer) -> Integer -> SBV Integer
    forall a b. (a -> b) -> a -> b
    $ Rational -> Integer
    forall a b. (RealFrac a, Integral b) => a -> b
    floor (AlgReal -> Rational
    forall a. Real a => a -> Rational
    toRational AlgReal
    i)
      | Bool
    True
      = SVal -> SBV Integer
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KUnbounded (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    y)))
      where y :: State -> IO SV
    y st :: State
    st = do SV
    xsv <- State -> SBV AlgReal -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV AlgReal
    x
                      State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    KUnbounded (Op -> [SV] -> SBVExpr
    SBVApp (Kind -> Kind -> Op
    KindCast Kind
    KReal Kind
    KUnbounded) [SV
    xsv])

    -- | label: Label the result of an expression. This is essentially a no-op, but useful as it generates a comment in the generated C/SMT-Lib code.
    -- Note that if the argument is a constant, then the label is dropped completely, per the usual constant folding strategy. Compare this to 'observe'
    -- which is good for printing counter-examples.
    label :: SymVal a => String -> SBV a -> SBV a
    label :: String -> SBV a -> SBV a
    label m :: String
    m x :: SBV a
    x
       | Just _ <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    x = SBV a
    x
       | Bool
    True                  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r
      where k :: Kind
    k    = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x
            r :: State -> IO SV
    r st :: State
    st = do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                      State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    k (Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Label String
    m) [SV
    xsv])

    -- | Check if an observable name is good.
    checkObservableName :: String -> Maybe String
    checkObservableName :: String -> Maybe String
    checkObservableName lbl :: String
    lbl
      | String -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null String
    lbl
      = String -> Maybe String
    forall a. a -> Maybe a
    Just "SBV.observe: Bad empty name!"
      | (Char -> Char) -> String -> String
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toLower String
    lbl String -> [String] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [String]
    smtLibReservedNames
      = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ "SBV.observe: The name chosen is reserved, please change it!: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> String
    forall a. Show a => a -> String
    show String
    lbl
      | "s" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` String
    lbl Bool -> Bool -> Bool
    && (Char -> Bool) -> String -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Char -> Bool
    isDigit (Int -> String -> String
    forall a. Int -> [a] -> [a]
    drop 1 String
    lbl)
      = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ "SBV.observe: Names of the form sXXX are internal to SBV, please use a different name: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> String
    forall a. Show a => a -> String
    show String
    lbl
      | Bool
    True
      = Maybe String
    forall a. Maybe a
    Nothing

    -- | Observe the value of an expression, if the given condition holds.  Such values are useful in model construction, as they are printed part of a satisfying model, or a
    -- counter-example. The same works for quick-check as well. Useful when we want to see intermediate values, or expected/obtained
    -- pairs in a particular run. Note that an observed expression is always symbolic, i.e., it won't be constant folded. Compare this to 'label'
    -- which is used for putting a label in the generated SMTLib-C code.
    observeIf :: SymVal a => (a -> Bool) -> String -> SBV a -> SBV a
    observeIf :: (a -> Bool) -> String -> SBV a -> SBV a
    observeIf cond :: a -> Bool
    cond m :: String
    m x :: SBV a
    x
      | Just bad :: String
    bad <- String -> Maybe String
    checkObservableName String
    m
      = String -> SBV a
    forall a. HasCallStack => String -> a
    error String
    bad
      | Bool
    True
      = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r
      where k :: Kind
    k = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x
            r :: State -> IO SV
    r st :: State
    st = do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                      State -> String -> (CV -> Bool) -> SV -> IO ()
    recordObservable State
    st String
    m (a -> Bool
    cond (a -> Bool) -> (CV -> a) -> CV -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CV -> a
    forall a. SymVal a => CV -> a
    fromCV) SV
    xsv
                      SV -> IO SV
    forall (m :: * -> *) a. Monad m => a -> m a
    return SV
    xsv

    -- | Observe the value of an expression, uncoditionally. See 'observeIf' for a generalized version.
    observe :: SymVal a => String -> SBV a -> SBV a
    observe :: String -> SBV a -> SBV a
    observe = (a -> Bool) -> String -> SBV a -> SBV a
    forall a. SymVal a => (a -> Bool) -> String -> SBV a -> SBV a
    observeIf (Bool -> a -> Bool
    forall a b. a -> b -> a
    const Bool
    True)

    -- | A variant of observe that you can use at the top-level. This is useful with quick-check, for instance.
    sObserve :: SymVal a => String -> SBV a -> Symbolic ()
    sObserve :: String -> SBV a -> Symbolic ()
    sObserve m :: String
    m x :: SBV a
    x
      | Just bad :: String
    bad <- String -> Maybe String
    checkObservableName String
    m
      = String -> Symbolic ()
    forall a. HasCallStack => String -> a
    error String
    bad
      | Bool
    True
      = do State
    st <- SymbolicT IO State
    forall (m :: * -> *). MonadSymbolic m => m State
    symbolicEnv
           IO () -> Symbolic ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> Symbolic ()) -> IO () -> Symbolic ()
    forall a b. (a -> b) -> a -> b
    $ do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                       State -> String -> (CV -> Bool) -> SV -> IO ()
    recordObservable State
    st String
    m (Bool -> CV -> Bool
    forall a b. a -> b -> a
    const Bool
    True) SV
    xsv

    -- | Symbolic Equality. Note that we can't use Haskell's 'Eq' class since Haskell insists on returning Bool
    -- Comparing symbolic values will necessarily return a symbolic value.
    infix 4 .==, ./=, .===, ./==
    class EqSymbolic a where
      -- | Symbolic equality.
      (.==) :: a -> a -> SBool
      -- | Symbolic inequality.
      (./=) :: a -> a -> SBool
      -- | Strong equality. On floats ('SFloat'/'SDouble'), strong equality is object equality; that
      -- is @NaN == NaN@ holds, but @+0 == -0@ doesn't. On other types, (.===) is simply (.==).
      -- Note that (.==) is the /right/ notion of equality for floats per IEEE754 specs, since by
      -- definition @+0 == -0@ and @NaN@ equals no other value including itself. But occasionally
      -- we want to be stronger and state @NaN@ equals @NaN@ and @+0@ and @-0@ are different from
      -- each other. In a context where your type is concrete, simply use `Data.SBV.fpIsEqualObject`. But in
      -- a polymorphic context, use the strong equality instead.
      --
      -- NB. If you do not care about or work with floats, simply use (.==) and (./=).
      (.===) :: a -> a -> SBool
      -- | Negation of strong equality. Equaivalent to negation of (.===) on all types.
      (./==) :: a -> a -> SBool

      -- | Returns (symbolic) 'sTrue' if all the elements of the given list are different.
      distinct :: [a] -> SBool

      -- | Returns (symbolic) `sTrue` if all the elements of the given list are different. The second
      -- list contains exceptions, i.e., if an element belongs to that set, it will be considered
      -- distinct regardless of repetition.
      --
      -- >>> prove $ \a -> distinctExcept [a, a] [0::SInteger] .<=> a .== 0
      -- Q.E.D.
      -- >>> prove $ \a b -> distinctExcept [a, b] [0::SWord8] .<=> (a .== b .=> a .== 0)
      -- Q.E.D.
      -- >>> prove $ \a b c d -> distinctExcept [a, b, c, d] [] .== distinct [a, b, c, (d::SInteger)]
      -- Q.E.D.
      distinctExcept :: [a] -> [a] -> SBool

      -- | Returns (symbolic) 'sTrue' if all the elements of the given list are the same.
      allEqual :: [a] -> SBool

      -- | Symbolic membership test.
      sElem    :: a -> [a] -> SBool

      -- | Symbolic negated membership test.
      sNotElem :: a -> [a] -> SBool

      {-# MINIMAL (.==) #-}

      x :: a
    x ./=  y :: a
    y = SBV Bool -> SBV Bool
    sNot (a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .==  a
    y)
      x :: a
    x .=== y :: a
    y = a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    y
      x :: a
    x ./== y :: a
    y = SBV Bool -> SBV Bool
    sNot (a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .=== a
    y)

      allEqual []     = SBV Bool
    sTrue
      allEqual (x :: a
    x:xs :: [a]
    xs) = (a -> SBV Bool) -> [a] -> SBV Bool
    forall a. (a -> SBV Bool) -> [a] -> SBV Bool
    sAll (a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .==) [a]
    xs

      -- Default implementation of distinct. Note that we override
      -- this method for the base types to generate better code.
      distinct []     = SBV Bool
    sTrue
      distinct (x :: a
    x:xs :: [a]
    xs) = (a -> SBV Bool) -> [a] -> SBV Bool
    forall a. (a -> SBV Bool) -> [a] -> SBV Bool
    sAll (a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    ./=) [a]
    xs SBV Bool -> SBV Bool -> SBV Bool
    .&& [a] -> SBV Bool
    forall a. EqSymbolic a => [a] -> SBV Bool
    distinct [a]
    xs

      -- Default implementation of distinctExcept. Note that we override
      -- this method for the base types to generate better code.
      distinctExcept es :: [a]
    es ignored :: [a]
    ignored = [a] -> SBV Bool
    go [a]
    es
        where isIgnored :: a -> SBV Bool
    isIgnored = (a -> [a] -> SBV Bool
    forall a. EqSymbolic a => a -> [a] -> SBV Bool
    `sElem` [a]
    ignored)

              go :: [a] -> SBV Bool
    go []     = SBV Bool
    sTrue
              go (x :: a
    x:xs :: [a]
    xs) = let xOK :: SBV Bool
    xOK  = a -> SBV Bool
    isIgnored a
    x SBV Bool -> SBV Bool -> SBV Bool
    .|| (a -> SBV Bool) -> [a] -> SBV Bool
    forall a. (a -> SBV Bool) -> [a] -> SBV Bool
    sAll (\y :: a
    y -> a -> SBV Bool
    isIgnored a
    y SBV Bool -> SBV Bool -> SBV Bool
    .|| a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    ./= a
    y) [a]
    xs
                          in SBV Bool
    xOK SBV Bool -> SBV Bool -> SBV Bool
    .&& [a] -> SBV Bool
    go [a]
    xs

      x :: a
    x `sElem`    xs :: [a]
    xs = (a -> SBV Bool) -> [a] -> SBV Bool
    forall a. (a -> SBV Bool) -> [a] -> SBV Bool
    sAny (a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    x) [a]
    xs
      x :: a
    x `sNotElem` xs :: [a]
    xs = SBV Bool -> SBV Bool
    sNot (a
    x a -> [a] -> SBV Bool
    forall a. EqSymbolic a => a -> [a] -> SBV Bool
    `sElem` [a]
    xs)

    -- | Symbolic Comparisons. Similar to 'Eq', we cannot implement Haskell's 'Ord' class
    -- since there is no way to return an 'Ordering' value from a symbolic comparison.
    -- Furthermore, 'OrdSymbolic' requires 'Mergeable' to implement if-then-else, for the
    -- benefit of implementing symbolic versions of 'max' and 'min' functions.
    infix 4 .<, .<=, .>, .>=
    class (Mergeable a, EqSymbolic a) => OrdSymbolic a where
      -- | Symbolic less than.
      (.<)  :: a -> a -> SBool
      -- | Symbolic less than or equal to.
      (.<=) :: a -> a -> SBool
      -- | Symbolic greater than.
      (.>)  :: a -> a -> SBool
      -- | Symbolic greater than or equal to.
      (.>=) :: a -> a -> SBool
      -- | Symbolic minimum.
      smin  :: a -> a -> a
      -- | Symbolic maximum.
      smax  :: a -> a -> a
      -- | Is the value withing the allowed /inclusive/ range?
      inRange    :: a -> (a, a) -> SBool

      {-# MINIMAL (.<) #-}

      a :: a
    a .<= b :: a
    b    = a
    a a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< a
    b SBV Bool -> SBV Bool -> SBV Bool
    .|| a
    a a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    b
      a :: a
    a .>  b :: a
    b    = a
    b a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<  a
    a
      a :: a
    a .>= b :: a
    b    = a
    b a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<= a
    a

      a :: a
    a `smin` b :: a
    b = SBV Bool -> a -> a -> a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (a
    a a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<= a
    b) a
    a a
    b
      a :: a
    a `smax` b :: a
    b = SBV Bool -> a -> a -> a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (a
    a a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<= a
    b) a
    b a
    a

      inRange x :: a
    x (y :: a
    y, z :: a
    z) = a
    x a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .>= a
    y SBV Bool -> SBV Bool -> SBV Bool
    .&& a
    x a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<= a
    z

    {- We can't have a generic instance of the form:

    instance Eq a => EqSymbolic a where
      x .== y = if x == y then true else sFalse

    even if we're willing to allow Flexible/undecidable instances..
    This is because if we allow this it would imply EqSymbolic (SBV a);
    since (SBV a) has to be Eq as it must be a Num. But this wouldn't be
    the right choice obviously; as the Eq instance is bogus for SBV
    for natural reasons..
    -}

    -- It is tempting to put in an @Eq a@ superclass here. But doing so
    -- is complicated, as it requires all underlying types to have equality,
    -- which is at best shaky for algebraic reals and sets. So, leave it out.
    instance EqSymbolic (SBV a) where
      SBV x :: SVal
    x .== :: SBV a -> SBV a -> SBV Bool
    .== SBV y :: SVal
    y = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svEqual SVal
    x SVal
    y)
      SBV x :: SVal
    x ./= :: SBV a -> SBV a -> SBV Bool
    ./= SBV y :: SVal
    y = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svNotEqual SVal
    x SVal
    y)

      SBV x :: SVal
    x .=== :: SBV a -> SBV a -> SBV Bool
    .=== SBV y :: SVal
    y = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svStrongEqual SVal
    x SVal
    y)

      -- Custom version of distinct that generates better code for base types
      distinct :: [SBV a] -> SBV Bool
    distinct []                                             = SBV Bool
    sTrue
      distinct [_]                                            = SBV Bool
    sTrue
      distinct xs :: [SBV a]
    xs | (SBV a -> Bool) -> [SBV a] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all SBV a -> Bool
    forall a. SBV a -> Bool
    isConc [SBV a]
    xs                             = [SBV a] -> SBV Bool
    forall a. EqSymbolic a => [a] -> SBV Bool
    checkDiff [SBV a]
    xs
                  | [SBV a :: SVal
    a, SBV b :: SVal
    b] <- [SBV a]
    xs, SVal
    a SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    True  = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Bool) -> SVal -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ SVal -> SVal
    svNot SVal
    b
                  | [SBV a :: SVal
    a, SBV b :: SVal
    b] <- [SBV a]
    xs, SVal
    b SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    True  = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Bool) -> SVal -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ SVal -> SVal
    svNot SVal
    a
                  | [SBV a :: SVal
    a, SBV b :: SVal
    b] <- [SBV a]
    xs, SVal
    a SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    False = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV SVal
    b
                  | [SBV a :: SVal
    a, SBV b :: SVal
    b] <- [SBV a]
    xs, SVal
    b SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    False = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV SVal
    a
                  | [SBV a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBV a]
    xs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 2 Bool -> Bool -> Bool
    && SBV a -> Bool
    forall a. SBV a -> Bool
    isBool ([SBV a] -> SBV a
    forall a. [a] -> a
    head [SBV a]
    xs)         = SBV Bool
    sFalse
                  | Bool
    True                                      = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KBool (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r)))
        where r :: State -> IO SV
    r st :: State
    st = do [SV]
    xsv <- (SBV a -> IO SV) -> [SBV a] -> IO [SV]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st) [SBV a]
    xs
                        State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    KBool (Op -> [SV] -> SBVExpr
    SBVApp Op
    NotEqual [SV]
    xsv)

              -- We call this in case all are concrete, which will
              -- reduce to a constant and generate no code at all!
              -- Note that this is essentially the same as the default
              -- definition, which unfortunately we can no longer call!
              checkDiff :: [a] -> SBV Bool
    checkDiff []     = SBV Bool
    sTrue
              checkDiff (a :: a
    a:as :: [a]
    as) = (a -> SBV Bool) -> [a] -> SBV Bool
    forall a. (a -> SBV Bool) -> [a] -> SBV Bool
    sAll (a
    a a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    ./=) [a]
    as SBV Bool -> SBV Bool -> SBV Bool
    .&& [a] -> SBV Bool
    checkDiff [a]
    as

              -- Sigh, we can't use isConcrete since that requires SymVal
              -- constraint that we don't have here. (To support SBools.)
              isConc :: SBV a -> Bool
    isConc (SBV (SVal _ (Left _))) = Bool
    True
              isConc _                       = Bool
    False

              -- Likewise here; need to go lower.
              SVal k1 :: Kind
    k1 (Left c1 :: CV
    c1) is :: SVal -> SVal -> Bool
    `is` SVal k2 :: Kind
    k2 (Left c2 :: CV
    c2) = (Kind
    k1, CV
    c1) (Kind, CV) -> (Kind, CV) -> Bool
    forall a. Eq a => a -> a -> Bool
    == (Kind
    k2, CV
    c2)
              _                 `is` _                 = Bool
    False

              isBool :: SBV a -> Bool
    isBool (SBV (SVal KBool _)) = Bool
    True
              isBool _                    = Bool
    False

      -- Custom version of distinctExcept that generates better code for base types
      -- We essentially keep track of an array and count cardinalities as we walk along.
      distinctExcept :: [SBV a] -> [SBV a] -> SBV Bool
    distinctExcept []  _       = SBV Bool
    sTrue
      distinctExcept [_] _       = SBV Bool
    sTrue
      distinctExcept es :: [SBV a]
    es  ignored :: [SBV a]
    ignored
         | (SBV a -> Bool) -> [SBV a] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all SBV a -> Bool
    forall a. SBV a -> Bool
    isConc ([SBV a]
    es [SBV a] -> [SBV a] -> [SBV a]
    forall a. [a] -> [a] -> [a]
    ++ [SBV a]
    ignored)
        = [SBV a] -> SBV Bool
    forall a. EqSymbolic a => [a] -> SBV Bool
    distinct ((SBV a -> Bool) -> [SBV a] -> [SBV a]
    forall a. (a -> Bool) -> [a] -> [a]
    filter SBV a -> Bool
    ignoreConc [SBV a]
    es)
        | Bool
    True
        = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KBool (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r)))
        where ignoreConc :: SBV a -> Bool
    ignoreConc x :: SBV a
    x = case SBV a
    x SBV a -> [SBV a] -> SBV Bool
    forall a. EqSymbolic a => a -> [a] -> SBV Bool
    `sElem` [SBV a]
    ignored of
                               SBV (SVal KBool (Left cv :: CV
    cv)) -> CV -> Bool
    cvToBool CV
    cv
                               _                          -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "distinctExcept: Impossible happened, concrete sElem failed: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ([SBV a], [SBV a], SBV a) -> String
    forall a. Show a => a -> String
    show ([SBV a]
    es, [SBV a]
    ignored, SBV a
    x)

              ek :: Kind
    ek = case [SBV a] -> SBV a
    forall a. [a] -> a
    head [SBV a]
    es of  -- Head is safe here as we're guaranteed to have a non-empty es by pattern matching above. (Actually, there'll be at least two elements)
                     SBV (SVal k :: Kind
    k _) -> Kind
    k

              r :: State -> IO SV
    r st :: State
    st = do let zero :: SBV Integer
    zero = 0 :: SInteger

                        SArray a Integer
    arr <- SArr -> SArray a Integer
    forall a b. SArr -> SArray a b
    SArray (SArr -> SArray a Integer) -> IO SArr -> IO (SArray a Integer)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> State -> (Kind, Kind) -> (Int -> String) -> Maybe SVal -> IO SArr
    newSArr State
    st (Kind
    ek, Kind
    KUnbounded) (\i :: Int
    i -> "array_" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    i) (SVal -> Maybe SVal
    forall a. a -> Maybe a
    Just (SBV Integer -> SVal
    forall a. SBV a -> SVal
    unSBV SBV Integer
    zero))

                        let incr :: SBV a -> SArray a Integer -> SBV Integer
    incr x :: SBV a
    x table :: SArray a Integer
    table = SBV Bool -> SBV Integer -> SBV Integer -> SBV Integer
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    x SBV a -> [SBV a] -> SBV Bool
    forall a. EqSymbolic a => a -> [a] -> SBV Bool
    `sElem` [SBV a]
    ignored) SBV Integer
    zero (1 SBV Integer -> SBV Integer -> SBV Integer
    forall a. Num a => a -> a -> a
    + SArray a Integer -> SBV a -> SBV Integer
    forall (array :: * -> * -> *) a b.
    SymArray array =>
    array a b -> SBV a -> SBV b
    readArray SArray a Integer
    table SBV a
    x)

                            insert :: [SBV a] -> SArray a Integer -> SArray a Integer
    insert []     table :: SArray a Integer
    table = SArray a Integer
    table
                            insert (x :: SBV a
    x:xs :: [SBV a]
    xs) table :: SArray a Integer
    table = [SBV a] -> SArray a Integer -> SArray a Integer
    insert [SBV a]
    xs (SArray a Integer -> SBV a -> SBV Integer -> SArray a Integer
    forall (array :: * -> * -> *) b a.
    (SymArray array, SymVal b) =>
    array a b -> SBV a -> SBV b -> array a b
    writeArray SArray a Integer
    table SBV a
    x (SBV a -> SArray a Integer -> SBV Integer
    incr SBV a
    x SArray a Integer
    table))

                            finalArray :: SArray a Integer
    finalArray = [SBV a] -> SArray a Integer -> SArray a Integer
    insert [SBV a]
    es SArray a Integer
    arr

                        State -> SBV Bool -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV Bool -> IO SV) -> SBV Bool -> IO SV
    forall a b. (a -> b) -> a -> b
    $ (SBV a -> SBV Bool) -> [SBV a] -> SBV Bool
    forall a. (a -> SBV Bool) -> [a] -> SBV Bool
    sAll (\e :: SBV a
    e -> SArray a Integer -> SBV a -> SBV Integer
    forall (array :: * -> * -> *) a b.
    SymArray array =>
    array a b -> SBV a -> SBV b
    readArray SArray a Integer
    finalArray SBV a
    e SBV Integer -> SBV Integer -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<= 1) [SBV a]
    es

              -- Sigh, we can't use isConcrete since that requires SymVal
              -- constraint that we don't have here. (To support SBools.)
              isConc :: SBV a -> Bool
    isConc (SBV (SVal _ (Left _))) = Bool
    True
              isConc _                       = Bool
    False

    -- | If comparison is over something SMTLib can handle, just translate it. Otherwise desugar.
    instance (Ord a, SymVal a) => OrdSymbolic (SBV a) where
      a :: SBV a
    a@(SBV x :: SVal
    x) .< :: SBV a -> SBV a -> SBV Bool
    .<  b :: SBV a
    b@(SBV y :: SVal
    y) | String -> SBV a -> SBV a -> Bool
    forall a. (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
    smtComparable "<"   SBV a
    a SBV a
    b = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svLessThan SVal
    x SVal
    y)
                              | Bool
    True                    = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svStructuralLessThan SVal
    x SVal
    y)

      a :: SBV a
    a@(SBV x :: SVal
    x) .<= :: SBV a -> SBV a -> SBV Bool
    .<= b :: SBV a
    b@(SBV y :: SVal
    y) | String -> SBV a -> SBV a -> Bool
    forall a. (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
    smtComparable ".<=" SBV a
    a SBV a
    b = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svLessEq SVal
    x SVal
    y)
                              | Bool
    True                    = SBV a
    a SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< SBV a
    b SBV Bool -> SBV Bool -> SBV Bool
    .|| SBV a
    a SBV a -> SBV a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a
    b

      a :: SBV a
    a@(SBV x :: SVal
    x) .> :: SBV a -> SBV a -> SBV Bool
    .>  b :: SBV a
    b@(SBV y :: SVal
    y) | String -> SBV a -> SBV a -> Bool
    forall a. (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
    smtComparable ">"   SBV a
    a SBV a
    b = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svGreaterThan SVal
    x SVal
    y)
                              | Bool
    True                    = SBV a
    b SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< SBV a
    a

      a :: SBV a
    a@(SBV x :: SVal
    x) .>= :: SBV a -> SBV a -> SBV Bool
    .>= b :: SBV a
    b@(SBV y :: SVal
    y) | String -> SBV a -> SBV a -> Bool
    forall a. (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
    smtComparable ">="  SBV a
    a SBV a
    b = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svGreaterEq SVal
    x SVal
    y)
                              | Bool
    True                    = SBV a
    b SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<= SBV a
    a

    -- Is this a type that's comparable by underlying translation to SMTLib?
    -- Note that we allow concrete versions to go through unless the type is a set, as there's really no reason not to.
    smtComparable :: (SymVal a, HasKind a) => String -> SBV a -> SBV a -> Bool
    smtComparable :: String -> SBV a -> SBV a -> Bool
    smtComparable op :: String
    op x :: SBV a
    x y :: SBV a
    y
      | SBV a -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV a
    x Bool -> Bool -> Bool
    && SBV a -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV a
    y Bool -> Bool -> Bool
    && Bool -> Bool
    not (Kind -> Bool
    forall a. HasKind a => a -> Bool
    isSet Kind
    k)
      = Bool
    True
      | Bool
    True
      = case Kind
    k of
          KBool             -> Bool
    True
          KBounded       {} -> Bool
    True
          KUnbounded     {} -> Bool
    True
          KReal          {} -> Bool
    True
          KUninterpreted {} -> Bool
    True
          KFloat            -> Bool
    True
          KDouble           -> Bool
    True
          KChar             -> Bool
    True
          KString           -> Bool
    True
          KList          {} -> Bool
    nope     -- Unfortunately, no way for us to desugar this
          KSet           {} -> Bool
    nope     -- Ditto here..
          KTuple         {} -> Bool
    False
          KMaybe         {} -> Bool
    False
          KEither        {} -> Bool
    False
     where k :: Kind
    k    = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x
           nope :: Bool
    nope = String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Data.SBV.OrdSymbolic: SMTLib does not support " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    op String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " for " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k

    -- Bool
    instance EqSymbolic Bool where
      x :: Bool
    x .== :: Bool -> Bool -> SBV Bool
    .== y :: Bool
    y = Bool -> SBV Bool
    fromBool (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ Bool
    x Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == Bool
    y

    -- Lists
    instance EqSymbolic a => EqSymbolic [a] where
      []     .== :: [a] -> [a] -> SBV Bool
    .== []     = SBV Bool
    sTrue
      (x :: a
    x:xs :: [a]
    xs) .== (y :: a
    y:ys :: [a]
    ys) = a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    y SBV Bool -> SBV Bool -> SBV Bool
    .&& [a]
    xs [a] -> [a] -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== [a]
    ys
      _      .== _      = SBV Bool
    sFalse

    instance OrdSymbolic a => OrdSymbolic [a] where
      []     .< :: [a] -> [a] -> SBV Bool
    .< []     = SBV Bool
    sFalse
      []     .< _      = SBV Bool
    sTrue
      _      .< []     = SBV Bool
    sFalse
      (x :: a
    x:xs :: [a]
    xs) .< (y :: a
    y:ys :: [a]
    ys) = a
    x a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< a
    y SBV Bool -> SBV Bool -> SBV Bool
    .|| (a
    x a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    y SBV Bool -> SBV Bool -> SBV Bool
    .&& [a]
    xs [a] -> [a] -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< [a]
    ys)

    -- Maybe
    instance EqSymbolic a => EqSymbolic (Maybe a) where
      Nothing .== :: Maybe a -> Maybe a -> SBV Bool
    .== Nothing = SBV Bool
    sTrue
      Just a :: a
    a  .== Just b :: a
    b  = a
    a a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    b
      _       .== _       = SBV Bool
    sFalse

    instance OrdSymbolic a => OrdSymbolic (Maybe a) where
      Nothing .< :: Maybe a -> Maybe a -> SBV Bool
    .<  Nothing = SBV Bool
    sFalse
      Nothing .<  _       = SBV Bool
    sTrue
      Just _  .<  Nothing = SBV Bool
    sFalse
      Just a :: a
    a  .<  Just b :: a
    b  = a
    a a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< a
    b

    -- Either
    instance (EqSymbolic a, EqSymbolic b) => EqSymbolic (Either a b) where
      Left a :: a
    a  .== :: Either a b -> Either a b -> SBV Bool
    .== Left b :: a
    b  = a
    a a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    b
      Right a :: b
    a .== Right b :: b
    b = b
    a b -> b -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== b
    b
      _       .== _       = SBV Bool
    sFalse

    instance (OrdSymbolic a, OrdSymbolic b) => OrdSymbolic (Either a b) where
      Left a :: a
    a  .< :: Either a b -> Either a b -> SBV Bool
    .< Left b :: a
    b  = a
    a a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< a
    b
      Left _  .< Right _ = SBV Bool
    sTrue
      Right _ .< Left _  = SBV Bool
    sFalse
      Right a :: b
    a .< Right b :: b
    b = b
    a b -> b -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< b
    b

    -- 2-Tuple
    instance (EqSymbolic a, EqSymbolic b) => EqSymbolic (a, b) where
      (a0 :: a
    a0, b0 :: b
    b0) .== :: (a, b) -> (a, b) -> SBV Bool
    .== (a1 :: a
    a1, b1 :: b
    b1) = a
    a0 a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    a1 SBV Bool -> SBV Bool -> SBV Bool
    .&& b
    b0 b -> b -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== b
    b1

    instance (OrdSymbolic a, OrdSymbolic b) => OrdSymbolic (a, b) where
      (a0 :: a
    a0, b0 :: b
    b0) .< :: (a, b) -> (a, b) -> SBV Bool
    .< (a1 :: a
    a1, b1 :: b
    b1) = a
    a0 a -> a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< a
    a1 SBV Bool -> SBV Bool -> SBV Bool
    .|| (a
    a0 a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== a
    a1 SBV Bool -> SBV Bool -> SBV Bool
    .&& b
    b0 b -> b -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< b
    b1)

    -- 3-Tuple
    instance (EqSymbolic a, EqSymbolic b, EqSymbolic c) => EqSymbolic (a, b, c) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0) .== :: (a, b, c) -> (a, b, c) -> SBV Bool
    .== (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1) = (a
    a0, b
    b0) (a, b) -> (a, b) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1) SBV Bool -> SBV Bool -> SBV Bool
    .&& c
    c0 c -> c -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== c
    c1

    instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c) => OrdSymbolic (a, b, c) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0) .< :: (a, b, c) -> (a, b, c) -> SBV Bool
    .< (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1) = (a
    a0, b
    b0) (a, b) -> (a, b) -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< (a
    a1, b
    b1) SBV Bool -> SBV Bool -> SBV Bool
    .|| ((a
    a0, b
    b0) (a, b) -> (a, b) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1) SBV Bool -> SBV Bool -> SBV Bool
    .&& c
    c0 c -> c -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< c
    c1)

    -- 4-Tuple
    instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d) => EqSymbolic (a, b, c, d) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0) .== :: (a, b, c, d) -> (a, b, c, d) -> SBV Bool
    .== (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1) = (a
    a0, b
    b0, c
    c0) (a, b, c) -> (a, b, c) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1) SBV Bool -> SBV Bool -> SBV Bool
    .&& d
    d0 d -> d -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== d
    d1

    instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d) => OrdSymbolic (a, b, c, d) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0) .< :: (a, b, c, d) -> (a, b, c, d) -> SBV Bool
    .< (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1) = (a
    a0, b
    b0, c
    c0) (a, b, c) -> (a, b, c) -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< (a
    a1, b
    b1, c
    c1) SBV Bool -> SBV Bool -> SBV Bool
    .|| ((a
    a0, b
    b0, c
    c0) (a, b, c) -> (a, b, c) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1) SBV Bool -> SBV Bool -> SBV Bool
    .&& d
    d0 d -> d -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< d
    d1)

    -- 5-Tuple
    instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e) => EqSymbolic (a, b, c, d, e) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0, e0 :: e
    e0) .== :: (a, b, c, d, e) -> (a, b, c, d, e) -> SBV Bool
    .== (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1, e1 :: e
    e1) = (a
    a0, b
    b0, c
    c0, d
    d0) (a, b, c, d) -> (a, b, c, d) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1, d
    d1) SBV Bool -> SBV Bool -> SBV Bool
    .&& e
    e0 e -> e -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== e
    e1

    instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e) => OrdSymbolic (a, b, c, d, e) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0, e0 :: e
    e0) .< :: (a, b, c, d, e) -> (a, b, c, d, e) -> SBV Bool
    .< (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1, e1 :: e
    e1) = (a
    a0, b
    b0, c
    c0, d
    d0) (a, b, c, d) -> (a, b, c, d) -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< (a
    a1, b
    b1, c
    c1, d
    d1) SBV Bool -> SBV Bool -> SBV Bool
    .|| ((a
    a0, b
    b0, c
    c0, d
    d0) (a, b, c, d) -> (a, b, c, d) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1, d
    d1) SBV Bool -> SBV Bool -> SBV Bool
    .&& e
    e0 e -> e -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< e
    e1)

    -- 6-Tuple
    instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e, EqSymbolic f) => EqSymbolic (a, b, c, d, e, f) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0, e0 :: e
    e0, f0 :: f
    f0) .== :: (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> SBV Bool
    .== (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1, e1 :: e
    e1, f1 :: f
    f1) = (a
    a0, b
    b0, c
    c0, d
    d0, e
    e0) (a, b, c, d, e) -> (a, b, c, d, e) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1, d
    d1, e
    e1) SBV Bool -> SBV Bool -> SBV Bool
    .&& f
    f0 f -> f -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== f
    f1

    instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e, OrdSymbolic f) => OrdSymbolic (a, b, c, d, e, f) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0, e0 :: e
    e0, f0 :: f
    f0) .< :: (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> SBV Bool
    .< (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1, e1 :: e
    e1, f1 :: f
    f1) =    (a
    a0, b
    b0, c
    c0, d
    d0, e
    e0) (a, b, c, d, e) -> (a, b, c, d, e) -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<  (a
    a1, b
    b1, c
    c1, d
    d1, e
    e1)
                                                           SBV Bool -> SBV Bool -> SBV Bool
    .|| ((a
    a0, b
    b0, c
    c0, d
    d0, e
    e0) (a, b, c, d, e) -> (a, b, c, d, e) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1, d
    d1, e
    e1) SBV Bool -> SBV Bool -> SBV Bool
    .&& f
    f0 f -> f -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< f
    f1)

    -- 7-Tuple
    instance (EqSymbolic a, EqSymbolic b, EqSymbolic c, EqSymbolic d, EqSymbolic e, EqSymbolic f, EqSymbolic g) => EqSymbolic (a, b, c, d, e, f, g) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0, e0 :: e
    e0, f0 :: f
    f0, g0 :: g
    g0) .== :: (a, b, c, d, e, f, g) -> (a, b, c, d, e, f, g) -> SBV Bool
    .== (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1, e1 :: e
    e1, f1 :: f
    f1, g1 :: g
    g1) = (a
    a0, b
    b0, c
    c0, d
    d0, e
    e0, f
    f0) (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1, d
    d1, e
    e1, f
    f1) SBV Bool -> SBV Bool -> SBV Bool
    .&& g
    g0 g -> g -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== g
    g1

    instance (OrdSymbolic a, OrdSymbolic b, OrdSymbolic c, OrdSymbolic d, OrdSymbolic e, OrdSymbolic f, OrdSymbolic g) => OrdSymbolic (a, b, c, d, e, f, g) where
      (a0 :: a
    a0, b0 :: b
    b0, c0 :: c
    c0, d0 :: d
    d0, e0 :: e
    e0, f0 :: f
    f0, g0 :: g
    g0) .< :: (a, b, c, d, e, f, g) -> (a, b, c, d, e, f, g) -> SBV Bool
    .< (a1 :: a
    a1, b1 :: b
    b1, c1 :: c
    c1, d1 :: d
    d1, e1 :: e
    e1, f1 :: f
    f1, g1 :: g
    g1) =    (a
    a0, b
    b0, c
    c0, d
    d0, e
    e0, f
    f0) (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .<  (a
    a1, b
    b1, c
    c1, d
    d1, e
    e1, f
    f1)
                                                                   SBV Bool -> SBV Bool -> SBV Bool
    .|| ((a
    a0, b
    b0, c
    c0, d
    d0, e
    e0, f
    f0) (a, b, c, d, e, f) -> (a, b, c, d, e, f) -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (a
    a1, b
    b1, c
    c1, d
    d1, e
    e1, f
    f1) SBV Bool -> SBV Bool -> SBV Bool
    .&& g
    g0 g -> g -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< g
    g1)

    -- | Symbolic Numbers. This is a simple class that simply incorporates all number like
    -- base types together, simplifying writing polymorphic type-signatures that work for all
    -- symbolic numbers, such as 'SWord8', 'SInt8' etc. For instance, we can write a generic
    -- list-minimum function as follows:
    --
    -- @
    --    mm :: SIntegral a => [SBV a] -> SBV a
    --    mm = foldr1 (\a b -> ite (a .<= b) a b)
    -- @
    --
    -- It is similar to the standard 'Integral' class, except ranging over symbolic instances.
    class (SymVal a, Num a, Bits a, Integral a) => SIntegral a

    -- 'SIntegral' Instances, skips Real/Float/Bool
    instance SIntegral Word8
    instance SIntegral Word16
    instance SIntegral Word32
    instance SIntegral Word64
    instance SIntegral Int8
    instance SIntegral Int16
    instance SIntegral Int32
    instance SIntegral Int64
    instance SIntegral Integer

    -- | Finite bit-length symbolic values. Essentially the same as 'SIntegral', but further leaves out 'Integer'. Loosely
    -- based on Haskell's @FiniteBits@ class, but with more methods defined and structured differently to fit into the
    -- symbolic world view. Minimal complete definition: 'sFiniteBitSize'.
    class (Ord a, SymVal a, Num a, Bits a) => SFiniteBits a where
        -- | Bit size.
        sFiniteBitSize      :: SBV a -> Int
        -- | Least significant bit of a word, always stored at index 0.
        lsb                 :: SBV a -> SBool
        -- | Most significant bit of a word, always stored at the last position.
        msb                 :: SBV a -> SBool
        -- | Big-endian blasting of a word into its bits.
        blastBE             :: SBV a -> [SBool]
        -- | Little-endian blasting of a word into its bits.
        blastLE             :: SBV a -> [SBool]
        -- | Reconstruct from given bits, given in little-endian.
        fromBitsBE          :: [SBool] -> SBV a
        -- | Reconstruct from given bits, given in little-endian.
        fromBitsLE          :: [SBool] -> SBV a
        -- | Replacement for 'testBit', returning 'SBool' instead of 'Bool'.
        sTestBit            :: SBV a -> Int -> SBool
        -- | Variant of 'sTestBit', where we want to extract multiple bit positions.
        sExtractBits        :: SBV a -> [Int] -> [SBool]
        -- | Variant of 'popCount', returning a symbolic value.
        sPopCount           :: SBV a -> SWord8
        -- | A combo of 'setBit' and 'clearBit', when the bit to be set is symbolic.
        setBitTo            :: SBV a -> Int -> SBool -> SBV a
        -- | Full adder, returns carry-out from the addition. Only for unsigned quantities.
        fullAdder           :: SBV a -> SBV a -> (SBool, SBV a)
        -- | Full multipler, returns both high and low-order bits. Only for unsigned quantities.
        fullMultiplier      :: SBV a -> SBV a -> (SBV a, SBV a)
        -- | Count leading zeros in a word, big-endian interpretation.
        sCountLeadingZeros  :: SBV a -> SWord8
        -- | Count trailing zeros in a word, big-endian interpretation.
        sCountTrailingZeros :: SBV a -> SWord8

        {-# MINIMAL sFiniteBitSize #-}

        -- Default implementations
        lsb (SBV v :: SVal
    v) = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svTestBit SVal
    v 0)
        msb x :: SBV a
    x       = SBV a -> Int -> SBV Bool
    forall a. SFiniteBits a => SBV a -> Int -> SBV Bool
    sTestBit SBV a
    x (SBV a -> Int
    forall a. SFiniteBits a => SBV a -> Int
    sFiniteBitSize SBV a
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1)

        blastBE   = [SBV Bool] -> [SBV Bool]
    forall a. [a] -> [a]
    reverse ([SBV Bool] -> [SBV Bool])
    -> (SBV a -> [SBV Bool]) -> SBV a -> [SBV Bool]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SBV a -> [SBV Bool]
    forall a. SFiniteBits a => SBV a -> [SBV Bool]
    blastLE
        blastLE x :: SBV a
    x = (Int -> SBV Bool) -> [Int] -> [SBV Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map (SBV a -> Int -> SBV Bool
    forall a. SFiniteBits a => SBV a -> Int -> SBV Bool
    sTestBit SBV a
    x) [0 .. SBV a -> Int
    forall a. HasKind a => a -> Int
    intSizeOf SBV a
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1]

        fromBitsBE = [SBV Bool] -> SBV a
    forall a. SFiniteBits a => [SBV Bool] -> SBV a
    fromBitsLE ([SBV Bool] -> SBV a)
    -> ([SBV Bool] -> [SBV Bool]) -> [SBV Bool] -> SBV a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [SBV Bool] -> [SBV Bool]
    forall a. [a] -> [a]
    reverse
        fromBitsLE bs :: [SBV Bool]
    bs
           | [SBV Bool] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBV Bool]
    bs Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    w
           = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "SBV.SFiniteBits.fromBitsLE/BE: Expected: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    w String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " bits, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show ([SBV Bool] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBV Bool]
    bs)
           | Bool
    True
           = SBV a
    result
           where w :: Int
    w = SBV a -> Int
    forall a. SFiniteBits a => SBV a -> Int
    sFiniteBitSize SBV a
    result
                 result :: SBV a
    result = SBV a -> Int -> [SBV Bool] -> SBV a
    forall t. (Mergeable t, Bits t) => t -> Int -> [SBV Bool] -> t
    go 0 0 [SBV Bool]
    bs

                 go :: t -> Int -> [SBV Bool] -> t
    go !t
    acc _  []     = t
    acc
                 go !t
    acc !Int
    i (x :: SBV Bool
    x:xs :: [SBV Bool]
    xs) = t -> Int -> [SBV Bool] -> t
    go (SBV Bool -> t -> t -> t
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    x (t -> Int -> t
    forall a. Bits a => a -> Int -> a
    setBit t
    acc Int
    i) t
    acc) (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +1) [SBV Bool]
    xs

        sTestBit (SBV x :: SVal
    x) i :: Int
    i = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svTestBit SVal
    x Int
    i)
        sExtractBits x :: SBV a
    x     = (Int -> SBV Bool) -> [Int] -> [SBV Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map (SBV a -> Int -> SBV Bool
    forall a. SFiniteBits a => SBV a -> Int -> SBV Bool
    sTestBit SBV a
    x)

        -- NB. 'sPopCount' returns an 'SWord8', which can overflow when used on quantities that have
        -- more than 255 bits. For the regular interface, this suffices for all types we support.
        -- For the Dynamic interface, if we ever implement this, this will fail for bit-vectors
        -- larger than that many bits. The alternative would be to return SInteger here, but that
        -- seems a total overkill for most use cases. If such is required, users are encouraged
        -- to define their own variants, which is rather easy.
        sPopCount x :: SBV a
    x
          | SBV a -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV a
    x  = SBV Word8 -> SBV a -> SBV Word8
    forall t t. (Num t, Num t, Bits t) => t -> t -> t
    go 0 SBV a
    x
          | Bool
    True          = [SBV Word8] -> SBV Word8
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum [SBV Bool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    b 1 0 | SBV Bool
    b <- SBV a -> [SBV Bool]
    forall a. SFiniteBits a => SBV a -> [SBV Bool]
    blastLE SBV a
    x]
          where -- concrete case
                go :: t -> t -> t
    go !t
    c 0 = t
    c
                go !t
    c w :: t
    w = t -> t -> t
    go (t
    ct -> t -> t
    forall a. Num a => a -> a -> a
    +1) (t
    w t -> t -> t
    forall a. Bits a => a -> a -> a
    .&. (t
    wt -> t -> t
    forall a. Num a => a -> a -> a
    -1))

        setBitTo x :: SBV a
    x i :: Int
    i b :: SBV Bool
    b = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    b (SBV a -> Int -> SBV a
    forall a. Bits a => a -> Int -> a
    setBit SBV a
    x Int
    i) (SBV a -> Int -> SBV a
    forall a. Bits a => a -> Int -> a
    clearBit SBV a
    x Int
    i)

        fullAdder a :: SBV a
    a b :: SBV a
    b
          | SBV a -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV a
    a = String -> (SBV Bool, SBV a)
    forall a. HasCallStack => String -> a
    error "fullAdder: only works on unsigned numbers"
          | Bool
    True       = (SBV a
    a SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .> SBV a
    s SBV Bool -> SBV Bool -> SBV Bool
    .|| SBV a
    b SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .> SBV a
    s, SBV a
    s)
          where s :: SBV a
    s = SBV a
    a SBV a -> SBV a -> SBV a
    forall a. Num a => a -> a -> a
    + SBV a
    b

        -- N.B. The higher-order bits are determined using a simple shift-add multiplier,
        -- thus involving bit-blasting. It'd be naive to expect SMT solvers to deal efficiently
        -- with properties involving this function, at least with the current state of the art.
        fullMultiplier a :: SBV a
    a b :: SBV a
    b
          | SBV a -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV a
    a = String -> (SBV a, SBV a)
    forall a. HasCallStack => String -> a
    error "fullMultiplier: only works on unsigned numbers"
          | Bool
    True       = (Int -> SBV a -> SBV a -> SBV a
    go (SBV a -> Int
    forall a. SFiniteBits a => SBV a -> Int
    sFiniteBitSize SBV a
    a) 0 SBV a
    a, SBV a
    aSBV a -> SBV a -> SBV a
    forall a. Num a => a -> a -> a
    *SBV a
    b)
          where go :: Int -> SBV a -> SBV a -> SBV a
    go 0 p :: SBV a
    p _ = SBV a
    p
                go n :: Int
    n p :: SBV a
    p x :: SBV a
    x = let (c :: SBV Bool
    c, p' :: SBV a
    p')  = SBV Bool
    -> (SBV Bool, SBV a) -> (SBV Bool, SBV a) -> (SBV Bool, SBV a)
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a -> SBV Bool
    forall a. SFiniteBits a => SBV a -> SBV Bool
    lsb SBV a
    x) (SBV a -> SBV a -> (SBV Bool, SBV a)
    forall a. SFiniteBits a => SBV a -> SBV a -> (SBV Bool, SBV a)
    fullAdder SBV a
    p SBV a
    b) (SBV Bool
    sFalse, SBV a
    p)
                               (o :: SBV Bool
    o, p'' :: SBV a
    p'') = SBV Bool -> SBV a -> (SBV Bool, SBV a)
    forall a. SFiniteBits a => SBV Bool -> SBV a -> (SBV Bool, SBV a)
    shiftIn SBV Bool
    c SBV a
    p'
                               (_, x' :: SBV a
    x')  = SBV Bool -> SBV a -> (SBV Bool, SBV a)
    forall a. SFiniteBits a => SBV Bool -> SBV a -> (SBV Bool, SBV a)
    shiftIn SBV Bool
    o SBV a
    x
                           in Int -> SBV a -> SBV a -> SBV a
    go (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1) SBV a
    p'' SBV a
    x'
                shiftIn :: SBV Bool -> SBV a -> (SBV Bool, SBV a)
    shiftIn k :: SBV Bool
    k v :: SBV a
    v = (SBV a -> SBV Bool
    forall a. SFiniteBits a => SBV a -> SBV Bool
    lsb SBV a
    v, SBV a
    mask SBV a -> SBV a -> SBV a
    forall a. Bits a => a -> a -> a
    .|. (SBV a
    v SBV a -> Int -> SBV a
    forall a. Bits a => a -> Int -> a
    `shiftR` 1))
                   where mask :: SBV a
    mask = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    k (Int -> SBV a
    forall a. Bits a => Int -> a
    bit (SBV a -> Int
    forall a. SFiniteBits a => SBV a -> Int
    sFiniteBitSize SBV a
    v Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1)) 0

        -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
        sCountLeadingZeros x :: SBV a
    x = Int -> SBV Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    m SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Num a => a -> a -> a
    - Int -> SBV Word8
    go Int
    m
          where m :: Int
    m = SBV a -> Int
    forall a. SFiniteBits a => SBV a -> Int
    sFiniteBitSize SBV a
    x Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1

                -- NB. When i is 0 below, which happens when x is 0 as we count all the way down,
                -- we return -1, which is equal to 2^n-1, giving us: n-1-(2^n-1) = n-2^n = n, as required, i.e., the bit-size.
                go :: Int -> SWord8
                go :: Int -> SBV Word8
    go i :: Int
    i | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 = SBV Word8
    i8
                     | Bool
    True  = SBV Bool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a -> Int -> SBV Bool
    forall a. SFiniteBits a => SBV a -> Int -> SBV Bool
    sTestBit SBV a
    x Int
    i) SBV Word8
    i8 (Int -> SBV Word8
    go (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1))
                   where i8 :: SBV Word8
    i8 = Word8 -> SBV Word8
    forall a. SymVal a => a -> SBV a
    literal (Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i :: Word8)

        -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
        sCountTrailingZeros x :: SBV a
    x = Int -> SBV Word8
    go 0
           where m :: Int
    m = SBV a -> Int
    forall a. SFiniteBits a => SBV a -> Int
    sFiniteBitSize SBV a
    x

                 go :: Int -> SWord8
                 go :: Int -> SBV Word8
    go i :: Int
    i | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    m = SBV Word8
    i8
                      | Bool
    True   = SBV Bool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a -> Int -> SBV Bool
    forall a. SFiniteBits a => SBV a -> Int -> SBV Bool
    sTestBit SBV a
    x Int
    i) SBV Word8
    i8 (Int -> SBV Word8
    go (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +1))
                    where i8 :: SBV Word8
    i8 = Word8 -> SBV Word8
    forall a. SymVal a => a -> SBV a
    literal (Int -> Word8
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i :: Word8)

    -- 'SFiniteBits' Instances, skips Real/Float/Bool/Integer
    instance SFiniteBits Word8  where sFiniteBitSize :: SBV Word8 -> Int
    sFiniteBitSize _ =  8
    instance SFiniteBits Word16 where sFiniteBitSize :: SBV Word16 -> Int
    sFiniteBitSize _ = 16
    instance SFiniteBits Word32 where sFiniteBitSize :: SBV Word32 -> Int
    sFiniteBitSize _ = 32
    instance SFiniteBits Word64 where sFiniteBitSize :: SBV Word64 -> Int
    sFiniteBitSize _ = 64
    instance SFiniteBits Int8   where sFiniteBitSize :: SBV Int8 -> Int
    sFiniteBitSize _ =  8
    instance SFiniteBits Int16  where sFiniteBitSize :: SBV Int16 -> Int
    sFiniteBitSize _ = 16
    instance SFiniteBits Int32  where sFiniteBitSize :: SBV Int32 -> Int
    sFiniteBitSize _ = 32
    instance SFiniteBits Int64  where sFiniteBitSize :: SBV Int64 -> Int
    sFiniteBitSize _ = 64

    -- | Returns 1 if the boolean is 'sTrue', otherwise 0.
    oneIf :: (Ord a, Num a, SymVal a) => SBool -> SBV a
    oneIf :: SBV Bool -> SBV a
    oneIf t :: SBV Bool
    t = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    t 1 0

    -- | Lift a pseudo-boolean op, performing checks
    liftPB :: String -> PBOp -> [SBool] -> SBool
    liftPB :: String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB w :: String
    w o :: PBOp
    o xs :: [SBV Bool]
    xs
      | Just e :: String
    e <- PBOp -> Maybe String
    check PBOp
    o
      = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    w String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    e
      | Bool
    True
      = SBV Bool
    result
      where check :: PBOp -> Maybe String
    check (PB_AtMost  k :: Int
    k) = Int -> Maybe String
    forall a. (Ord a, Num a, Show a) => a -> Maybe String
    pos Int
    k
            check (PB_AtLeast k :: Int
    k) = Int -> Maybe String
    forall a. (Ord a, Num a, Show a) => a -> Maybe String
    pos Int
    k
            check (PB_Exactly k :: Int
    k) = Int -> Maybe String
    forall a. (Ord a, Num a, Show a) => a -> Maybe String
    pos Int
    k
            check (PB_Le cs :: [Int]
    cs   k :: Int
    k) = Int -> Maybe String
    forall a. (Ord a, Num a, Show a) => a -> Maybe String
    pos Int
    k Maybe String -> Maybe String -> Maybe String
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` [Int] -> Maybe String
    match [Int]
    cs
            check (PB_Ge cs :: [Int]
    cs   k :: Int
    k) = Int -> Maybe String
    forall a. (Ord a, Num a, Show a) => a -> Maybe String
    pos Int
    k Maybe String -> Maybe String -> Maybe String
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` [Int] -> Maybe String
    match [Int]
    cs
            check (PB_Eq cs :: [Int]
    cs   k :: Int
    k) = Int -> Maybe String
    forall a. (Ord a, Num a, Show a) => a -> Maybe String
    pos Int
    k Maybe String -> Maybe String -> Maybe String
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` [Int] -> Maybe String
    match [Int]
    cs

            pos :: a -> Maybe String
    pos k :: a
    k
              | a
    k a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ "comparison value must be positive, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ a -> String
    forall a. Show a => a -> String
    show a
    k
              | Bool
    True  = Maybe String
    forall a. Maybe a
    Nothing

            match :: [Int] -> Maybe String
    match cs :: [Int]
    cs
              | (Int -> Bool) -> [Int] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    any (Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0) [Int]
    cs = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ "coefficients must be non-negative. Received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ [Int] -> String
    forall a. Show a => a -> String
    show [Int]
    cs
              | Int
    lxs Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    lcs   = String -> Maybe String
    forall a. a -> Maybe a
    Just (String -> Maybe String) -> String -> Maybe String
    forall a b. (a -> b) -> a -> b
    $ "coefficient length must match number of arguments. Received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> String
    forall a. Show a => a -> String
    show (Int
    lcs, Int
    lxs)
              | Bool
    True         = Maybe String
    forall a. Maybe a
    Nothing
              where lxs :: Int
    lxs = [SBV Bool] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBV Bool]
    xs
                    lcs :: Int
    lcs = [Int] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Int]
    cs

            result :: SBV Bool
    result = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KBool (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r)))
            r :: State -> IO SV
    r st :: State
    st   = do [SV]
    xsv <- (SBV Bool -> IO SV) -> [SBV Bool] -> IO [SV]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (State -> SBV Bool -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st) [SBV Bool]
    xs
                        -- PseudoBoolean's implicitly require support for integers, so make sure to register that kind!
                        State -> Kind -> IO ()
    registerKind State
    st Kind
    KUnbounded
                        State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    KBool (Op -> [SV] -> SBVExpr
    SBVApp (PBOp -> Op
    PseudoBoolean PBOp
    o) [SV]
    xsv)

    -- | 'sTrue' if at most @k@ of the input arguments are 'sTrue'
    pbAtMost :: [SBool] -> Int -> SBool
    pbAtMost :: [SBV Bool] -> Int -> SBV Bool
    pbAtMost xs :: [SBV Bool]
    xs k :: Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0             = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbAtMost: Non-negative value required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    k
     | (SBV Bool -> Bool) -> [SBV Bool] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all SBV Bool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete [SBV Bool]
    xs = Bool -> SBV Bool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((SBV Bool -> Integer) -> [SBV Bool] -> [Integer]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> Int -> SBV Bool -> Integer
    pbToInteger "pbAtMost" 1) [SBV Bool]
    xs) Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    k
     | Bool
    True              = String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB "pbAtMost" (Int -> PBOp
    PB_AtMost Int
    k) [SBV Bool]
    xs

    -- | 'sTrue' if at least @k@ of the input arguments are 'sTrue'
    pbAtLeast :: [SBool] -> Int -> SBool
    pbAtLeast :: [SBV Bool] -> Int -> SBV Bool
    pbAtLeast xs :: [SBV Bool]
    xs k :: Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0             = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbAtLeast: Non-negative value required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    k
     | (SBV Bool -> Bool) -> [SBV Bool] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all SBV Bool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete [SBV Bool]
    xs = Bool -> SBV Bool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((SBV Bool -> Integer) -> [SBV Bool] -> [Integer]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> Int -> SBV Bool -> Integer
    pbToInteger "pbAtLeast" 1) [SBV Bool]
    xs) Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    k
     | Bool
    True              = String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB "pbAtLeast" (Int -> PBOp
    PB_AtLeast Int
    k) [SBV Bool]
    xs

    -- | 'sTrue' if exactly @k@ of the input arguments are 'sTrue'
    pbExactly :: [SBool] -> Int -> SBool
    pbExactly :: [SBV Bool] -> Int -> SBV Bool
    pbExactly xs :: [SBV Bool]
    xs k :: Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0             = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbExactly: Non-negative value required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    k
     | (SBV Bool -> Bool) -> [SBV Bool] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all SBV Bool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete [SBV Bool]
    xs = Bool -> SBV Bool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((SBV Bool -> Integer) -> [SBV Bool] -> [Integer]
    forall a b. (a -> b) -> [a] -> [b]
    map (String -> Int -> SBV Bool -> Integer
    pbToInteger "pbExactly" 1) [SBV Bool]
    xs) Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    k
     | Bool
    True              = String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB "pbExactly" (Int -> PBOp
    PB_Exactly Int
    k) [SBV Bool]
    xs

    -- | 'sTrue' if the sum of coefficients for 'sTrue' elements is at most @k@. Generalizes 'pbAtMost'.
    pbLe :: [(Int, SBool)] -> Int -> SBool
    pbLe :: [(Int, SBV Bool)] -> Int -> SBV Bool
    pbLe xs :: [(Int, SBV Bool)]
    xs k :: Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0                     = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbLe: Non-negative value required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    k
     | ((Int, SBV Bool) -> Bool) -> [(Int, SBV Bool)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (SBV Bool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete (SBV Bool -> Bool)
    -> ((Int, SBV Bool) -> SBV Bool) -> (Int, SBV Bool) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int, SBV Bool) -> SBV Bool
    forall a b. (a, b) -> b
    snd) [(Int, SBV Bool)]
    xs = Bool -> SBV Bool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum [String -> Int -> SBV Bool -> Integer
    pbToInteger "pbLe" Int
    c SBV Bool
    b | (c :: Int
    c, b :: SBV Bool
    b) <- [(Int, SBV Bool)]
    xs] Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    k
     | Bool
    True                      = String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB "pbLe" ([Int] -> Int -> PBOp
    PB_Le (((Int, SBV Bool) -> Int) -> [(Int, SBV Bool)] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, SBV Bool) -> Int
    forall a b. (a, b) -> a
    fst [(Int, SBV Bool)]
    xs) Int
    k) (((Int, SBV Bool) -> SBV Bool) -> [(Int, SBV Bool)] -> [SBV Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, SBV Bool) -> SBV Bool
    forall a b. (a, b) -> b
    snd [(Int, SBV Bool)]
    xs)

    -- | 'sTrue' if the sum of coefficients for 'sTrue' elements is at least @k@. Generalizes 'pbAtLeast'.
    pbGe :: [(Int, SBool)] -> Int -> SBool
    pbGe :: [(Int, SBV Bool)] -> Int -> SBV Bool
    pbGe xs :: [(Int, SBV Bool)]
    xs k :: Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0                     = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbGe: Non-negative value required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    k
     | ((Int, SBV Bool) -> Bool) -> [(Int, SBV Bool)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (SBV Bool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete (SBV Bool -> Bool)
    -> ((Int, SBV Bool) -> SBV Bool) -> (Int, SBV Bool) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int, SBV Bool) -> SBV Bool
    forall a b. (a, b) -> b
    snd) [(Int, SBV Bool)]
    xs = Bool -> SBV Bool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum [String -> Int -> SBV Bool -> Integer
    pbToInteger "pbGe" Int
    c SBV Bool
    b | (c :: Int
    c, b :: SBV Bool
    b) <- [(Int, SBV Bool)]
    xs] Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    k
     | Bool
    True                      = String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB "pbGe" ([Int] -> Int -> PBOp
    PB_Ge (((Int, SBV Bool) -> Int) -> [(Int, SBV Bool)] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, SBV Bool) -> Int
    forall a b. (a, b) -> a
    fst [(Int, SBV Bool)]
    xs) Int
    k) (((Int, SBV Bool) -> SBV Bool) -> [(Int, SBV Bool)] -> [SBV Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, SBV Bool) -> SBV Bool
    forall a b. (a, b) -> b
    snd [(Int, SBV Bool)]
    xs)

    -- | 'sTrue' if the sum of coefficients for 'sTrue' elements is exactly least @k@. Useful for coding
    -- /exactly K-of-N/ constraints, and in particular mutex constraints.
    pbEq :: [(Int, SBool)] -> Int -> SBool
    pbEq :: [(Int, SBV Bool)] -> Int -> SBV Bool
    pbEq xs :: [(Int, SBV Bool)]
    xs k :: Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0                     = String -> SBV Bool
    forall a. HasCallStack => String -> a
    error (String -> SBV Bool) -> String -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbEq: Non-negative value required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    k
     | ((Int, SBV Bool) -> Bool) -> [(Int, SBV Bool)] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (SBV Bool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete (SBV Bool -> Bool)
    -> ((Int, SBV Bool) -> SBV Bool) -> (Int, SBV Bool) -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (Int, SBV Bool) -> SBV Bool
    forall a b. (a, b) -> b
    snd) [(Int, SBV Bool)]
    xs = Bool -> SBV Bool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBV Bool) -> Bool -> SBV Bool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum [String -> Int -> SBV Bool -> Integer
    pbToInteger "pbEq" Int
    c SBV Bool
    b | (c :: Int
    c, b :: SBV Bool
    b) <- [(Int, SBV Bool)]
    xs] Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    k
     | Bool
    True                      = String -> PBOp -> [SBV Bool] -> SBV Bool
    liftPB "pbEq" ([Int] -> Int -> PBOp
    PB_Eq (((Int, SBV Bool) -> Int) -> [(Int, SBV Bool)] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, SBV Bool) -> Int
    forall a b. (a, b) -> a
    fst [(Int, SBV Bool)]
    xs) Int
    k) (((Int, SBV Bool) -> SBV Bool) -> [(Int, SBV Bool)] -> [SBV Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map (Int, SBV Bool) -> SBV Bool
    forall a b. (a, b) -> b
    snd [(Int, SBV Bool)]
    xs)

    -- | 'sTrue' if there is at most one set bit
    pbMutexed :: [SBool] -> SBool
    pbMutexed :: [SBV Bool] -> SBV Bool
    pbMutexed xs :: [SBV Bool]
    xs = [SBV Bool] -> Int -> SBV Bool
    pbAtMost [SBV Bool]
    xs 1

    -- | 'sTrue' if there is exactly one set bit
    pbStronglyMutexed :: [SBool] -> SBool
    pbStronglyMutexed :: [SBV Bool] -> SBV Bool
    pbStronglyMutexed xs :: [SBV Bool]
    xs = [SBV Bool] -> Int -> SBV Bool
    pbExactly [SBV Bool]
    xs 1

    -- | Convert a concrete pseudo-boolean to given int; converting to integer
    pbToInteger :: String -> Int -> SBool -> Integer
    pbToInteger :: String -> Int -> SBV Bool -> Integer
    pbToInteger w :: String
    w c :: Int
    c b :: SBV Bool
    b
     | Int
    c Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0                 = String -> Integer
    forall a. HasCallStack => String -> a
    error (String -> Integer) -> String -> Integer
    forall a b. (a -> b) -> a -> b
    $ "SBV." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    w String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": Non-negative coefficient required, received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    c
     | Just v :: Bool
    v <- SBV Bool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV Bool
    b = if Bool
    v then Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    c else 0
     | Bool
    True                  = String -> Integer
    forall a. HasCallStack => String -> a
    error (String -> Integer) -> String -> Integer
    forall a b. (a -> b) -> a -> b
    $ "SBV.pbToInteger: Received a symbolic boolean: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, SBV Bool) -> String
    forall a. Show a => a -> String
    show (Int
    c, SBV Bool
    b)

    -- | Predicate for optimizing word operations like (+) and (*).
    isConcreteZero :: SBV a -> Bool
    isConcreteZero :: SBV a -> Bool
    isConcreteZero (SBV (SVal _     (Left (CV _     (CInteger n :: Integer
    n))))) = Integer
    n Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0
    isConcreteZero (SBV (SVal KReal (Left (CV KReal (CAlgReal v :: AlgReal
    v))))) = AlgReal -> Bool
    isExactRational AlgReal
    v Bool -> Bool -> Bool
    && AlgReal
    v AlgReal -> AlgReal -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0
    isConcreteZero _                                                 = Bool
    False

    -- | Predicate for optimizing word operations like (+) and (*).
    isConcreteOne :: SBV a -> Bool
    isConcreteOne :: SBV a -> Bool
    isConcreteOne (SBV (SVal _     (Left (CV _     (CInteger 1))))) = Bool
    True
    isConcreteOne (SBV (SVal KReal (Left (CV KReal (CAlgReal v :: AlgReal
    v))))) = AlgReal -> Bool
    isExactRational AlgReal
    v Bool -> Bool -> Bool
    && AlgReal
    v AlgReal -> AlgReal -> Bool
    forall a. Eq a => a -> a -> Bool
    == 1
    isConcreteOne _                                                 = Bool
    False

    -- Num instance for symbolic words.
    instance (Ord a, Num a, SymVal a) => Num (SBV a) where
      fromInteger :: Integer -> SBV a
    fromInteger = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal (a -> SBV a) -> (Integer -> a) -> Integer -> SBV a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral
      SBV x :: SVal
    x + :: SBV a -> SBV a -> SBV a
    + SBV y :: SVal
    y = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svPlus SVal
    x SVal
    y)
      SBV x :: SVal
    x * :: SBV a -> SBV a -> SBV a
    * SBV y :: SVal
    y = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svTimes SVal
    x SVal
    y)
      SBV x :: SVal
    x - :: SBV a -> SBV a -> SBV a
    - SBV y :: SVal
    y = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svMinus SVal
    x SVal
    y)
      -- Abs is problematic for floating point, due to -0; case, so we carefully shuttle it down
      -- to the solver to avoid the can of worms. (Alternative would be to do an if-then-else here.)
      abs :: SBV a -> SBV a
    abs (SBV x :: SVal
    x) = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal
    svAbs SVal
    x)
      signum :: SBV a -> SBV a
    signum a :: SBV a
    a
        -- NB. The following "carefully" tests the number for == 0, as Float/Double's NaN and +/-0
        -- cases would cause trouble with explicit equality tests.
        | SBV a -> Bool
    forall a. HasKind a => a -> Bool
    hasSign SBV a
    a = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    a SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .> SBV a
    z) SBV a
    i
                    (SBV a -> SBV a) -> SBV a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    a SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< SBV a
    z) (SBV a -> SBV a
    forall a. Num a => a -> a
    negate SBV a
    i) SBV a
    a
        | Bool
    True      = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    a SBV a -> SBV a -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .> SBV a
    z) SBV a
    i SBV a
    a
        where z :: SBV a
    z = Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    a) (0::Integer)
              i :: SBV a
    i = Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    a) (1::Integer)
      -- negate is tricky because on double/float -0 is different than 0; so we cannot
      -- just rely on the default definition; which would be 0-0, which is not -0!
      negate :: SBV a -> SBV a
    negate (SBV x :: SVal
    x) = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal
    svUNeg SVal
    x)

    -- | Symbolic exponentiation using bit blasting and repeated squaring.
    --
    -- N.B. The exponent must be unsigned/bounded if symbolic. Signed exponents will be rejected.
    (.^) :: (Mergeable b, Num b, SIntegral e) => b -> SBV e -> b
    b :: b
    b .^ :: b -> SBV e -> b
    .^ e :: SBV e
    e
      | SBV e -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV e
    e, Just (Integer
    x :: Integer) <- SBV Integer -> Maybe Integer
    forall a. SymVal a => SBV a -> Maybe a
    unliteral (SBV e -> SBV Integer
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV e
    e)
      = if Integer
    x Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= 0 then let go :: a -> a -> a
    go n :: a
    n v :: a
    v
                            | a
    n a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 = 1
                            | a -> Bool
    forall a. Integral a => a -> Bool
    even a
    n =     a -> a -> a
    go (a
    n a -> a -> a
    forall a. Integral a => a -> a -> a
    `div` 2) (a
    v a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    v)
                            | Bool
    True   = a
    v a -> a -> a
    forall a. Num a => a -> a -> a
    * a -> a -> a
    go (a
    n a -> a -> a
    forall a. Integral a => a -> a -> a
    `div` 2) (a
    v a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    v)
                       in  Integer -> b -> b
    forall a a. (Num a, Integral a) => a -> a -> a
    go Integer
    x b
    b
                  else String -> b
    forall a. HasCallStack => String -> a
    error (String -> b) -> String -> b
    forall a b. (a -> b) -> a -> b
    $ "(.^): exponentiation: negative exponent: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Integer -> String
    forall a. Show a => a -> String
    show Integer
    x
      | Bool -> Bool
    not (SBV e -> Bool
    forall a. HasKind a => a -> Bool
    isBounded SBV e
    e) Bool -> Bool -> Bool
    || SBV e -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV e
    e
      = String -> b
    forall a. HasCallStack => String -> a
    error (String -> b) -> String -> b
    forall a b. (a -> b) -> a -> b
    $ "(.^): exponentiation only works with unsigned bounded symbolic exponents, kind: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show (SBV e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV e
    e)
      | Bool
    True
      =  -- NB. We can't simply use sTestBit and blastLE since they have SFiniteBit requirement
         -- but we want to have SIntegral here only.
         let SBV expt :: SVal
    expt = SBV e
    e
             expBit :: Int -> SBV Bool
    expBit i :: Int
    i = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svTestBit SVal
    expt Int
    i)
             blasted :: [SBV Bool]
    blasted  = (Int -> SBV Bool) -> [Int] -> [SBV Bool]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> SBV Bool
    expBit [0 .. SBV e -> Int
    forall a. HasKind a => a -> Int
    intSizeOf SBV e
    e Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - 1]
         in [b] -> b
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    product ([b] -> b) -> [b] -> b
    forall a b. (a -> b) -> a -> b
    $ (SBV Bool -> b -> b) -> [SBV Bool] -> [b] -> [b]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\use :: SBV Bool
    use n :: b
    n -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    use b
    n 1)
                              [SBV Bool]
    blasted
                              ((b -> b) -> b -> [b]
    forall a. (a -> a) -> a -> [a]
    iterate (\x :: b
    x -> b
    xb -> b -> b
    forall a. Num a => a -> a -> a
    *b
    x) b
    b)

    instance (Ord a, SymVal a, Fractional a) => Fractional (SBV a) where
      fromRational :: Rational -> SBV a
    fromRational  = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal (a -> SBV a) -> (Rational -> a) -> Rational -> SBV a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Rational -> a
    forall a. Fractional a => Rational -> a
    fromRational
      SBV x :: SVal
    x / :: SBV a -> SBV a -> SBV a
    / sy :: SBV a
    sy@(SBV y :: SVal
    y) | Bool
    div0 = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    sy SBV a -> SBV a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== 0) 0 SBV a
    res
                         | Bool
    True = SBV a
    res
           where res :: SBV a
    res  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svDivide SVal
    x SVal
    y)
                 -- Identify those kinds where we have a div-0 equals 0 exception
                 div0 :: Bool
    div0 = case SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    sy of
                          KFloat             -> Bool
    False
                          KDouble            -> Bool
    False
                          KReal              -> Bool
    True
                          -- Following cases should not happen since these types should *not* be instances of Fractional
                          k :: Kind
    k@KBounded{}       -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@Kind
    KUnbounded       -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@Kind
    KBool            -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@Kind
    KString          -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@Kind
    KChar            -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@KList{}          -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@KSet{}           -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@KUninterpreted{} -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@KTuple{}         -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@KMaybe{}         -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k
                          k :: Kind
    k@KEither{}        -> String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "Unexpected Fractional case for: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show Kind
    k

    -- | Define Floating instance on SBV's; only for base types that are already floating; i.e., SFloat and SDouble
    -- Note that most of the fields are "undefined" for symbolic values, we add methods as they are supported by SMTLib.
    -- Currently, the only symbolicly available function in this class is sqrt.
    instance (Ord a, SymVal a, Fractional a, Floating a) => Floating (SBV a) where
        pi :: SBV a
    pi      = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal a
    forall a. Floating a => a
    pi
        exp :: SBV a -> SBV a
    exp     = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "exp"     a -> a
    forall a. Floating a => a -> a
    exp
        log :: SBV a -> SBV a
    log     = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "log"     a -> a
    forall a. Floating a => a -> a
    log
        sqrt :: SBV a -> SBV a
    sqrt    = FPOp -> (a -> a) -> SBV a -> SBV a
    forall a. SymVal a => FPOp -> (a -> a) -> SBV a -> SBV a
    lift1F   FPOp
    FP_Sqrt   a -> a
    forall a. Floating a => a -> a
    sqrt
        sin :: SBV a -> SBV a
    sin     = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "sin"     a -> a
    forall a. Floating a => a -> a
    sin
        cos :: SBV a -> SBV a
    cos     = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "cos"     a -> a
    forall a. Floating a => a -> a
    cos
        tan :: SBV a -> SBV a
    tan     = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "tan"     a -> a
    forall a. Floating a => a -> a
    tan
        asin :: SBV a -> SBV a
    asin    = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "asin"    a -> a
    forall a. Floating a => a -> a
    asin
        acos :: SBV a -> SBV a
    acos    = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "acos"    a -> a
    forall a. Floating a => a -> a
    acos
        atan :: SBV a -> SBV a
    atan    = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "atan"    a -> a
    forall a. Floating a => a -> a
    atan
        sinh :: SBV a -> SBV a
    sinh    = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "sinh"    a -> a
    forall a. Floating a => a -> a
    sinh
        cosh :: SBV a -> SBV a
    cosh    = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "cosh"    a -> a
    forall a. Floating a => a -> a
    cosh
        tanh :: SBV a -> SBV a
    tanh    = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "tanh"    a -> a
    forall a. Floating a => a -> a
    tanh
        asinh :: SBV a -> SBV a
    asinh   = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "asinh"   a -> a
    forall a. Floating a => a -> a
    asinh
        acosh :: SBV a -> SBV a
    acosh   = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "acosh"   a -> a
    forall a. Floating a => a -> a
    acosh
        atanh :: SBV a -> SBV a
    atanh   = String -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a) -> SBV a -> SBV a
    lift1FNS "atanh"   a -> a
    forall a. Floating a => a -> a
    atanh
        ** :: SBV a -> SBV a -> SBV a
    (**)    = String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS "**"      a -> a -> a
    forall a. Floating a => a -> a -> a
    (**)
        logBase :: SBV a -> SBV a -> SBV a
    logBase = String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS "logBase" a -> a -> a
    forall a. Floating a => a -> a -> a
    logBase

    -- | Lift a 1 arg FP-op, using sRNE default
    lift1F :: SymVal a => FPOp -> (a -> a) -> SBV a -> SBV a
    lift1F :: FPOp -> (a -> a) -> SBV a -> SBV a
    lift1F w :: FPOp
    w op :: a -> a
    op a :: SBV a
    a
      | Just v :: a
    v <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    a
      = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal (a -> SBV a) -> a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ a -> a
    op a
    v
      | Bool
    True
      = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r
      where k :: Kind
    k    = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    a
            r :: State -> IO SV
    r st :: State
    st = do SV
    swa  <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    a
                      SV
    swm  <- State -> SBV RoundingMode -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV RoundingMode
    sRNE
                      State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    k (Op -> [SV] -> SBVExpr
    SBVApp (FPOp -> Op
    IEEEFP FPOp
    w) [SV
    swm, SV
    swa])

    -- | Lift a float/double unary function, only over constants
    lift1FNS :: (SymVal a, Floating a) => String -> (a -> a) -> SBV a -> SBV a
    lift1FNS :: String -> (a -> a) -> SBV a -> SBV a
    lift1FNS nm :: String
    nm f :: a -> a
    f sv :: SBV a
    sv
      | Just v :: a
    v <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    sv = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal (a -> SBV a) -> a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ a -> a
    f a
    v
      | Bool
    True                   = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "SBV." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    nm String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": not supported for symbolic values of type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    sv)

    -- | Lift a float/double binary function, only over constants
    lift2FNS :: (SymVal a, Floating a) => String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS :: String -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS nm :: String
    nm f :: a -> a -> a
    f sv1 :: SBV a
    sv1 sv2 :: SBV a
    sv2
      | Just v1 :: a
    v1 <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    sv1
      , Just v2 :: a
    v2 <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    sv2 = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal (a -> SBV a) -> a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ a -> a -> a
    f a
    v1 a
    v2
      | Bool
    True                     = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "SBV." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    nm String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ": not supported for symbolic values of type " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    sv1)

    -- NB. In the optimizations below, use of -1 is valid as
    -- -1 has all bits set to True for both signed and unsigned values
    -- | Using 'popCount' or 'testBit' on non-concrete values will result in an
    -- error. Use 'sPopCount' or 'sTestBit' instead.
    instance (Ord a, Num a, Bits a, SymVal a) => Bits (SBV a) where
      SBV x :: SVal
    x .&. :: SBV a -> SBV a -> SBV a
    .&. SBV y :: SVal
    y    = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svAnd SVal
    x SVal
    y)
      SBV x :: SVal
    x .|. :: SBV a -> SBV a -> SBV a
    .|. SBV y :: SVal
    y    = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svOr SVal
    x SVal
    y)
      SBV x :: SVal
    x xor :: SBV a -> SBV a -> SBV a
    `xor` SBV y :: SVal
    y  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svXOr SVal
    x SVal
    y)
      complement :: SBV a -> SBV a
    complement (SBV x :: SVal
    x) = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal
    svNot SVal
    x)
      bitSize :: SBV a -> Int
    bitSize  x :: SBV a
    x         = SBV a -> Int
    forall a. HasKind a => a -> Int
    intSizeOf SBV a
    x
      bitSizeMaybe :: SBV a -> Maybe Int
    bitSizeMaybe x :: SBV a
    x     = Int -> Maybe Int
    forall a. a -> Maybe a
    Just (Int -> Maybe Int) -> Int -> Maybe Int
    forall a b. (a -> b) -> a -> b
    $ SBV a -> Int
    forall a. HasKind a => a -> Int
    intSizeOf SBV a
    x
      isSigned :: SBV a -> Bool
    isSigned x :: SBV a
    x         = SBV a -> Bool
    forall a. HasKind a => a -> Bool
    hasSign SBV a
    x
      bit :: Int -> SBV a
    bit i :: Int
    i              = 1 SBV a -> Int -> SBV a
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    i
      setBit :: SBV a -> Int -> SBV a
    setBit        x :: SBV a
    x i :: Int
    i  = SBV a
    x SBV a -> SBV a -> SBV a
    forall a. Bits a => a -> a -> a
    .|. Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (Int -> Integer
    forall a. Bits a => Int -> a
    bit Int
    i :: Integer)
      clearBit :: SBV a -> Int -> SBV a
    clearBit      x :: SBV a
    x i :: Int
    i  = SBV a
    x SBV a -> SBV a -> SBV a
    forall a. Bits a => a -> a -> a
    .&. Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (Integer -> Integer
    forall a. Bits a => a -> a
    complement (Int -> Integer
    forall a. Bits a => Int -> a
    bit Int
    i) :: Integer)
      complementBit :: SBV a -> Int -> SBV a
    complementBit x :: SBV a
    x i :: Int
    i  = SBV a
    x SBV a -> SBV a -> SBV a
    forall a. Bits a => a -> a -> a
    `xor` Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (Int -> Integer
    forall a. Bits a => Int -> a
    bit Int
    i :: Integer)
      shiftL :: SBV a -> Int -> SBV a
    shiftL  (SBV x :: SVal
    x) i :: Int
    i  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svShl SVal
    x Int
    i)
      shiftR :: SBV a -> Int -> SBV a
    shiftR  (SBV x :: SVal
    x) i :: Int
    i  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svShr SVal
    x Int
    i)
      rotateL :: SBV a -> Int -> SBV a
    rotateL (SBV x :: SVal
    x) i :: Int
    i  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svRol SVal
    x Int
    i)
      rotateR :: SBV a -> Int -> SBV a
    rotateR (SBV x :: SVal
    x) i :: Int
    i  = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svRor SVal
    x Int
    i)
      -- NB. testBit is *not* implementable on non-concrete symbolic words
      x :: SBV a
    x testBit :: SBV a -> Int -> Bool
    `testBit` i :: Int
    i
        | SBV (SVal _ (Left (CV _ (CInteger n :: Integer
    n)))) <- SBV a
    x
        = Integer -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Integer
    n Int
    i
        | Bool
    True
        = String -> Bool
    forall a. HasCallStack => String -> a
    error (String -> Bool) -> String -> Bool
    forall a b. (a -> b) -> a -> b
    $ "SBV.testBit: Called on symbolic value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. Show a => a -> String
    show SBV a
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ". Use sTestBit instead."
      -- NB. popCount is *not* implementable on non-concrete symbolic words
      popCount :: SBV a -> Int
    popCount x :: SBV a
    x
        | SBV (SVal _ (Left (CV (KBounded _ w :: Int
    w) (CInteger n :: Integer
    n)))) <- SBV a
    x
        = Integer -> Int
    forall a. Bits a => a -> Int
    popCount (Integer
    n Integer -> Integer -> Integer
    forall a. Bits a => a -> a -> a
    .&. (Int -> Integer
    forall a. Bits a => Int -> a
    bit Int
    w Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    - 1))
        | Bool
    True
        = String -> Int
    forall a. HasCallStack => String -> a
    error (String -> Int) -> String -> Int
    forall a b. (a -> b) -> a -> b
    $ "SBV.popCount: Called on symbolic value: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. Show a => a -> String
    show SBV a
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ". Use sPopCount instead."

    -- | Conversion between integral-symbolic values, akin to Haskell's `fromIntegral`
    sFromIntegral :: forall a b. (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> SBV b
    sFromIntegral :: SBV a -> SBV b
    sFromIntegral x :: SBV a
    x
      | Kind
    kFrom Kind -> Kind -> Bool
    forall a. Eq a => a -> a -> Bool
    == Kind
    kTo
      = SVal -> SBV b
    forall a. SVal -> SBV a
    SBV (SBV a -> SVal
    forall a. SBV a -> SVal
    unSBV SBV a
    x)
      | SBV a -> Bool
    forall a. HasKind a => a -> Bool
    isReal SBV a
    x
      = String -> SBV b
    forall a. HasCallStack => String -> a
    error "SBV.sFromIntegral: Called on a real value" -- can't really happen due to types, but being overcautious
      | Just v :: a
    v <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    x
      = b -> SBV b
    forall a. SymVal a => a -> SBV a
    literal (a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    v)
      | Bool
    True
      = SBV b
    result
      where result :: SBV b
    result = SVal -> SBV b
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    kTo (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    y)))
            kFrom :: Kind
    kFrom  = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x
            kTo :: Kind
    kTo    = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
            y :: State -> IO SV
    y st :: State
    st   = do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                        State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    kTo (Op -> [SV] -> SBVExpr
    SBVApp (Kind -> Kind -> Op
    KindCast Kind
    kFrom Kind
    kTo) [SV
    xsv])

    -- | Lift a binary operation thru it's dynamic counterpart. Note that
    -- we still want the actual functions here as differ in their type
    -- compared to their dynamic counterparts, but the implementations
    -- are the same.
    liftViaSVal :: (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal :: (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal f :: SVal -> SVal -> SVal
    f (SBV a :: SVal
    a) (SBV b :: SVal
    b) = SVal -> SBV c
    forall a. SVal -> SBV a
    SBV (SVal -> SBV c) -> SVal -> SBV c
    forall a b. (a -> b) -> a -> b
    $ SVal -> SVal -> SVal
    f SVal
    a SVal
    b

    -- | Generalization of 'shiftL', when the shift-amount is symbolic. Since Haskell's
    -- 'shiftL' only takes an 'Int' as the shift amount, it cannot be used when we have
    -- a symbolic amount to shift with.
    sShiftLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
    sShiftLeft :: SBV a -> SBV b -> SBV a
    sShiftLeft = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV a
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svShiftLeft

    -- | Generalization of 'shiftR', when the shift-amount is symbolic. Since Haskell's
    -- 'shiftR' only takes an 'Int' as the shift amount, it cannot be used when we have
    -- a symbolic amount to shift with.
    --
    -- NB. If the shiftee is signed, then this is an arithmetic shift; otherwise it's logical,
    -- following the usual Haskell convention. See 'sSignedShiftArithRight' for a variant
    -- that explicitly uses the msb as the sign bit, even for unsigned underlying types.
    sShiftRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
    sShiftRight :: SBV a -> SBV b -> SBV a
    sShiftRight = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV a
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svShiftRight

    -- | Arithmetic shift-right with a symbolic unsigned shift amount. This is equivalent
    -- to 'sShiftRight' when the argument is signed. However, if the argument is unsigned,
    -- then it explicitly treats its msb as a sign-bit, and uses it as the bit that
    -- gets shifted in. Useful when using the underlying unsigned bit representation to implement
    -- custom signed operations. Note that there is no direct Haskell analogue of this function.
    sSignedShiftArithRight:: (SFiniteBits a, SIntegral b) => SBV a -> SBV b -> SBV a
    sSignedShiftArithRight :: SBV a -> SBV b -> SBV a
    sSignedShiftArithRight x :: SBV a
    x i :: SBV b
    i
      | SBV b -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV b
    i = String -> SBV a
    forall a. HasCallStack => String -> a
    error "sSignedShiftArithRight: shift amount should be unsigned"
      | SBV a -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV a
    x = SBV a -> SBV b -> SBV a
    forall a b c. SBV a -> SBV b -> SBV c
    ssa SBV a
    x SBV b
    i
      | Bool
    True       = SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a -> SBV Bool
    forall a. SFiniteBits a => SBV a -> SBV Bool
    msb SBV a
    x)
                         (SBV a -> SBV a
    forall a. Bits a => a -> a
    complement (SBV a -> SBV b -> SBV a
    forall a b c. SBV a -> SBV b -> SBV c
    ssa (SBV a -> SBV a
    forall a. Bits a => a -> a
    complement SBV a
    x) SBV b
    i))
                         (SBV a -> SBV b -> SBV a
    forall a b c. SBV a -> SBV b -> SBV c
    ssa SBV a
    x SBV b
    i)
      where ssa :: SBV a -> SBV b -> SBV c
    ssa = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svShiftRight

    -- | Generalization of 'rotateL', when the shift-amount is symbolic. Since Haskell's
    -- 'rotateL' only takes an 'Int' as the shift amount, it cannot be used when we have
    -- a symbolic amount to shift with. The first argument should be a bounded quantity.
    sRotateLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
    sRotateLeft :: SBV a -> SBV b -> SBV a
    sRotateLeft = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV a
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svRotateLeft

    -- | An implementation of rotate-left, using a barrel shifter like design. Only works when both
    -- arguments are finite bitvectors, and furthermore when the second argument is unsigned.
    -- The first condition is enforced by the type, but the second is dynamically checked.
    -- We provide this implementation as an alternative to `sRotateLeft` since SMTLib logic
    -- does not support variable argument rotates (as opposed to shifts), and thus this
    -- implementation can produce better code for verification compared to `sRotateLeft`.
    --
    -- >>> prove $ \x y -> (x `sBarrelRotateLeft`  y) `sBarrelRotateRight` (y :: SWord32) .== (x :: SWord64)
    -- Q.E.D.
    sBarrelRotateLeft :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
    sBarrelRotateLeft :: SBV a -> SBV b -> SBV a
    sBarrelRotateLeft = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV a
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svBarrelRotateLeft

    -- | Generalization of 'rotateR', when the shift-amount is symbolic. Since Haskell's
    -- 'rotateR' only takes an 'Int' as the shift amount, it cannot be used when we have
    -- a symbolic amount to shift with. The first argument should be a bounded quantity.
    sRotateRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a
    sRotateRight :: SBV a -> SBV b -> SBV a
    sRotateRight = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV a
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svRotateRight

    -- | An implementation of rotate-right, using a barrel shifter like design. See comments
    -- for `sBarrelRotateLeft` for details.
    --
    -- >>> prove $ \x y -> (x `sBarrelRotateRight` y) `sBarrelRotateLeft`  (y :: SWord32) .== (x :: SWord64)
    -- Q.E.D.
    sBarrelRotateRight :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
    sBarrelRotateRight :: SBV a -> SBV b -> SBV a
    sBarrelRotateRight = (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV a
    forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    svBarrelRotateRight

    -- Enum instance. These instances are suitable for use with concrete values,
    -- and will be less useful for symbolic values around. Note that `fromEnum` requires
    -- a concrete argument for obvious reasons. Other variants (succ, pred, [x..]) etc are similarly
    -- limited. While symbolic variants can be defined for many of these, they will just diverge
    -- as final sizes cannot be determined statically.
    instance (Show a, Bounded a, Integral a, Num a, SymVal a) => Enum (SBV a) where
      succ :: SBV a -> SBV a
    succ x :: SBV a
    x
        | a
    v a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == (a
    forall a. Bounded a => a
    maxBound :: a) = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "Enum.succ{" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. HasKind a => a -> String
    showType SBV a
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "}: tried to take `succ' of maxBound"
        | Bool
    True                 = a -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a -> SBV a) -> a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ a
    v a -> a -> a
    forall a. Num a => a -> a -> a
    + 1
        where v :: a
    v = String -> SBV a -> a
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "succ" SBV a
    x
      pred :: SBV a -> SBV a
    pred x :: SBV a
    x
        | a
    v a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == (a
    forall a. Bounded a => a
    minBound :: a) = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "Enum.pred{" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. HasKind a => a -> String
    showType SBV a
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "}: tried to take `pred' of minBound"
        | Bool
    True                 = a -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a -> SBV a) -> a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ a
    v a -> a -> a
    forall a. Num a => a -> a -> a
    - 1
        where v :: a
    v = String -> SBV a -> a
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "pred" SBV a
    x
      toEnum :: Int -> SBV a
    toEnum x :: Int
    x
        | Integer
    xi Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < a -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a
    forall a. Bounded a => a
    minBound :: a) Bool -> Bool -> Bool
    || Integer
    xi Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > a -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a
    forall a. Bounded a => a
    maxBound :: a)
        = String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "Enum.toEnum{" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. HasKind a => a -> String
    showType SBV a
    r String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "}: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " is out-of-bounds " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (a, a) -> String
    forall a. Show a => a -> String
    show (a
    forall a. Bounded a => a
    minBound :: a, a
    forall a. Bounded a => a
    maxBound :: a)
        | Bool
    True
        = SBV a
    r
        where xi :: Integer
              xi :: Integer
    xi = Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    x
              r  :: SBV a
              r :: SBV a
    r  = Int -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    x
      fromEnum :: SBV a -> Int
    fromEnum x :: SBV a
    x
         | Integer
    r Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    forall a. Bounded a => a
    minBound :: Int) Bool -> Bool -> Bool
    || Integer
    r Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    forall a. Bounded a => a
    maxBound :: Int)
         = String -> Int
    forall a. HasCallStack => String -> a
    error (String -> Int) -> String -> Int
    forall a b. (a -> b) -> a -> b
    $ "Enum.fromEnum{" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. HasKind a => a -> String
    showType SBV a
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "}:  value " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Integer -> String
    forall a. Show a => a -> String
    show Integer
    r String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " is outside of Int's bounds " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> String
    forall a. Show a => a -> String
    show (Int
    forall a. Bounded a => a
    minBound :: Int, Int
    forall a. Bounded a => a
    maxBound :: Int)
         | Bool
    True
         = Integer -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    r
        where r :: Integer
              r :: Integer
    r = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "fromEnum" SBV a
    x
      enumFrom :: SBV a -> [SBV a]
    enumFrom x :: SBV a
    x = (Integer -> SBV a) -> [Integer] -> [SBV a]
    forall a b. (a -> b) -> [a] -> [b]
    map Integer -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral [Integer
    xi .. a -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a
    forall a. Bounded a => a
    maxBound :: a)]
         where xi :: Integer
               xi :: Integer
    xi = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "enumFrom" SBV a
    x
      enumFromThen :: SBV a -> SBV a -> [SBV a]
    enumFromThen x :: SBV a
    x y :: SBV a
    y
         | Integer
    yi Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Integer
    xi  = (Integer -> SBV a) -> [Integer] -> [SBV a]
    forall a b. (a -> b) -> [a] -> [b]
    map Integer -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral [Integer
    xi, Integer
    yi .. a -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a
    forall a. Bounded a => a
    maxBound :: a)]
         | Bool
    True      = (Integer -> SBV a) -> [Integer] -> [SBV a]
    forall a b. (a -> b) -> [a] -> [b]
    map Integer -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral [Integer
    xi, Integer
    yi .. a -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (a
    forall a. Bounded a => a
    minBound :: a)]
           where xi, yi :: Integer
                 xi :: Integer
    xi = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "enumFromThen.x" SBV a
    x
                 yi :: Integer
    yi = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "enumFromThen.y" SBV a
    y
      enumFromThenTo :: SBV a -> SBV a -> SBV a -> [SBV a]
    enumFromThenTo x :: SBV a
    x y :: SBV a
    y z :: SBV a
    z = (Integer -> SBV a) -> [Integer] -> [SBV a]
    forall a b. (a -> b) -> [a] -> [b]
    map Integer -> SBV a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral [Integer
    xi, Integer
    yi .. Integer
    zi]
           where xi, yi, zi :: Integer
                 xi :: Integer
    xi = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "enumFromThenTo.x" SBV a
    x
                 yi :: Integer
    yi = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "enumFromThenTo.y" SBV a
    y
                 zi :: Integer
    zi = String -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt "enumFromThenTo.z" SBV a
    z

    -- | Helper function for use in enum operations
    enumCvt :: (SymVal a, Integral a, Num b) => String -> SBV a -> b
    enumCvt :: String -> SBV a -> b
    enumCvt w :: String
    w x :: SBV a
    x = case SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    x of
                    Nothing -> String -> b
    forall a. HasCallStack => String -> a
    error (String -> b) -> String -> b
    forall a b. (a -> b) -> a -> b
    $ "Enum." String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    w String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "{" String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. HasKind a => a -> String
    showType SBV a
    x String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "}: Called on symbolic value " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> String
    forall a. Show a => a -> String
    show SBV a
    x
                    Just v :: a
    v  -> a -> b
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    v

    -- | The 'SDivisible' class captures the essence of division.
    -- Unfortunately we cannot use Haskell's 'Integral' class since the 'Real'
    -- and 'Enum' superclasses are not implementable for symbolic bit-vectors.
    -- However, 'quotRem' and 'divMod' both make perfect sense, and the 'SDivisible' class captures
    -- this operation. One issue is how division by 0 behaves. The verification
    -- technology requires total functions, and there are several design choices
    -- here. We follow Isabelle/HOL approach of assigning the value 0 for division
    -- by 0. Therefore, we impose the following pair of laws:
    --
    -- @
    --      x `sQuotRem` 0 = (0, x)
    --      x `sDivMod`  0 = (0, x)
    -- @
    --
    -- Note that our instances implement this law even when @x@ is @0@ itself.
    --
    -- NB. 'quot' truncates toward zero, while 'div' truncates toward negative infinity.
    --
    -- === C code generation of division operations
    --
    -- In the case of division or modulo of a minimal signed value (e.g. @-128@ for
    -- 'SInt8') by @-1@, SMTLIB and Haskell agree on what the result should be.
    -- Unfortunately the result in C code depends on CPU architecture and compiler
    -- settings, as this is undefined behaviour in C.  **SBV does not guarantee**
    -- what will happen in generated C code in this corner case.
    class SDivisible a where
      sQuotRem :: a -> a -> (a, a)
      sDivMod  :: a -> a -> (a, a)
      sQuot    :: a -> a -> a
      sRem     :: a -> a -> a
      sDiv     :: a -> a -> a
      sMod     :: a -> a -> a

      {-# MINIMAL sQuotRem, sDivMod #-}

      x :: a
    x `sQuot` y :: a
    y = (a, a) -> a
    forall a b. (a, b) -> a
    fst ((a, a) -> a) -> (a, a) -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> a -> (a, a)
    forall a. SDivisible a => a -> a -> (a, a)
    `sQuotRem` a
    y
      x :: a
    x `sRem`  y :: a
    y = (a, a) -> a
    forall a b. (a, b) -> b
    snd ((a, a) -> a) -> (a, a) -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> a -> (a, a)
    forall a. SDivisible a => a -> a -> (a, a)
    `sQuotRem` a
    y
      x :: a
    x `sDiv`  y :: a
    y = (a, a) -> a
    forall a b. (a, b) -> a
    fst ((a, a) -> a) -> (a, a) -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> a -> (a, a)
    forall a. SDivisible a => a -> a -> (a, a)
    `sDivMod`  a
    y
      x :: a
    x `sMod`  y :: a
    y = (a, a) -> a
    forall a b. (a, b) -> b
    snd ((a, a) -> a) -> (a, a) -> a
    forall a b. (a -> b) -> a -> b
    $ a
    x a -> a -> (a, a)
    forall a. SDivisible a => a -> a -> (a, a)
    `sDivMod`  a
    y

    instance SDivisible Word64 where
      sQuotRem :: Word64 -> Word64 -> (Word64, Word64)
    sQuotRem x :: Word64
    x 0 = (0, Word64
    x)
      sQuotRem x :: Word64
    x y :: Word64
    y = Word64
    x Word64 -> Word64 -> (Word64, Word64)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Word64
    y
      sDivMod :: Word64 -> Word64 -> (Word64, Word64)
    sDivMod  x :: Word64
    x 0 = (0, Word64
    x)
      sDivMod  x :: Word64
    x y :: Word64
    y = Word64
    x Word64 -> Word64 -> (Word64, Word64)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Word64
    y

    instance SDivisible Int64 where
      sQuotRem :: Int64 -> Int64 -> (Int64, Int64)
    sQuotRem x :: Int64
    x 0 = (0, Int64
    x)
      sQuotRem x :: Int64
    x y :: Int64
    y = Int64
    x Int64 -> Int64 -> (Int64, Int64)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Int64
    y
      sDivMod :: Int64 -> Int64 -> (Int64, Int64)
    sDivMod  x :: Int64
    x 0 = (0, Int64
    x)
      sDivMod  x :: Int64
    x y :: Int64
    y = Int64
    x Int64 -> Int64 -> (Int64, Int64)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Int64
    y

    instance SDivisible Word32 where
      sQuotRem :: Word32 -> Word32 -> (Word32, Word32)
    sQuotRem x :: Word32
    x 0 = (0, Word32
    x)
      sQuotRem x :: Word32
    x y :: Word32
    y = Word32
    x Word32 -> Word32 -> (Word32, Word32)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Word32
    y
      sDivMod :: Word32 -> Word32 -> (Word32, Word32)
    sDivMod  x :: Word32
    x 0 = (0, Word32
    x)
      sDivMod  x :: Word32
    x y :: Word32
    y = Word32
    x Word32 -> Word32 -> (Word32, Word32)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Word32
    y

    instance SDivisible Int32 where
      sQuotRem :: Int32 -> Int32 -> (Int32, Int32)
    sQuotRem x :: Int32
    x 0 = (0, Int32
    x)
      sQuotRem x :: Int32
    x y :: Int32
    y = Int32
    x Int32 -> Int32 -> (Int32, Int32)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Int32
    y
      sDivMod :: Int32 -> Int32 -> (Int32, Int32)
    sDivMod  x :: Int32
    x 0 = (0, Int32
    x)
      sDivMod  x :: Int32
    x y :: Int32
    y = Int32
    x Int32 -> Int32 -> (Int32, Int32)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Int32
    y

    instance SDivisible Word16 where
      sQuotRem :: Word16 -> Word16 -> (Word16, Word16)
    sQuotRem x :: Word16
    x 0 = (0, Word16
    x)
      sQuotRem x :: Word16
    x y :: Word16
    y = Word16
    x Word16 -> Word16 -> (Word16, Word16)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Word16
    y
      sDivMod :: Word16 -> Word16 -> (Word16, Word16)
    sDivMod  x :: Word16
    x 0 = (0, Word16
    x)
      sDivMod  x :: Word16
    x y :: Word16
    y = Word16
    x Word16 -> Word16 -> (Word16, Word16)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Word16
    y

    instance SDivisible Int16 where
      sQuotRem :: Int16 -> Int16 -> (Int16, Int16)
    sQuotRem x :: Int16
    x 0 = (0, Int16
    x)
      sQuotRem x :: Int16
    x y :: Int16
    y = Int16
    x Int16 -> Int16 -> (Int16, Int16)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Int16
    y
      sDivMod :: Int16 -> Int16 -> (Int16, Int16)
    sDivMod  x :: Int16
    x 0 = (0, Int16
    x)
      sDivMod  x :: Int16
    x y :: Int16
    y = Int16
    x Int16 -> Int16 -> (Int16, Int16)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Int16
    y

    instance SDivisible Word8 where
      sQuotRem :: Word8 -> Word8 -> (Word8, Word8)
    sQuotRem x :: Word8
    x 0 = (0, Word8
    x)
      sQuotRem x :: Word8
    x y :: Word8
    y = Word8
    x Word8 -> Word8 -> (Word8, Word8)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Word8
    y
      sDivMod :: Word8 -> Word8 -> (Word8, Word8)
    sDivMod  x :: Word8
    x 0 = (0, Word8
    x)
      sDivMod  x :: Word8
    x y :: Word8
    y = Word8
    x Word8 -> Word8 -> (Word8, Word8)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Word8
    y

    instance SDivisible Int8 where
      sQuotRem :: Int8 -> Int8 -> (Int8, Int8)
    sQuotRem x :: Int8
    x 0 = (0, Int8
    x)
      sQuotRem x :: Int8
    x y :: Int8
    y = Int8
    x Int8 -> Int8 -> (Int8, Int8)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Int8
    y
      sDivMod :: Int8 -> Int8 -> (Int8, Int8)
    sDivMod  x :: Int8
    x 0 = (0, Int8
    x)
      sDivMod  x :: Int8
    x y :: Int8
    y = Int8
    x Int8 -> Int8 -> (Int8, Int8)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Int8
    y

    instance SDivisible Integer where
      sQuotRem :: Integer -> Integer -> (Integer, Integer)
    sQuotRem x :: Integer
    x 0 = (0, Integer
    x)
      sQuotRem x :: Integer
    x y :: Integer
    y = Integer
    x Integer -> Integer -> (Integer, Integer)
    forall a. Integral a => a -> a -> (a, a)
    `quotRem` Integer
    y
      sDivMod :: Integer -> Integer -> (Integer, Integer)
    sDivMod  x :: Integer
    x 0 = (0, Integer
    x)
      sDivMod  x :: Integer
    x y :: Integer
    y = Integer
    x Integer -> Integer -> (Integer, Integer)
    forall a. Integral a => a -> a -> (a, a)
    `divMod` Integer
    y

    instance SDivisible CV where
      sQuotRem :: CV -> CV -> (CV, CV)
    sQuotRem a :: CV
    a b :: CV
    b
        | CInteger x :: Integer
    x <- CV -> CVal
    cvVal CV
    a, CInteger y :: Integer
    y <- CV -> CVal
    cvVal CV
    b
        = let (r1 :: Integer
    r1, r2 :: Integer
    r2) = Integer -> Integer -> (Integer, Integer)
    forall a. SDivisible a => a -> a -> (a, a)
    sQuotRem Integer
    x Integer
    y in (CV -> CV
    normCV CV
    a{ cvVal :: CVal
    cvVal = Integer -> CVal
    CInteger Integer
    r1 }, CV -> CV
    normCV CV
    b{ cvVal :: CVal
    cvVal = Integer -> CVal
    CInteger Integer
    r2 })
      sQuotRem a :: CV
    a b :: CV
    b = String -> (CV, CV)
    forall a. HasCallStack => String -> a
    error (String -> (CV, CV)) -> String -> (CV, CV)
    forall a b. (a -> b) -> a -> b
    $ "SBV.sQuotRem: impossible, unexpected args received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (CV, CV) -> String
    forall a. Show a => a -> String
    show (CV
    a, CV
    b)
      sDivMod :: CV -> CV -> (CV, CV)
    sDivMod a :: CV
    a b :: CV
    b
        | CInteger x :: Integer
    x <- CV -> CVal
    cvVal CV
    a, CInteger y :: Integer
    y <- CV -> CVal
    cvVal CV
    b
        = let (r1 :: Integer
    r1, r2 :: Integer
    r2) = Integer -> Integer -> (Integer, Integer)
    forall a. SDivisible a => a -> a -> (a, a)
    sDivMod Integer
    x Integer
    y in (CV -> CV
    normCV CV
    a{ cvVal :: CVal
    cvVal = Integer -> CVal
    CInteger Integer
    r1 }, CV -> CV
    normCV CV
    b{ cvVal :: CVal
    cvVal = Integer -> CVal
    CInteger Integer
    r2 })
      sDivMod a :: CV
    a b :: CV
    b = String -> (CV, CV)
    forall a. HasCallStack => String -> a
    error (String -> (CV, CV)) -> String -> (CV, CV)
    forall a b. (a -> b) -> a -> b
    $ "SBV.sDivMod: impossible, unexpected args received: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (CV, CV) -> String
    forall a. Show a => a -> String
    show (CV
    a, CV
    b)

    instance SDivisible SWord64 where
      sQuotRem :: SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
    sQuotRem = SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
    sDivMod  = SBV Word64 -> SBV Word64 -> (SBV Word64, SBV Word64)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SInt64 where
      sQuotRem :: SBV Int64 -> SBV Int64 -> (SBV Int64, SBV Int64)
    sQuotRem = SBV Int64 -> SBV Int64 -> (SBV Int64, SBV Int64)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Int64 -> SBV Int64 -> (SBV Int64, SBV Int64)
    sDivMod  = SBV Int64 -> SBV Int64 -> (SBV Int64, SBV Int64)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SWord32 where
      sQuotRem :: SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
    sQuotRem = SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
    sDivMod  = SBV Word32 -> SBV Word32 -> (SBV Word32, SBV Word32)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SInt32 where
      sQuotRem :: SBV Int32 -> SBV Int32 -> (SBV Int32, SBV Int32)
    sQuotRem = SBV Int32 -> SBV Int32 -> (SBV Int32, SBV Int32)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Int32 -> SBV Int32 -> (SBV Int32, SBV Int32)
    sDivMod  = SBV Int32 -> SBV Int32 -> (SBV Int32, SBV Int32)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SWord16 where
      sQuotRem :: SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
    sQuotRem = SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
    sDivMod  = SBV Word16 -> SBV Word16 -> (SBV Word16, SBV Word16)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SInt16 where
      sQuotRem :: SBV Int16 -> SBV Int16 -> (SBV Int16, SBV Int16)
    sQuotRem = SBV Int16 -> SBV Int16 -> (SBV Int16, SBV Int16)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Int16 -> SBV Int16 -> (SBV Int16, SBV Int16)
    sDivMod  = SBV Int16 -> SBV Int16 -> (SBV Int16, SBV Int16)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SWord8 where
      sQuotRem :: SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
    sQuotRem = SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
    sDivMod  = SBV Word8 -> SBV Word8 -> (SBV Word8, SBV Word8)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    instance SDivisible SInt8 where
      sQuotRem :: SBV Int8 -> SBV Int8 -> (SBV Int8, SBV Int8)
    sQuotRem = SBV Int8 -> SBV Int8 -> (SBV Int8, SBV Int8)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem
      sDivMod :: SBV Int8 -> SBV Int8 -> (SBV Int8, SBV Int8)
    sDivMod  = SBV Int8 -> SBV Int8 -> (SBV Int8, SBV Int8)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod

    -- | Lift 'quotRem' to symbolic words. Division by 0 is defined s.t. @x/0 = 0@; which
    -- holds even when @x@ is @0@ itself.
    liftQRem :: (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem :: SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem x :: SBV a
    x y :: SBV a
    y
      | SBV a -> Bool
    forall a. SBV a -> Bool
    isConcreteZero SBV a
    x
      = (SBV a
    x, SBV a
    x)
      | SBV a -> Bool
    forall a. SBV a -> Bool
    isConcreteOne SBV a
    y
      = (SBV a
    x, SBV a
    z)
    {-------------------------------
     - N.B. The seemingly innocuous variant when y == -1 only holds if the type is signed;
     - and also is problematic around the minBound.. So, we refrain from that optimization
      | isConcreteOnes y
      = (-x, z)
    --------------------------------}
      | Bool
    True
      = SBV Bool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    y SBV a -> SBV a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a
    z) (SBV a
    z, SBV a
    x) (SBV a -> SBV a -> (SBV a, SBV a)
    forall a a a a. SBV a -> SBV a -> (SBV a, SBV a)
    qr SBV a
    x SBV a
    y)
      where qr :: SBV a -> SBV a -> (SBV a, SBV a)
    qr (SBV (SVal sgnsz :: Kind
    sgnsz (Left a :: CV
    a))) (SBV (SVal _ (Left b :: CV
    b))) = let (q :: CV
    q, r :: CV
    r) = CV -> CV -> (CV, CV)
    forall a. SDivisible a => a -> a -> (a, a)
    sQuotRem CV
    a CV
    b in (SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    sgnsz (CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left CV
    q)), SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    sgnsz (CV -> Either CV (Cached SV)
    forall a b. a -> Either a b
    Left CV
    r)))
            qr a :: SBV a
    a@(SBV (SVal sgnsz :: Kind
    sgnsz _))      b :: SBV a
    b                       = (SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    sgnsz (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache (Op -> State -> IO SV
    mk Op
    Quot)))), SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    sgnsz (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache (Op -> State -> IO SV
    mk Op
    Rem)))))
                    where mk :: Op -> State -> IO SV
    mk o :: Op
    o st :: State
    st = do SV
    sw1 <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    a
                                       SV
    sw2 <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    b
                                       Op -> State -> Kind -> SV -> SV -> IO SV
    mkSymOp Op
    o State
    st Kind
    sgnsz SV
    sw1 SV
    sw2
            z :: SBV a
    z = Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (0::Integer)

    -- | Lift 'divMod' to symbolic words. Division by 0 is defined s.t. @x/0 = 0@; which
    -- holds even when @x@ is @0@ itself. Essentially, this is conversion from quotRem
    -- (truncate to 0) to divMod (truncate towards negative infinity)
    liftDMod :: (Ord a, SymVal a, Num a, SDivisible (SBV a)) => SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod :: SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod x :: SBV a
    x y :: SBV a
    y
      | SBV a -> Bool
    forall a. SBV a -> Bool
    isConcreteZero SBV a
    x
      = (SBV a
    x, SBV a
    x)
      | SBV a -> Bool
    forall a. SBV a -> Bool
    isConcreteOne SBV a
    y
      = (SBV a
    x, SBV a
    z)
    {-------------------------------
     - N.B. The seemingly innocuous variant when y == -1 only holds if the type is signed;
     - and also is problematic around the minBound.. So, we refrain from that optimization
      | isConcreteOnes y
      = (-x, z)
    --------------------------------}
      | Bool
    True
      = SBV Bool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a
    y SBV a -> SBV a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a
    z) (SBV a
    z, SBV a
    x) ((SBV a, SBV a) -> (SBV a, SBV a))
    -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a b. (a -> b) -> a -> b
    $ SBV Bool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV a -> SBV a
    forall a. Num a => a -> a
    signum SBV a
    r SBV a -> SBV a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV a
    forall a. Num a => a -> a
    negate (SBV a -> SBV a
    forall a. Num a => a -> a
    signum SBV a
    y)) (SBV a
    qSBV a -> SBV a -> SBV a
    forall a. Num a => a -> a -> a
    -SBV a
    i, SBV a
    rSBV a -> SBV a -> SBV a
    forall a. Num a => a -> a -> a
    +SBV a
    y) (SBV a, SBV a)
    qr
     where qr :: (SBV a, SBV a)
    qr@(q :: SBV a
    q, r :: SBV a
    r) = SBV a
    x SBV a -> SBV a -> (SBV a, SBV a)
    forall a. SDivisible a => a -> a -> (a, a)
    `sQuotRem` SBV a
    y
           z :: SBV a
    z = Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (0::Integer)
           i :: SBV a
    i = Kind -> Integer -> SBV a
    forall a b. Integral a => Kind -> a -> SBV b
    genLiteral (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (1::Integer)

    -- SInteger instance for quotRem/divMod are tricky!
    -- SMT-Lib only has Euclidean operations, but Haskell
    -- uses "truncate to 0" for quotRem, and "truncate to negative infinity" for divMod.
    -- So, we cannot just use the above liftings directly.
    instance SDivisible SInteger where
      sDivMod :: SBV Integer -> SBV Integer -> (SBV Integer, SBV Integer)
    sDivMod = SBV Integer -> SBV Integer -> (SBV Integer, SBV Integer)
    forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod
      sQuotRem :: SBV Integer -> SBV Integer -> (SBV Integer, SBV Integer)
    sQuotRem x :: SBV Integer
    x y :: SBV Integer
    y
        | Bool -> Bool
    not (SBV Integer -> Bool
    forall a. SymVal a => SBV a -> Bool
    isSymbolic SBV Integer
    x Bool -> Bool -> Bool
    || SBV Integer -> Bool
    forall a. SymVal a => SBV a -> Bool
    isSymbolic SBV Integer
    y)
        = SBV Integer -> SBV Integer -> (SBV Integer, SBV Integer)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem SBV Integer
    x SBV Integer
    y
        | Bool
    True
        = SBV Bool
    -> (SBV Integer, SBV Integer)
    -> (SBV Integer, SBV Integer)
    -> (SBV Integer, SBV Integer)
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV Integer
    y SBV Integer -> SBV Integer -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== 0) (0, SBV Integer
    x) (SBV Integer
    qESBV Integer -> SBV Integer -> SBV Integer
    forall a. Num a => a -> a -> a
    +SBV Integer
    i, SBV Integer
    rESBV Integer -> SBV Integer -> SBV Integer
    forall a. Num a => a -> a -> a
    -SBV Integer
    iSBV Integer -> SBV Integer -> SBV Integer
    forall a. Num a => a -> a -> a
    *SBV Integer
    y)
        where (qE :: SBV Integer
    qE, rE :: SBV Integer
    rE) = SBV Integer -> SBV Integer -> (SBV Integer, SBV Integer)
    forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem SBV Integer
    x SBV Integer
    y   -- for integers, this is euclidean due to SMTLib semantics
              i :: SBV Integer
    i = SBV Bool -> SBV Integer -> SBV Integer -> SBV Integer
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV Integer
    x SBV Integer -> SBV Integer -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .>= 0 SBV Bool -> SBV Bool -> SBV Bool
    .|| SBV Integer
    rE SBV Integer -> SBV Integer -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== 0) 0
                (SBV Integer -> SBV Integer) -> SBV Integer -> SBV Integer
    forall a b. (a -> b) -> a -> b
    $ SBV Bool -> SBV Integer -> SBV Integer -> SBV Integer
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV Integer
    y SBV Integer -> SBV Integer -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .>  0)              1 (-1)

    -- Quickcheck interface
    instance (SymVal a, Arbitrary a) => Arbitrary (SBV a) where
      arbitrary :: Gen (SBV a)
    arbitrary = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal (a -> SBV a) -> Gen a -> Gen (SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Gen a
    forall a. Arbitrary a => Gen a
    arbitrary

    -- |  Symbolic conditionals are modeled by the 'Mergeable' class, describing
    -- how to merge the results of an if-then-else call with a symbolic test. SBV
    -- provides all basic types as instances of this class, so users only need
    -- to declare instances for custom data-types of their programs as needed.
    --
    -- A 'Mergeable' instance may be automatically derived for a custom data-type
    -- with a single constructor where the type of each field is an instance of
    -- 'Mergeable', such as a record of symbolic values. Users only need to add
    -- 'G.Generic' and 'Mergeable' to the @deriving@ clause for the data-type. See
    -- 'Documentation.SBV.Examples.Puzzles.U2Bridge.Status' for an example and an
    -- illustration of what the instance would look like if written by hand.
    --
    -- The function 'select' is a total-indexing function out of a list of choices
    -- with a default value, simulating array/list indexing. It's an n-way generalization
    -- of the 'ite' function.
    --
    -- Minimal complete definition: None, if the type is instance of @Generic@. Otherwise
    -- 'symbolicMerge'. Note that most types subject to merging are likely to be
    -- trivial instances of @Generic@.
    class Mergeable a where
       -- | Merge two values based on the condition. The first argument states
       -- whether we force the then-and-else branches before the merging, at the
       -- word level. This is an efficiency concern; one that we'd rather not
       -- make but unfortunately necessary for getting symbolic simulation
       -- working efficiently.
       symbolicMerge :: Bool -> SBool -> a -> a -> a
       -- | Total indexing operation. @select xs default index@ is intuitively
       -- the same as @xs !! index@, except it evaluates to @default@ if @index@
       -- underflows/overflows.
       select :: (Ord b, SymVal b, Num b) => [a] -> a -> SBV b -> a
       -- NB. Earlier implementation of select used the binary-search trick
       -- on the index to chop down the search space. While that is a good trick
       -- in general, it doesn't work for SBV since we do not have any notion of
       -- "concrete" subwords: If an index is symbolic, then all its bits are
       -- symbolic as well. So, the binary search only pays off only if the indexed
       -- list is really humongous, which is not very common in general. (Also,
       -- for the case when the list is bit-vectors, we use SMT tables anyhow.)
       select xs :: [a]
    xs err :: a
    err ind :: SBV b
    ind
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    isReal   SBV b
    ind = String -> a
    forall a. String -> a
    bad "real"
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    isFloat  SBV b
    ind = String -> a
    forall a. String -> a
    bad "float"
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    isDouble SBV b
    ind = String -> a
    forall a. String -> a
    bad "double"
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    hasSign  SBV b
    ind = SBV Bool -> a -> a -> a
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (SBV b
    ind SBV b -> SBV b -> SBV Bool
    forall a. OrdSymbolic a => a -> a -> SBV Bool
    .< 0) a
    err ([a] -> SBV b -> a -> a
    forall a t.
    (Num a, Mergeable t, EqSymbolic a) =>
    [t] -> a -> t -> t
    walk [a]
    xs SBV b
    ind a
    err)
        | Bool
    True         =                     [a] -> SBV b -> a -> a
    forall a t.
    (Num a, Mergeable t, EqSymbolic a) =>
    [t] -> a -> t -> t
    walk [a]
    xs SBV b
    ind a
    err
        where bad :: String -> a
    bad w :: String
    w = String -> a
    forall a. HasCallStack => String -> a
    error (String -> a) -> String -> a
    forall a b. (a -> b) -> a -> b
    $ "SBV.select: unsupported " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    w String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " valued select/index expression"
              walk :: [t] -> a -> t -> t
    walk []     _ acc :: t
    acc = t
    acc
              walk (e :: t
    e:es :: [t]
    es) i :: a
    i acc :: t
    acc = [t] -> a -> t -> t
    walk [t]
    es (a
    ia -> a -> a
    forall a. Num a => a -> a -> a
    -1) (SBV Bool -> t -> t -> t
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite (a
    i a -> a -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== 0) t
    e t
    acc)

       -- Default implementation for 'symbolicMerge' if the type is 'Generic'
       default symbolicMerge :: (G.Generic a, GMergeable (G.Rep a)) => Bool -> SBool -> a -> a -> a
       symbolicMerge = Bool -> SBV Bool -> a -> a -> a
    forall a.
    (Generic a, GMergeable (Rep a)) =>
    Bool -> SBV Bool -> a -> a -> a
    symbolicMergeDefault

    -- | If-then-else. This is by definition 'symbolicMerge' with both
    -- branches forced. This is typically the desired behavior, but also
    -- see 'iteLazy' should you need more laziness.
    ite :: Mergeable a => SBool -> a -> a -> a
    ite :: SBV Bool -> a -> a -> a
    ite t :: SBV Bool
    t a :: a
    a b :: a
    b
      | Just r :: Bool
    r <- SBV Bool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV Bool
    t = if Bool
    r then a
    a else a
    b
      | Bool
    True                  = Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    True SBV Bool
    t a
    a a
    b

    -- | A Lazy version of ite, which does not force its arguments. This might
    -- cause issues for symbolic simulation with large thunks around, so use with
    -- care.
    iteLazy :: Mergeable a => SBool -> a -> a -> a
    iteLazy :: SBV Bool -> a -> a -> a
    iteLazy t :: SBV Bool
    t a :: a
    a b :: a
    b
      | Just r :: Bool
    r <- SBV Bool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV Bool
    t = if Bool
    r then a
    a else a
    b
      | Bool
    True                  = Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    False SBV Bool
    t a
    a a
    b

    -- | Symbolic assert. Check that the given boolean condition is always 'sTrue' in the given path. The
    -- optional first argument can be used to provide call-stack info via GHC's location facilities.
    sAssert :: HasKind a => Maybe CallStack -> String -> SBool -> SBV a -> SBV a
    sAssert :: Maybe CallStack -> String -> SBV Bool -> SBV a -> SBV a
    sAssert cs :: Maybe CallStack
    cs msg :: String
    msg cond :: SBV Bool
    cond x :: SBV a
    x
       | Just mustHold :: Bool
    mustHold <- SBV Bool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV Bool
    cond
       = if Bool
    mustHold
         then SBV a
    x
         else String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ SafeResult -> String
    forall a. Show a => a -> String
    show (SafeResult -> String) -> SafeResult -> String
    forall a b. (a -> b) -> a -> b
    $ (Maybe String, String, SMTResult) -> SafeResult
    SafeResult (([(String, SrcLoc)] -> String
    locInfo ([(String, SrcLoc)] -> String)
    -> (CallStack -> [(String, SrcLoc)]) -> CallStack -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CallStack -> [(String, SrcLoc)]
    getCallStack) (CallStack -> String) -> Maybe CallStack -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe CallStack
    cs, String
    msg, SMTConfig -> SMTModel -> SMTResult
    Satisfiable SMTConfig
    defaultSMTCfg ([(String, GeneralizedCV)]
    -> Maybe [((Quantifier, NamedSymVar), Maybe CV)]
    -> [(String, CV)]
    -> [(String, (SBVType, ([([CV], CV)], CV)))]
    -> SMTModel
    SMTModel [] Maybe [((Quantifier, NamedSymVar), Maybe CV)]
    forall a. Maybe a
    Nothing [] []))
       | Bool
    True
       = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r
      where k :: Kind
    k     = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x
            r :: State -> IO SV
    r st :: State
    st  = do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                       let pc :: SBV Bool
    pc = State -> SBV Bool
    getPathCondition State
    st
                           -- We're checking if there are any cases where the path-condition holds, but not the condition
                           -- Any violations of this, should be signaled, i.e., whenever the following formula is satisfiable
                           mustNeverHappen :: SBV Bool
    mustNeverHappen = SBV Bool
    pc SBV Bool -> SBV Bool -> SBV Bool
    .&& SBV Bool -> SBV Bool
    sNot SBV Bool
    cond
                       SV
    cnd <- State -> SBV Bool -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV Bool
    mustNeverHappen
                       State -> Maybe CallStack -> String -> SV -> IO ()
    addAssertion State
    st Maybe CallStack
    cs String
    msg SV
    cnd
                       SV -> IO SV
    forall (m :: * -> *) a. Monad m => a -> m a
    return SV
    xsv

            locInfo :: [(String, SrcLoc)] -> String
    locInfo ps :: [(String, SrcLoc)]
    ps = String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate ",\n " (((String, SrcLoc) -> String) -> [(String, SrcLoc)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, SrcLoc) -> String
    loc [(String, SrcLoc)]
    ps)
              where loc :: (String, SrcLoc) -> String
    loc (f :: String
    f, sl :: SrcLoc
    sl) = [String] -> String
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [SrcLoc -> String
    srcLocFile SrcLoc
    sl, ":", Int -> String
    forall a. Show a => a -> String
    show (SrcLoc -> Int
    srcLocStartLine SrcLoc
    sl), ":", Int -> String
    forall a. Show a => a -> String
    show (SrcLoc -> Int
    srcLocStartCol SrcLoc
    sl), ":", String
    f]

    -- | Merge two symbolic values, at kind @k@, possibly @force@'ing the branches to make
    -- sure they do not evaluate to the same result. This should only be used for internal purposes;
    -- as default definitions provided should suffice in many cases. (i.e., End users should
    -- only need to define 'symbolicMerge' when needed; which should be rare to start with.)
    symbolicMergeWithKind :: Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind :: Kind -> Bool -> SBV Bool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind k :: Kind
    k force :: Bool
    force (SBV t :: SVal
    t) (SBV a :: SVal
    a) (SBV b :: SVal
    b) = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (Kind -> Bool -> SVal -> SVal -> SVal -> SVal
    svSymbolicMerge Kind
    k Bool
    force SVal
    t SVal
    a SVal
    b)

    instance SymVal a => Mergeable (SBV a) where
        symbolicMerge :: Bool -> SBV Bool -> SBV a -> SBV a -> SBV a
    symbolicMerge force :: Bool
    force t :: SBV Bool
    t x :: SBV a
    x y :: SBV a
    y
        -- Carefully use the kindOf instance to avoid strictness issues.
           | Bool
    force = Kind -> Bool -> SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Kind -> Bool -> SBV Bool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x)          Bool
    True  SBV Bool
    t SBV a
    x SBV a
    y
           | Bool
    True  = Kind -> Bool -> SBV Bool -> SBV a -> SBV a -> SBV a
    forall a. Kind -> Bool -> SBV Bool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)) Bool
    False SBV Bool
    t SBV a
    x SBV a
    y
        -- Custom version of select that translates to SMT-Lib tables at the base type of words
        select :: [SBV a] -> SBV a -> SBV b -> SBV a
    select xs :: [SBV a]
    xs err :: SBV a
    err ind :: SBV b
    ind
          | SBV (SVal _ (Left c :: CV
    c)) <- SBV b
    ind = case CV -> CVal
    cvVal CV
    c of
                                             CInteger i :: Integer
    i -> if Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 Bool -> Bool -> Bool
    || Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= [SBV a] -> Integer
    forall i a. Num i => [a] -> i
    genericLength [SBV a]
    xs
                                                           then SBV a
    err
                                                           else [SBV a]
    xs [SBV a] -> Integer -> SBV a
    forall i a. Integral i => [a] -> i -> a
    `genericIndex` Integer
    i
                                             _          -> String -> SBV a
    forall a. HasCallStack => String -> a
    error (String -> SBV a) -> String -> SBV a
    forall a b. (a -> b) -> a -> b
    $ "SBV.select: unsupported " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show (SBV b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV b
    ind) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " valued select/index expression"
        select xsOrig :: [SBV a]
    xsOrig err :: SBV a
    err ind :: SBV b
    ind = [SBV a]
    xs [SBV a] -> SBV a -> SBV a
    forall a b. a -> b -> b
    `seq` SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    kElt (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r)))
          where kInd :: Kind
    kInd = SBV b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV b
    ind
                kElt :: Kind
    kElt = SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    err
                -- Based on the index size, we need to limit the elements. For instance if the index is 8 bits, but there
                -- are 257 elements, that last element will never be used and we can chop it of..
                xs :: [SBV a]
    xs   = case SBV b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV b
    ind of
                         KBounded False i :: Int
    i -> Integer -> [SBV a] -> [SBV a]
    forall i a. Integral i => i -> [a] -> [a]
    genericTake ((2::Integer) Integer -> Integer -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    ^ (Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Int
    i     :: Integer)) [SBV a]
    xsOrig
                         KBounded True  i :: Int
    i -> Integer -> [SBV a] -> [SBV a]
    forall i a. Integral i => i -> [a] -> [a]
    genericTake ((2::Integer) Integer -> Integer -> Integer
    forall a b. (Num a, Integral b) => a -> b -> a
    ^ (Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -1) :: Integer)) [SBV a]
    xsOrig
                         KUnbounded       -> [SBV a]
    xsOrig
                         _                -> String -> [SBV a]
    forall a. HasCallStack => String -> a
    error (String -> [SBV a]) -> String -> [SBV a]
    forall a b. (a -> b) -> a -> b
    $ "SBV.select: unsupported " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Kind -> String
    forall a. Show a => a -> String
    show (SBV b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV b
    ind) String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " valued select/index expression"
                r :: State -> IO SV
    r st :: State
    st  = do [SV]
    sws <- (SBV a -> IO SV) -> [SBV a] -> IO [SV]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    mapM (State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st) [SBV a]
    xs
                           SV
    swe <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    err
                           if (SV -> Bool) -> [SV] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all (SV -> SV -> Bool
    forall a. Eq a => a -> a -> Bool
    == SV
    swe) [SV]
    sws  -- off-chance that all elts are the same. Note that this also correctly covers the case when list is empty.
                              then SV -> IO SV
    forall (m :: * -> *) a. Monad m => a -> m a
    return SV
    swe
                              else do Int
    idx <- State -> Kind -> Kind -> [SV] -> IO Int
    getTableIndex State
    st Kind
    kInd Kind
    kElt [SV]
    sws
                                      SV
    swi <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    ind
                                      let len :: Int
    len = [SBV a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBV a]
    xs
                                      -- NB. No need to worry here that the index might be < 0; as the SMTLib translation takes care of that automatically
                                      State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    kElt (Op -> [SV] -> SBVExpr
    SBVApp ((Int, Kind, Kind, Int) -> SV -> SV -> Op
    LkUp (Int
    idx, Kind
    kInd, Kind
    kElt, Int
    len) SV
    swi SV
    swe) [])

    -- Unit
    instance Mergeable () where
       symbolicMerge :: Bool -> SBV Bool -> () -> () -> ()
    symbolicMerge _ _ _ _ = ()
       select :: [()] -> () -> SBV b -> ()
    select _ _ _ = ()

    -- | Construct a useful error message if we hit an unmergeable case.
    cannotMerge :: String -> String -> String -> a
    cannotMerge :: String -> String -> String -> a
    cannotMerge typ :: String
    typ why :: String
    why hint :: String
    hint = String -> a
    forall a. HasCallStack => String -> a
    error (String -> a) -> String -> a
    forall a b. (a -> b) -> a -> b
    $ [String] -> String
    unlines [ ""
                                               , "*** Data.SBV.Mergeable: Cannot merge instances of " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    typ String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ "."
                                               , "*** While trying to do a symbolic if-then-else with incompatible branch results."
                                               , "***"
                                               , "*** " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    why
                                               , "*** "
                                               , "*** Hint: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    hint
                                               ]

    -- Mergeable instances for List/Maybe/Either/Array are useful, but can
    -- throw exceptions if there is no structural matching of the results
    -- It's a question whether we should really keep them..

    -- Lists
    instance Mergeable a => Mergeable [a] where
      symbolicMerge :: Bool -> SBV Bool -> [a] -> [a] -> [a]
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t xs :: [a]
    xs ys :: [a]
    ys
        | Int
    lxs Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    lys = (a -> a -> a) -> [a] -> [a] -> [a]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t) [a]
    xs [a]
    ys
        | Bool
    True       = String -> String -> String -> [a]
    forall a. String -> String -> String -> a
    cannotMerge "lists"
                                   ("Branches produce different sizes: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    lxs String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " vs " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    lys String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ ". Must have the same length.")
                                   "Use the 'SList' type (and Data.SBV.List routines) to model fully symbolic lists."
        where (lxs :: Int
    lxs, lys :: Int
    lys) = ([a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    xs, [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [a]
    ys)

    -- ZipList
    instance Mergeable a => Mergeable (ZipList a) where
      symbolicMerge :: Bool -> SBV Bool -> ZipList a -> ZipList a -> ZipList a
    symbolicMerge force :: Bool
    force test :: SBV Bool
    test (ZipList xs :: [a]
    xs) (ZipList ys :: [a]
    ys)
        = [a] -> ZipList a
    forall a. [a] -> ZipList a
    ZipList (Bool -> SBV Bool -> [a] -> [a] -> [a]
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    force SBV Bool
    test [a]
    xs [a]
    ys)

    -- Maybe
    instance Mergeable a => Mergeable (Maybe a) where
      symbolicMerge :: Bool -> SBV Bool -> Maybe a -> Maybe a -> Maybe a
    symbolicMerge _ _ Nothing  Nothing  = Maybe a
    forall a. Maybe a
    Nothing
      symbolicMerge f :: Bool
    f t :: SBV Bool
    t (Just a :: a
    a) (Just b :: a
    b) = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    a a
    b
      symbolicMerge _ _ a :: Maybe a
    a b :: Maybe a
    b = String -> String -> String -> Maybe a
    forall a. String -> String -> String -> a
    cannotMerge "'Maybe' values"
                                          ("Branches produce different constructors: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (String, String) -> String
    forall a. Show a => a -> String
    show (Maybe a -> String
    forall a. Maybe a -> String
    k Maybe a
    a, Maybe a -> String
    forall a. Maybe a -> String
    k Maybe a
    b))
                                          "Instead of an option type, try using a valid bit to indicate when a result is valid."
          where k :: Maybe a -> String
    k Nothing = "Nothing"
                k _       = "Just"

    -- Either
    instance (Mergeable a, Mergeable b) => Mergeable (Either a b) where
      symbolicMerge :: Bool -> SBV Bool -> Either a b -> Either a b -> Either a b
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (Left a :: a
    a)  (Left b :: a
    b)  = a -> Either a b
    forall a b. a -> Either a b
    Left  (a -> Either a b) -> a -> Either a b
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    a a
    b
      symbolicMerge f :: Bool
    f t :: SBV Bool
    t (Right a :: b
    a) (Right b :: b
    b) = b -> Either a b
    forall a b. b -> Either a b
    Right (b -> Either a b) -> b -> Either a b
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    a b
    b
      symbolicMerge _ _ a :: Either a b
    a b :: Either a b
    b = String -> String -> String -> Either a b
    forall a. String -> String -> String -> a
    cannotMerge "'Either' values"
                                          ("Branches produce different constructors: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (String, String) -> String
    forall a. Show a => a -> String
    show (Either a b -> String
    forall a b. Either a b -> String
    k Either a b
    a, Either a b -> String
    forall a b. Either a b -> String
    k Either a b
    b))
                                          "Consider using a product type by a tag instead."
         where k :: Either a b -> String
    k (Left _)  = "Left"
               k (Right _) = "Right"

    -- Arrays
    instance (Ix a, Mergeable b) => Mergeable (Array a b) where
      symbolicMerge :: Bool -> SBV Bool -> Array a b -> Array a b -> Array a b
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t a :: Array a b
    a b :: Array a b
    b
        | (a, a)
    ba (a, a) -> (a, a) -> Bool
    forall a. Eq a => a -> a -> Bool
    == (a, a)
    bb = (a, a) -> [b] -> Array a b
    forall i e. Ix i => (i, i) -> [e] -> Array i e
    listArray (a, a)
    ba ((b -> b -> b) -> [b] -> [b] -> [b]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t) (Array a b -> [b]
    forall i e. Array i e -> [e]
    elems Array a b
    a) (Array a b -> [b]
    forall i e. Array i e -> [e]
    elems Array a b
    b))
        | Bool
    True     = String -> String -> String -> Array a b
    forall a. String -> String -> String -> a
    cannotMerge "'Array' values"
                                 ("Branches produce different ranges: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> String
    forall a. Show a => a -> String
    show ((a, a) -> Int
    k (a, a)
    ba, (a, a) -> Int
    k (a, a)
    bb))
                                 "Consider using SBV's native arrays 'SArray' and 'SFunArray' instead."
        where [ba :: (a, a)
    ba, bb :: (a, a)
    bb] = (Array a b -> (a, a)) -> [Array a b] -> [(a, a)]
    forall a b. (a -> b) -> [a] -> [b]
    map Array a b -> (a, a)
    forall i e. Array i e -> (i, i)
    bounds [Array a b
    a, Array a b
    b]
              k :: (a, a) -> Int
    k = (a, a) -> Int
    forall a. Ix a => (a, a) -> Int
    rangeSize

    -- Functions
    instance Mergeable b => Mergeable (a -> b) where
      symbolicMerge :: Bool -> SBV Bool -> (a -> b) -> (a -> b) -> a -> b
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t g :: a -> b
    g h :: a -> b
    h x :: a
    x = Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t (a -> b
    g a
    x) (a -> b
    h a
    x)
      {- Following definition, while correct, is utterly inefficient. Since the
         application is delayed, this hangs on to the inner list and all the
         impending merges, even when ind is concrete. Thus, it's much better to
         simply use the default definition for the function case.
      -}
      -- select xs err ind = \x -> select (map ($ x) xs) (err x) ind

    -- 2-Tuple
    instance (Mergeable a, Mergeable b) => Mergeable (a, b) where
      symbolicMerge :: Bool -> SBV Bool -> (a, b) -> (a, b) -> (a, b)
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (i0 :: a
    i0, i1 :: b
    i1) (j0 :: a
    j0, j1 :: b
    j1) = ( Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    i0 a
    j0
                                            , Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    i1 b
    j1
                                            )

      select :: [(a, b)] -> (a, b) -> SBV b -> (a, b)
    select xs :: [(a, b)]
    xs (err1 :: a
    err1, err2 :: b
    err2) ind :: SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [a]
    as a
    err1 SBV b
    ind
                                   , [b] -> b -> SBV b -> b
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [b]
    bs b
    err2 SBV b
    ind
                                   )
        where (as :: [a]
    as, bs :: [b]
    bs) = [(a, b)] -> ([a], [b])
    forall a b. [(a, b)] -> ([a], [b])
    unzip [(a, b)]
    xs

    -- 3-Tuple
    instance (Mergeable a, Mergeable b, Mergeable c) => Mergeable (a, b, c) where
      symbolicMerge :: Bool -> SBV Bool -> (a, b, c) -> (a, b, c) -> (a, b, c)
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (i0 :: a
    i0, i1 :: b
    i1, i2 :: c
    i2) (j0 :: a
    j0, j1 :: b
    j1, j2 :: c
    j2) = ( Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    i0 a
    j0
                                                    , Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    i1 b
    j1
                                                    , Bool -> SBV Bool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t c
    i2 c
    j2
                                                    )

      select :: [(a, b, c)] -> (a, b, c) -> SBV b -> (a, b, c)
    select xs :: [(a, b, c)]
    xs (err1 :: a
    err1, err2 :: b
    err2, err3 :: c
    err3) ind :: SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [a]
    as a
    err1 SBV b
    ind
                                         , [b] -> b -> SBV b -> b
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [b]
    bs b
    err2 SBV b
    ind
                                         , [c] -> c -> SBV b -> c
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [c]
    cs c
    err3 SBV b
    ind
                                         )

        where (as :: [a]
    as, bs :: [b]
    bs, cs :: [c]
    cs) = [(a, b, c)] -> ([a], [b], [c])
    forall a b c. [(a, b, c)] -> ([a], [b], [c])
    unzip3 [(a, b, c)]
    xs

    -- 4-Tuple
    instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d) => Mergeable (a, b, c, d) where
      symbolicMerge :: Bool -> SBV Bool -> (a, b, c, d) -> (a, b, c, d) -> (a, b, c, d)
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (i0 :: a
    i0, i1 :: b
    i1, i2 :: c
    i2, i3 :: d
    i3) (j0 :: a
    j0, j1 :: b
    j1, j2 :: c
    j2, j3 :: d
    j3) = ( Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    i0 a
    j0
                                                            , Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    i1 b
    j1
                                                            , Bool -> SBV Bool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t c
    i2 c
    j2
                                                            , Bool -> SBV Bool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t d
    i3 d
    j3
                                                            )

      select :: [(a, b, c, d)] -> (a, b, c, d) -> SBV b -> (a, b, c, d)
    select xs :: [(a, b, c, d)]
    xs (err1 :: a
    err1, err2 :: b
    err2, err3 :: c
    err3, err4 :: d
    err4) ind :: SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [a]
    as a
    err1 SBV b
    ind
                                               , [b] -> b -> SBV b -> b
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [b]
    bs b
    err2 SBV b
    ind
                                               , [c] -> c -> SBV b -> c
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [c]
    cs c
    err3 SBV b
    ind
                                               , [d] -> d -> SBV b -> d
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [d]
    ds d
    err4 SBV b
    ind
                                               )
        where (as :: [a]
    as, bs :: [b]
    bs, cs :: [c]
    cs, ds :: [d]
    ds) = [(a, b, c, d)] -> ([a], [b], [c], [d])
    forall a b c d. [(a, b, c, d)] -> ([a], [b], [c], [d])
    unzip4 [(a, b, c, d)]
    xs

    -- 5-Tuple
    instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e) => Mergeable (a, b, c, d, e) where
      symbolicMerge :: Bool
    -> SBV Bool
    -> (a, b, c, d, e)
    -> (a, b, c, d, e)
    -> (a, b, c, d, e)
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (i0 :: a
    i0, i1 :: b
    i1, i2 :: c
    i2, i3 :: d
    i3, i4 :: e
    i4) (j0 :: a
    j0, j1 :: b
    j1, j2 :: c
    j2, j3 :: d
    j3, j4 :: e
    j4) = ( Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    i0 a
    j0
                                                                    , Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    i1 b
    j1
                                                                    , Bool -> SBV Bool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t c
    i2 c
    j2
                                                                    , Bool -> SBV Bool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t d
    i3 d
    j3
                                                                    , Bool -> SBV Bool -> e -> e -> e
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t e
    i4 e
    j4
                                                                    )

      select :: [(a, b, c, d, e)] -> (a, b, c, d, e) -> SBV b -> (a, b, c, d, e)
    select xs :: [(a, b, c, d, e)]
    xs (err1 :: a
    err1, err2 :: b
    err2, err3 :: c
    err3, err4 :: d
    err4, err5 :: e
    err5) ind :: SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [a]
    as a
    err1 SBV b
    ind
                                                     , [b] -> b -> SBV b -> b
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [b]
    bs b
    err2 SBV b
    ind
                                                     , [c] -> c -> SBV b -> c
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [c]
    cs c
    err3 SBV b
    ind
                                                     , [d] -> d -> SBV b -> d
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [d]
    ds d
    err4 SBV b
    ind
                                                     , [e] -> e -> SBV b -> e
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [e]
    es e
    err5 SBV b
    ind
                                                     )
        where (as :: [a]
    as, bs :: [b]
    bs, cs :: [c]
    cs, ds :: [d]
    ds, es :: [e]
    es) = [(a, b, c, d, e)] -> ([a], [b], [c], [d], [e])
    forall a b c d e. [(a, b, c, d, e)] -> ([a], [b], [c], [d], [e])
    unzip5 [(a, b, c, d, e)]
    xs

    -- 6-Tuple
    instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e, Mergeable f) => Mergeable (a, b, c, d, e, f) where
      symbolicMerge :: Bool
    -> SBV Bool
    -> (a, b, c, d, e, f)
    -> (a, b, c, d, e, f)
    -> (a, b, c, d, e, f)
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (i0 :: a
    i0, i1 :: b
    i1, i2 :: c
    i2, i3 :: d
    i3, i4 :: e
    i4, i5 :: f
    i5) (j0 :: a
    j0, j1 :: b
    j1, j2 :: c
    j2, j3 :: d
    j3, j4 :: e
    j4, j5 :: f
    j5) = ( Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    i0 a
    j0
                                                                            , Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    i1 b
    j1
                                                                            , Bool -> SBV Bool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t c
    i2 c
    j2
                                                                            , Bool -> SBV Bool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t d
    i3 d
    j3
                                                                            , Bool -> SBV Bool -> e -> e -> e
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t e
    i4 e
    j4
                                                                            , Bool -> SBV Bool -> f -> f -> f
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t f
    i5 f
    j5
                                                                            )

      select :: [(a, b, c, d, e, f)]
    -> (a, b, c, d, e, f) -> SBV b -> (a, b, c, d, e, f)
    select xs :: [(a, b, c, d, e, f)]
    xs (err1 :: a
    err1, err2 :: b
    err2, err3 :: c
    err3, err4 :: d
    err4, err5 :: e
    err5, err6 :: f
    err6) ind :: SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [a]
    as a
    err1 SBV b
    ind
                                                           , [b] -> b -> SBV b -> b
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [b]
    bs b
    err2 SBV b
    ind
                                                           , [c] -> c -> SBV b -> c
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [c]
    cs c
    err3 SBV b
    ind
                                                           , [d] -> d -> SBV b -> d
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [d]
    ds d
    err4 SBV b
    ind
                                                           , [e] -> e -> SBV b -> e
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [e]
    es e
    err5 SBV b
    ind
                                                           , [f] -> f -> SBV b -> f
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [f]
    fs f
    err6 SBV b
    ind
                                                           )
        where (as :: [a]
    as, bs :: [b]
    bs, cs :: [c]
    cs, ds :: [d]
    ds, es :: [e]
    es, fs :: [f]
    fs) = [(a, b, c, d, e, f)] -> ([a], [b], [c], [d], [e], [f])
    forall a b c d e f.
    [(a, b, c, d, e, f)] -> ([a], [b], [c], [d], [e], [f])
    unzip6 [(a, b, c, d, e, f)]
    xs

    -- 7-Tuple
    instance (Mergeable a, Mergeable b, Mergeable c, Mergeable d, Mergeable e, Mergeable f, Mergeable g) => Mergeable (a, b, c, d, e, f, g) where
      symbolicMerge :: Bool
    -> SBV Bool
    -> (a, b, c, d, e, f, g)
    -> (a, b, c, d, e, f, g)
    -> (a, b, c, d, e, f, g)
    symbolicMerge f :: Bool
    f t :: SBV Bool
    t (i0 :: a
    i0, i1 :: b
    i1, i2 :: c
    i2, i3 :: d
    i3, i4 :: e
    i4, i5 :: f
    i5, i6 :: g
    i6) (j0 :: a
    j0, j1 :: b
    j1, j2 :: c
    j2, j3 :: d
    j3, j4 :: e
    j4, j5 :: f
    j5, j6 :: g
    j6) = ( Bool -> SBV Bool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t a
    i0 a
    j0
                                                                                    , Bool -> SBV Bool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t b
    i1 b
    j1
                                                                                    , Bool -> SBV Bool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t c
    i2 c
    j2
                                                                                    , Bool -> SBV Bool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t d
    i3 d
    j3
                                                                                    , Bool -> SBV Bool -> e -> e -> e
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t e
    i4 e
    j4
                                                                                    , Bool -> SBV Bool -> f -> f -> f
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t f
    i5 f
    j5
                                                                                    , Bool -> SBV Bool -> g -> g -> g
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    f SBV Bool
    t g
    i6 g
    j6
                                                                                    )

      select :: [(a, b, c, d, e, f, g)]
    -> (a, b, c, d, e, f, g) -> SBV b -> (a, b, c, d, e, f, g)
    select xs :: [(a, b, c, d, e, f, g)]
    xs (err1 :: a
    err1, err2 :: b
    err2, err3 :: c
    err3, err4 :: d
    err4, err5 :: e
    err5, err6 :: f
    err6, err7 :: g
    err7) ind :: SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [a]
    as a
    err1 SBV b
    ind
                                                                 , [b] -> b -> SBV b -> b
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [b]
    bs b
    err2 SBV b
    ind
                                                                 , [c] -> c -> SBV b -> c
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [c]
    cs c
    err3 SBV b
    ind
                                                                 , [d] -> d -> SBV b -> d
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [d]
    ds d
    err4 SBV b
    ind
                                                                 , [e] -> e -> SBV b -> e
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [e]
    es e
    err5 SBV b
    ind
                                                                 , [f] -> f -> SBV b -> f
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [f]
    fs f
    err6 SBV b
    ind
                                                                 , [g] -> g -> SBV b -> g
    forall a b.
    (Mergeable a, Ord b, SymVal b, Num b) =>
    [a] -> a -> SBV b -> a
    select [g]
    gs g
    err7 SBV b
    ind
                                                                 )
        where (as :: [a]
    as, bs :: [b]
    bs, cs :: [c]
    cs, ds :: [d]
    ds, es :: [e]
    es, fs :: [f]
    fs, gs :: [g]
    gs) = [(a, b, c, d, e, f, g)] -> ([a], [b], [c], [d], [e], [f], [g])
    forall a b c d e f g.
    [(a, b, c, d, e, f, g)] -> ([a], [b], [c], [d], [e], [f], [g])
    unzip7 [(a, b, c, d, e, f, g)]
    xs

    -- Arbitrary product types, using GHC.Generics
    --
    -- NB: Because of the way GHC.Generics works, the implementation of
    -- symbolicMerge' is recursive. The derived instance for @data T a = T a a a a@
    -- resembles that for (a, (a, (a, a))), not the flat 4-tuple (a, a, a, a). This
    -- difference should have no effect in practice. Note also that, unlike the
    -- hand-rolled tuple instances, the generic instance does not provide a custom
    -- 'select' implementation, and so does not benefit from the SMT-table
    -- implementation in the 'SBV a' instance.

    -- | Not exported. Symbolic merge using the generic representation provided by
    -- 'G.Generics'.
    symbolicMergeDefault :: (G.Generic a, GMergeable (G.Rep a)) => Bool -> SBool -> a -> a -> a
    symbolicMergeDefault :: Bool -> SBV Bool -> a -> a -> a
    symbolicMergeDefault force :: Bool
    force t :: SBV Bool
    t x :: a
    x y :: a
    y = Rep a Any -> a
    forall a x. Generic a => Rep a x -> a
    G.to (Rep a Any -> a) -> Rep a Any -> a
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBV Bool -> Rep a Any -> Rep a Any -> Rep a Any
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBV Bool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBV Bool
    t (a -> Rep a Any
    forall a x. Generic a => a -> Rep a x
    G.from a
    x) (a -> Rep a Any
    forall a x. Generic a => a -> Rep a x
    G.from a
    y)

    -- | Not exported. Used only in 'symbolicMergeDefault'. Instances are provided for
    -- the generic representations of product types where each element is Mergeable.
    class GMergeable f where
      symbolicMerge' :: Bool -> SBool -> f a -> f a -> f a

    instance GMergeable U1 where
      symbolicMerge' :: Bool -> SBV Bool -> U1 a -> U1 a -> U1 a
    symbolicMerge' _ _ _ _ = U1 a
    forall k (p :: k). U1 p
    U1

    instance (Mergeable c) => GMergeable (K1 i c) where
      symbolicMerge' :: Bool -> SBV Bool -> K1 i c a -> K1 i c a -> K1 i c a
    symbolicMerge' force :: Bool
    force t :: SBV Bool
    t (K1 x :: c
    x) (K1 y :: c
    y) = c -> K1 i c a
    forall k i c (p :: k). c -> K1 i c p
    K1 (c -> K1 i c a) -> c -> K1 i c a
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBV Bool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBV Bool -> a -> a -> a
    symbolicMerge Bool
    force SBV Bool
    t c
    x c
    y

    instance (GMergeable f) => GMergeable (M1 i c f) where
      symbolicMerge' :: Bool -> SBV Bool -> M1 i c f a -> M1 i c f a -> M1 i c f a
    symbolicMerge' force :: Bool
    force t :: SBV Bool
    t (M1 x :: f a
    x) (M1 y :: f a
    y) = f a -> M1 i c f a
    forall k i (c :: Meta) (f :: k -> *) (p :: k). f p -> M1 i c f p
    M1 (f a -> M1 i c f a) -> f a -> M1 i c f a
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBV Bool -> f a -> f a -> f a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBV Bool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBV Bool
    t f a
    x f a
    y

    instance (GMergeable f, GMergeable g) => GMergeable (f :*: g) where
      symbolicMerge' :: Bool -> SBV Bool -> (:*:) f g a -> (:*:) f g a -> (:*:) f g a
    symbolicMerge' force :: Bool
    force t :: SBV Bool
    t (x1 :: f a
    x1 :*: y1 :: g a
    y1) (x2 :: f a
    x2 :*: y2 :: g a
    y2) = Bool -> SBV Bool -> f a -> f a -> f a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBV Bool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBV Bool
    t f a
    x1 f a
    x2 f a -> g a -> (:*:) f g a
    forall k (f :: k -> *) (g :: k -> *) (p :: k).
    f p -> g p -> (:*:) f g p
    :*: Bool -> SBV Bool -> g a -> g a -> g a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBV Bool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBV Bool
    t g a
    y1 g a
    y2

    -- Bounded instances
    instance (SymVal a, Bounded a) => Bounded (SBV a) where
      minBound :: SBV a
    minBound = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal a
    forall a. Bounded a => a
    minBound
      maxBound :: SBV a
    maxBound = a -> SBV a
    forall a. SymVal a => a -> SBV a
    literal a
    forall a. Bounded a => a
    maxBound

    -- Arrays

    -- SArrays are both "EqSymbolic" and "Mergeable"
    instance EqSymbolic (SArray a b) where
      SArray a :: SArr
    a .== :: SArray a b -> SArray a b -> SBV Bool
    .== SArray b :: SArr
    b = SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV (SArr
    a SArr -> SArr -> SVal
    `eqSArr` SArr
    b)

    -- When merging arrays; we'll ignore the force argument. This is arguably
    -- the right thing to do as we've too many things and likely we want to keep it efficient.
    instance SymVal b => Mergeable (SArray a b) where
      symbolicMerge :: Bool -> SBV Bool -> SArray a b -> SArray a b -> SArray a b
    symbolicMerge _ = SBV Bool -> SArray a b -> SArray a b -> SArray a b
    forall (array :: * -> * -> *) b a.
    (SymArray array, SymVal b) =>
    SBV Bool -> array a b -> array a b -> array a b
    mergeArrays

    -- When merging arrays; we'll ignore the force argument. This is arguably
    -- the right thing to do as we've too many things and likely we want to keep it efficient.
    instance SymVal b => Mergeable (SFunArray a b) where
      symbolicMerge :: Bool -> SBV Bool -> SFunArray a b -> SFunArray a b -> SFunArray a b
    symbolicMerge _ = SBV Bool -> SFunArray a b -> SFunArray a b -> SFunArray a b
    forall (array :: * -> * -> *) b a.
    (SymArray array, SymVal b) =>
    SBV Bool -> array a b -> array a b -> array a b
    mergeArrays

    -- | Uninterpreted constants and functions. An uninterpreted constant is
    -- a value that is indexed by its name. The only property the prover assumes
    -- about these values are that they are equivalent to themselves; i.e., (for
    -- functions) they return the same results when applied to same arguments.
    -- We support uninterpreted-functions as a general means of black-box'ing
    -- operations that are /irrelevant/ for the purposes of the proof; i.e., when
    -- the proofs can be performed without any knowledge about the function itself.
    --
    -- Minimal complete definition: 'sbvUninterpret'. However, most instances in
    -- practice are already provided by SBV, so end-users should not need to define their
    -- own instances.
    class Uninterpreted a where
      -- | Uninterpret a value, receiving an object that can be used instead. Use this version
      -- when you do not need to add an axiom about this value.
      uninterpret :: String -> a
      -- | Uninterpret a value, only for the purposes of code-generation. For execution
      -- and verification the value is used as is. For code-generation, the alternate
      -- definition is used. This is useful when we want to take advantage of native
      -- libraries on the target languages.
      cgUninterpret :: String -> [String] -> a -> a
      -- | Most generalized form of uninterpretation, this function should not be needed
      -- by end-user-code, but is rather useful for the library development.
      sbvUninterpret :: Maybe ([String], a) -> String -> a

      {-# MINIMAL sbvUninterpret #-}

      -- defaults:
      uninterpret             = Maybe ([String], a) -> String -> a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret Maybe ([String], a)
    forall a. Maybe a
    Nothing
      cgUninterpret nm :: String
    nm code :: [String]
    code v :: a
    v = Maybe ([String], a) -> String -> a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String], a) -> Maybe ([String], a)
    forall a. a -> Maybe a
    Just ([String]
    code, a
    v)) String
    nm

    -- Plain constants
    instance HasKind a => Uninterpreted (SBV a) where
      sbvUninterpret :: Maybe ([String], SBV a) -> String -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], SBV a)
    mbCgData nm :: String
    nm
         | Just (_, v :: SBV a
    v) <- Maybe ([String], SBV a)
    mbCgData = SBV a
    v
         | Bool
    True                    = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
        where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
              result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                             case (Bool
    isSMT, Maybe ([String], SBV a)
    mbCgData) of
                               (True, Just (_, v :: SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    v
                               _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    ka]) (([String], SBV a) -> [String]
    forall a b. (a, b) -> a
    fst (([String], SBV a) -> [String])
    -> Maybe ([String], SBV a) -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], SBV a)
    mbCgData)
                                                         State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) []

    -- Functions of one argument
    instance (SymVal b, HasKind a) => Uninterpreted (SBV b -> SBV a) where
      sbvUninterpret :: Maybe ([String], SBV b -> SBV a) -> String -> SBV b -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV b -> SBV a
    f
        where f :: SBV b -> SBV a
    f arg0 :: SBV b
    arg0
               | Just (_, v :: SBV b -> SBV a
    v) <- Maybe ([String], SBV b -> SBV a)
    mbCgData, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg0
               = SBV b -> SBV a
    v SBV b
    arg0
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe ([String], SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV b -> SBV a
    v SBV b
    arg0)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    kb, Kind
    ka]) (([String], SBV b -> SBV a) -> [String]
    forall a b. (a, b) -> a
    fst (([String], SBV b -> SBV a) -> [String])
    -> Maybe ([String], SBV b -> SBV a) -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg0
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0]

    -- Functions of two arguments
    instance (SymVal c, SymVal b, HasKind a) => Uninterpreted (SBV c -> SBV b -> SBV a) where
      sbvUninterpret :: Maybe ([String], SBV c -> SBV b -> SBV a)
    -> String -> SBV c -> SBV b -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], SBV c -> SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV c -> SBV b -> SBV a
    f
        where f :: SBV c -> SBV b -> SBV a
    f arg0 :: SBV c
    arg0 arg1 :: SBV b
    arg1
               | Just (_, v :: SBV c -> SBV b -> SBV a
    v) <- Maybe ([String], SBV c -> SBV b -> SBV a)
    mbCgData, SBV c -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV c
    arg0, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg1
               = SBV c -> SBV b -> SBV a
    v SBV c
    arg0 SBV b
    arg1
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy c
    forall k (t :: k). Proxy t
    Proxy @c)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe ([String], SBV c -> SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV c -> SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV c -> SBV b -> SBV a
    v SBV c
    arg0 SBV b
    arg1)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    kc, Kind
    kb, Kind
    ka]) (([String], SBV c -> SBV b -> SBV a) -> [String]
    forall a b. (a, b) -> a
    fst (([String], SBV c -> SBV b -> SBV a) -> [String])
    -> Maybe ([String], SBV c -> SBV b -> SBV a) -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], SBV c -> SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV c -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV c
    arg0
                                                                SV
    sw1 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg1
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0, SV
    sw1]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0, SV
    sw1]

    -- Functions of three arguments
    instance (SymVal d, SymVal c, SymVal b, HasKind a) => Uninterpreted (SBV d -> SBV c -> SBV b -> SBV a) where
      sbvUninterpret :: Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    -> String -> SBV d -> SBV c -> SBV b -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV d -> SBV c -> SBV b -> SBV a
    f arg0 :: SBV d
    arg0 arg1 :: SBV c
    arg1 arg2 :: SBV b
    arg2
               | Just (_, v :: SBV d -> SBV c -> SBV b -> SBV a
    v) <- Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData, SBV d -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV d
    arg0, SBV c -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV c
    arg1, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg2
               = SBV d -> SBV c -> SBV b -> SBV a
    v SBV d
    arg0 SBV c
    arg1 SBV b
    arg2
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy c
    forall k (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy d
    forall k (t :: k). Proxy t
    Proxy @d)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV d -> SBV c -> SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV d -> SBV c -> SBV b -> SBV a
    v SBV d
    arg0 SBV c
    arg1 SBV b
    arg2)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (([String], SBV d -> SBV c -> SBV b -> SBV a) -> [String]
    forall a b. (a, b) -> a
    fst (([String], SBV d -> SBV c -> SBV b -> SBV a) -> [String])
    -> Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV d -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV d
    arg0
                                                                SV
    sw1 <- State -> SBV c -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV c
    arg1
                                                                SV
    sw2 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg2
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0, SV
    sw1, SV
    sw2]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0, SV
    sw1, SV
    sw2]

    -- Functions of four arguments
    instance (SymVal e, SymVal d, SymVal c, SymVal b, HasKind a) => Uninterpreted (SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvUninterpret :: Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f arg0 :: SBV e
    arg0 arg1 :: SBV d
    arg1 arg2 :: SBV c
    arg2 arg3 :: SBV b
    arg3
               | Just (_, v :: SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v) <- Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData, SBV e -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV e
    arg0, SBV d -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV d
    arg1, SBV c -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV c
    arg2, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg3
               = SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV e
    arg0 SBV d
    arg1 SBV c
    arg2 SBV b
    arg3
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy c
    forall k (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy d
    forall k (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy e
    forall k (t :: k). Proxy t
    Proxy @e)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV e
    arg0 SBV d
    arg1 SBV c
    arg2 SBV b
    arg3)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a) -> [String]
    forall a b. (a, b) -> a
    fst (([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a) -> [String])
    -> Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV e -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV e
    arg0
                                                                SV
    sw1 <- State -> SBV d -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV d
    arg1
                                                                SV
    sw2 <- State -> SBV c -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV c
    arg2
                                                                SV
    sw3 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg3
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3]

    -- Functions of five arguments
    instance (SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, HasKind a) => Uninterpreted (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvUninterpret :: Maybe
      ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    sbvUninterpret mbCgData :: Maybe
      ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f arg0 :: SBV f
    arg0 arg1 :: SBV e
    arg1 arg2 :: SBV d
    arg2 arg3 :: SBV c
    arg3 arg4 :: SBV b
    arg4
               | Just (_, v :: SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v) <- Maybe
      ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData, SBV f -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV f
    arg0, SBV e -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV e
    arg1, SBV d -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV d
    arg2, SBV c -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV c
    arg3, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg4
               = SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV f
    arg0 SBV e
    arg1 SBV d
    arg2 SBV c
    arg3 SBV b
    arg4
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy c
    forall k (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy d
    forall k (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy e
    forall k (t :: k). Proxy t
    Proxy @e)
                     kf :: Kind
    kf = Proxy f -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy f
    forall k (t :: k). Proxy t
    Proxy @f)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe
      ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV f
    arg0 SBV e
    arg1 SBV d
    arg2 SBV c
    arg3 SBV b
    arg4)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    kf, Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> [String]
    forall a b. (a, b) -> a
    fst (([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
     -> [String])
    -> Maybe
         ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe
      ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV f -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV f
    arg0
                                                                SV
    sw1 <- State -> SBV e -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV e
    arg1
                                                                SV
    sw2 <- State -> SBV d -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV d
    arg2
                                                                SV
    sw3 <- State -> SBV c -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV c
    arg3
                                                                SV
    sw4 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg4
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3, SV
    sw4]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3, SV
    sw4]

    -- Functions of six arguments
    instance (SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, HasKind a) => Uninterpreted (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvUninterpret :: Maybe
      ([String],
       SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvUninterpret mbCgData :: Maybe
      ([String],
       SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f arg0 :: SBV g
    arg0 arg1 :: SBV f
    arg1 arg2 :: SBV e
    arg2 arg3 :: SBV d
    arg3 arg4 :: SBV c
    arg4 arg5 :: SBV b
    arg5
               | Just (_, v :: SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v) <- Maybe
      ([String],
       SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData, SBV g -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV g
    arg0, SBV f -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV f
    arg1, SBV e -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV e
    arg2, SBV d -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV d
    arg3, SBV c -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV c
    arg4, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg5
               = SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV g
    arg0 SBV f
    arg1 SBV e
    arg2 SBV d
    arg3 SBV c
    arg4 SBV b
    arg5
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy c
    forall k (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy d
    forall k (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy e
    forall k (t :: k). Proxy t
    Proxy @e)
                     kf :: Kind
    kf = Proxy f -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy f
    forall k (t :: k). Proxy t
    Proxy @f)
                     kg :: Kind
    kg = Proxy g -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy g
    forall k (t :: k). Proxy t
    Proxy @g)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe
      ([String],
       SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV g
    arg0 SBV f
    arg1 SBV e
    arg2 SBV d
    arg3 SBV c
    arg4 SBV b
    arg5)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    kg, Kind
    kf, Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (([String],
     SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> [String]
    forall a b. (a, b) -> a
    fst (([String],
      SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
     -> [String])
    -> Maybe
         ([String],
          SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe
      ([String],
       SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV g -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV g
    arg0
                                                                SV
    sw1 <- State -> SBV f -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV f
    arg1
                                                                SV
    sw2 <- State -> SBV e -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV e
    arg2
                                                                SV
    sw3 <- State -> SBV d -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV d
    arg3
                                                                SV
    sw4 <- State -> SBV c -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV c
    arg4
                                                                SV
    sw5 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg5
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3, SV
    sw4, SV
    sw5]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3, SV
    sw4, SV
    sw5]

    -- Functions of seven arguments
    instance (SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, HasKind a)
                => Uninterpreted (SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvUninterpret :: Maybe
      ([String],
       SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String
    -> SBV h
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvUninterpret mbCgData :: Maybe
      ([String],
       SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData nm :: String
    nm = SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f arg0 :: SBV h
    arg0 arg1 :: SBV g
    arg1 arg2 :: SBV f
    arg2 arg3 :: SBV e
    arg3 arg4 :: SBV d
    arg4 arg5 :: SBV c
    arg5 arg6 :: SBV b
    arg6
               | Just (_, v :: SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v) <- Maybe
      ([String],
       SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData, SBV h -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV h
    arg0, SBV g -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV g
    arg1, SBV f -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV f
    arg2, SBV e -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV e
    arg3, SBV d -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV d
    arg4, SBV c -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV c
    arg5, SBV b -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete SBV b
    arg6
               = SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV h
    arg0 SBV g
    arg1 SBV f
    arg2 SBV e
    arg3 SBV d
    arg4 SBV c
    arg5 SBV b
    arg6
               | Bool
    True
               = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    ka (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    result
               where ka :: Kind
    ka = Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy a
    forall k (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy c
    forall k (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy d
    forall k (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy e
    forall k (t :: k). Proxy t
    Proxy @e)
                     kf :: Kind
    kf = Proxy f -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy f
    forall k (t :: k). Proxy t
    Proxy @f)
                     kg :: Kind
    kg = Proxy g -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy g
    forall k (t :: k). Proxy t
    Proxy @g)
                     kh :: Kind
    kh = Proxy h -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy h
    forall k (t :: k). Proxy t
    Proxy @h)
                     result :: State -> IO SV
    result st :: State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, Maybe
      ([String],
       SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData) of
                                      (True, Just (_, v :: SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v SBV h
    arg0 SBV g
    arg1 SBV f
    arg2 SBV e
    arg3 SBV d
    arg4 SBV c
    arg5 SBV b
    arg6)
                                      _                   -> do State -> String -> SBVType -> Maybe [String] -> IO ()
    newUninterpreted State
    st String
    nm ([Kind] -> SBVType
    SBVType [Kind
    kh, Kind
    kg, Kind
    kf, Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (([String],
     SBV h
     -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> [String]
    forall a b. (a, b) -> a
    fst (([String],
      SBV h
      -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
     -> [String])
    -> Maybe
         ([String],
          SBV h
          -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe [String]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe
      ([String],
       SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    mbCgData)
                                                                SV
    sw0 <- State -> SBV h -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV h
    arg0
                                                                SV
    sw1 <- State -> SBV g -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV g
    arg1
                                                                SV
    sw2 <- State -> SBV f -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV f
    arg2
                                                                SV
    sw3 <- State -> SBV e -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV e
    arg3
                                                                SV
    sw4 <- State -> SBV d -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV d
    arg4
                                                                SV
    sw5 <- State -> SBV c -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV c
    arg5
                                                                SV
    sw6 <- State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    arg6
                                                                (SV -> IO ()) -> [SV] -> IO ()
    forall (t :: * -> *) (m :: * -> *) a b.
    (Foldable t, Monad m) =>
    (a -> m b) -> t a -> m ()
    mapM_ SV -> IO ()
    forceSVArg [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3, SV
    sw4, SV
    sw5, SV
    sw6]
                                                                State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    ka (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (String -> Op
    Uninterpreted String
    nm) [SV
    sw0, SV
    sw1, SV
    sw2, SV
    sw3, SV
    sw4, SV
    sw5, SV
    sw6]

    -- Uncurried functions of two arguments
    instance (SymVal c, SymVal b, HasKind a) => Uninterpreted ((SBV c, SBV b) -> SBV a) where
      sbvUninterpret :: Maybe ([String], (SBV c, SBV b) -> SBV a)
    -> String -> (SBV c, SBV b) -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], (SBV c, SBV b) -> SBV a)
    mbCgData nm :: String
    nm = let f :: SBV c -> SBV b -> SBV a
    f = Maybe ([String], SBV c -> SBV b -> SBV a)
    -> String -> SBV c -> SBV b -> SBV a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String], (SBV c, SBV b) -> SBV a)
    -> ([String], SBV c -> SBV b -> SBV a)
    forall a a b c. (a, (a, b) -> c) -> (a, a -> b -> c)
    uc2 (([String], (SBV c, SBV b) -> SBV a)
     -> ([String], SBV c -> SBV b -> SBV a))
    -> Maybe ([String], (SBV c, SBV b) -> SBV a)
    -> Maybe ([String], SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], (SBV c, SBV b) -> SBV a)
    mbCgData) String
    nm in (SBV c -> SBV b -> SBV a) -> (SBV c, SBV b) -> SBV a
    forall a b c. (a -> b -> c) -> (a, b) -> c
    uncurry SBV c -> SBV b -> SBV a
    f
        where uc2 :: (a, (a, b) -> c) -> (a, a -> b -> c)
    uc2 (cs :: a
    cs, fn :: (a, b) -> c
    fn) = (a
    cs, ((a, b) -> c) -> a -> b -> c
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (a, b) -> c
    fn)

    -- Uncurried functions of three arguments
    instance (SymVal d, SymVal c, SymVal b, HasKind a) => Uninterpreted ((SBV d, SBV c, SBV b) -> SBV a) where
      sbvUninterpret :: Maybe ([String], (SBV d, SBV c, SBV b) -> SBV a)
    -> String -> (SBV d, SBV c, SBV b) -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], (SBV d, SBV c, SBV b) -> SBV a)
    mbCgData nm :: String
    nm = let f :: SBV d -> SBV c -> SBV b -> SBV a
    f = Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    -> String -> SBV d -> SBV c -> SBV b -> SBV a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String], (SBV d, SBV c, SBV b) -> SBV a)
    -> ([String], SBV d -> SBV c -> SBV b -> SBV a)
    forall a a b c t. (a, (a, b, c) -> t) -> (a, a -> b -> c -> t)
    uc3 (([String], (SBV d, SBV c, SBV b) -> SBV a)
     -> ([String], SBV d -> SBV c -> SBV b -> SBV a))
    -> Maybe ([String], (SBV d, SBV c, SBV b) -> SBV a)
    -> Maybe ([String], SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], (SBV d, SBV c, SBV b) -> SBV a)
    mbCgData) String
    nm in \(arg0 :: SBV d
    arg0, arg1 :: SBV c
    arg1, arg2 :: SBV b
    arg2) -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV d
    arg0 SBV c
    arg1 SBV b
    arg2
        where uc3 :: (a, (a, b, c) -> t) -> (a, a -> b -> c -> t)
    uc3 (cs :: a
    cs, fn :: (a, b, c) -> t
    fn) = (a
    cs, \a :: a
    a b :: b
    b c :: c
    c -> (a, b, c) -> t
    fn (a
    a, b
    b, c
    c))

    -- Uncurried functions of four arguments
    instance (SymVal e, SymVal d, SymVal c, SymVal b, HasKind a)
                => Uninterpreted ((SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvUninterpret :: Maybe ([String], (SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> String -> (SBV e, SBV d, SBV c, SBV b) -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], (SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData nm :: String
    nm = let f :: SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String], (SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a a b c d t.
    (a, (a, b, c, d) -> t) -> (a, a -> b -> c -> d -> t)
    uc4 (([String], (SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    -> Maybe ([String], (SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> Maybe ([String], SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], (SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData) String
    nm in \(arg0 :: SBV e
    arg0, arg1 :: SBV d
    arg1, arg2 :: SBV c
    arg2, arg3 :: SBV b
    arg3) -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV e
    arg0 SBV d
    arg1 SBV c
    arg2 SBV b
    arg3
        where uc4 :: (a, (a, b, c, d) -> t) -> (a, a -> b -> c -> d -> t)
    uc4 (cs :: a
    cs, fn :: (a, b, c, d) -> t
    fn) = (a
    cs, \a :: a
    a b :: b
    b c :: c
    c d :: d
    d -> (a, b, c, d) -> t
    fn (a
    a, b
    b, c
    c, d
    d))

    -- Uncurried functions of five arguments
    instance (SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, HasKind a)
                => Uninterpreted ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvUninterpret :: Maybe ([String], (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> String -> (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a
    sbvUninterpret mbCgData :: Maybe ([String], (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData nm :: String
    nm = let f :: SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = Maybe
      ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String], (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a a b c d e t.
    (a, (a, b, c, d, e) -> t) -> (a, a -> b -> c -> d -> e -> t)
    uc5 (([String], (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    -> Maybe ([String], (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> Maybe
         ([String], SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe ([String], (SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData) String
    nm in \(arg0 :: SBV f
    arg0, arg1 :: SBV e
    arg1, arg2 :: SBV d
    arg2, arg3 :: SBV c
    arg3, arg4 :: SBV b
    arg4) -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV f
    arg0 SBV e
    arg1 SBV d
    arg2 SBV c
    arg3 SBV b
    arg4
        where uc5 :: (a, (a, b, c, d, e) -> t) -> (a, a -> b -> c -> d -> e -> t)
    uc5 (cs :: a
    cs, fn :: (a, b, c, d, e) -> t
    fn) = (a
    cs, \a :: a
    a b :: b
    b c :: c
    c d :: d
    d e :: e
    e -> (a, b, c, d, e) -> t
    fn (a
    a, b
    b, c
    c, d
    d, e
    e))

    -- Uncurried functions of six arguments
    instance (SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, HasKind a)
                => Uninterpreted ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvUninterpret :: Maybe
      ([String], (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> String -> (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a
    sbvUninterpret mbCgData :: Maybe
      ([String], (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData nm :: String
    nm = let f :: SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = Maybe
      ([String],
       SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String], (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> ([String],
        SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a a b c d e f t.
    (a, (a, b, c, d, e, f) -> t)
    -> (a, a -> b -> c -> d -> e -> f -> t)
    uc6 (([String], (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> ([String],
         SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    -> Maybe
         ([String], (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> Maybe
         ([String],
          SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe
      ([String], (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData) String
    nm in \(arg0 :: SBV g
    arg0, arg1 :: SBV f
    arg1, arg2 :: SBV e
    arg2, arg3 :: SBV d
    arg3, arg4 :: SBV c
    arg4, arg5 :: SBV b
    arg5) -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV g
    arg0 SBV f
    arg1 SBV e
    arg2 SBV d
    arg3 SBV c
    arg4 SBV b
    arg5
        where uc6 :: (a, (a, b, c, d, e, f) -> t)
    -> (a, a -> b -> c -> d -> e -> f -> t)
    uc6 (cs :: a
    cs, fn :: (a, b, c, d, e, f) -> t
    fn) = (a
    cs, \a :: a
    a b :: b
    b c :: c
    c d :: d
    d e :: e
    e f :: f
    f -> (a, b, c, d, e, f) -> t
    fn (a
    a, b
    b, c
    c, d
    d, e
    e, f
    f))

    -- Uncurried functions of seven arguments
    instance (SymVal h, SymVal g, SymVal f, SymVal e, SymVal d, SymVal c, SymVal b, HasKind a)
                => Uninterpreted ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvUninterpret :: Maybe
      ([String],
       (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> String
    -> (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b)
    -> SBV a
    sbvUninterpret mbCgData :: Maybe
      ([String],
       (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData nm :: String
    nm = let f :: SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = Maybe
      ([String],
       SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> String
    -> SBV h
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. Uninterpreted a => Maybe ([String], a) -> String -> a
    sbvUninterpret (([String],
     (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> ([String],
        SBV h
        -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a a b c d e f g t.
    (a, (a, b, c, d, e, f, g) -> t)
    -> (a, a -> b -> c -> d -> e -> f -> g -> t)
    uc7 (([String],
      (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> ([String],
         SBV h
         -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    -> Maybe
         ([String],
          (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> Maybe
         ([String],
          SBV h
          -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe
      ([String],
       (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    mbCgData) String
    nm in \(arg0 :: SBV h
    arg0, arg1 :: SBV g
    arg1, arg2 :: SBV f
    arg2, arg3 :: SBV e
    arg3, arg4 :: SBV d
    arg4, arg5 :: SBV c
    arg5, arg6 :: SBV b
    arg6) -> SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV h
    arg0 SBV g
    arg1 SBV f
    arg2 SBV e
    arg3 SBV d
    arg4 SBV c
    arg5 SBV b
    arg6
        where uc7 :: (a, (a, b, c, d, e, f, g) -> t)
    -> (a, a -> b -> c -> d -> e -> f -> g -> t)
    uc7 (cs :: a
    cs, fn :: (a, b, c, d, e, f, g) -> t
    fn) = (a
    cs, \a :: a
    a b :: b
    b c :: c
    c d :: d
    d e :: e
    e f :: f
    f g :: g
    g -> (a, b, c, d, e, f, g) -> t
    fn (a
    a, b
    b, c
    c, d
    d, e
    e, f
    f, g
    g))

    -- | Symbolic computations provide a context for writing symbolic programs.
    instance MonadIO m => SolverContext (SymbolicT m) where
       constrain :: SBV Bool -> SymbolicT m ()
    constrain                   (SBV c :: SVal
    c) = Bool -> [(String, String)] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [(String, String)] -> SVal -> m ()
    imposeConstraint Bool
    False []               SVal
    c
       softConstrain :: SBV Bool -> SymbolicT m ()
    softConstrain               (SBV c :: SVal
    c) = Bool -> [(String, String)] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [(String, String)] -> SVal -> m ()
    imposeConstraint Bool
    True  []               SVal
    c
       namedConstraint :: String -> SBV Bool -> SymbolicT m ()
    namedConstraint        nm :: String
    nm   (SBV c :: SVal
    c) = Bool -> [(String, String)] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [(String, String)] -> SVal -> m ()
    imposeConstraint Bool
    False [(":named", String
    nm)] SVal
    c
       constrainWithAttribute :: [(String, String)] -> SBV Bool -> SymbolicT m ()
    constrainWithAttribute atts :: [(String, String)]
    atts (SBV c :: SVal
    c) = Bool -> [(String, String)] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [(String, String)] -> SVal -> m ()
    imposeConstraint Bool
    False [(String, String)]
    atts             SVal
    c
       addAxiom :: String -> [String] -> SymbolicT m ()
    addAxiom                            = String -> [String] -> SymbolicT m ()
    forall (m :: * -> *).
    (SolverContext m, MonadIO m) =>
    String -> [String] -> m ()
    addSymAxiom
       contextState :: SymbolicT m State
    contextState                        = SymbolicT m State
    forall (m :: * -> *). MonadSymbolic m => m State
    symbolicEnv

       setOption :: SMTOption -> SymbolicT m ()
    setOption o :: SMTOption
    o = SMTOption -> SymbolicT m ()
    forall (m :: * -> *). MonadSymbolic m => SMTOption -> m ()
    addNewSMTOption  SMTOption
    o

    -- | Add an axiom. Only used internally, use `addAxiom` from user programs which works over
    -- both regular and query modes of usage.
    addSymAxiom :: (SolverContext m, MonadIO m) => String -> [String] -> m ()
    addSymAxiom :: String -> [String] -> m ()
    addSymAxiom nm :: String
    nm ax :: [String]
    ax = do
            State
    st <- m State
    forall (m :: * -> *). SolverContext m => m State
    contextState
            IO () -> m ()
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ State
    -> (State -> IORef [(String, [String])])
    -> ([(String, [String])] -> [(String, [String])])
    -> IO ()
    -> IO ()
    forall a. State -> (State -> IORef a) -> (a -> a) -> IO () -> IO ()
    modifyState State
    st State -> IORef [(String, [String])]
    raxioms ((String
    nm, [String]
    ax) (String, [String]) -> [(String, [String])] -> [(String, [String])]
    forall a. a -> [a] -> [a]
    :) (() -> IO ()
    forall (m :: * -> *) a. Monad m => a -> m a
    return ())

    -- | Generalization of 'Data.SBV.assertWithPenalty'
    assertWithPenalty :: MonadSymbolic m => String -> SBool -> Penalty -> m ()
    assertWithPenalty :: String -> SBV Bool -> Penalty -> m ()
    assertWithPenalty nm :: String
    nm o :: SBV Bool
    o p :: Penalty
    p = Objective SVal -> m ()
    forall (m :: * -> *). MonadSymbolic m => Objective SVal -> m ()
    addSValOptGoal (Objective SVal -> m ()) -> Objective SVal -> m ()
    forall a b. (a -> b) -> a -> b
    $ SBV Bool -> SVal
    forall a. SBV a -> SVal
    unSBV (SBV Bool -> SVal) -> Objective (SBV Bool) -> Objective SVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` String -> SBV Bool -> Penalty -> Objective (SBV Bool)
    forall a. String -> a -> Penalty -> Objective a
    AssertWithPenalty String
    nm SBV Bool
    o Penalty
    p

    -- | Class of metrics we can optimize for. Currently, booleans,
    -- bounded signed/unsigned bit-vectors, unbounded integers,
    -- algebraic reals and floats can be optimized. You can add
    -- your instances, but bewared that the 'MetricSpace' should
    -- map your type to something the backend solver understands, which
    -- are limited to unsigned bit-vectors, reals, and unbounded integers
    -- for z3.
    --
    -- A good reference on these features is given in the following paper:
    -- <http://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/nbjorner-scss2014.pdf>.
    --
    -- Minimal completion: None. However, if @MetricSpace@ is not identical to the type, you want
    -- to define 'toMetricSpace' and possibly 'minimize'/'maximize' to add extra constraints as necessary.
    class Metric a where
      -- | The metric space we optimize the goal over. Usually the same as the type itself, but not always!
      -- For instance, signed bit-vectors are optimized over their unsigned counterparts, floats are
      -- optimized over their 'Word32' comparable counterparts, etc.
      type MetricSpace a :: *
      type MetricSpace a = a

      -- | Compute the metric value to optimize.
      toMetricSpace   :: SBV a -> SBV (MetricSpace a)
      -- | Compute the value itself from the metric corresponding to it.
      fromMetricSpace :: SBV (MetricSpace a) -> SBV a

      -- | Minimizing a metric space
      msMinimize :: (MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
      msMinimize nm :: String
    nm o :: SBV a
    o = Objective SVal -> m ()
    forall (m :: * -> *). MonadSymbolic m => Objective SVal -> m ()
    addSValOptGoal (Objective SVal -> m ()) -> Objective SVal -> m ()
    forall a b. (a -> b) -> a -> b
    $ SBV (MetricSpace a) -> SVal
    forall a. SBV a -> SVal
    unSBV (SBV (MetricSpace a) -> SVal)
    -> Objective (SBV (MetricSpace a)) -> Objective SVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` String -> SBV (MetricSpace a) -> Objective (SBV (MetricSpace a))
    forall a. String -> a -> Objective a
    Minimize String
    nm (SBV a -> SBV (MetricSpace a)
    forall a. Metric a => SBV a -> SBV (MetricSpace a)
    toMetricSpace SBV a
    o)

      -- | Maximizing a metric space
      msMaximize :: (MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
      msMaximize nm :: String
    nm o :: SBV a
    o = Objective SVal -> m ()
    forall (m :: * -> *). MonadSymbolic m => Objective SVal -> m ()
    addSValOptGoal (Objective SVal -> m ()) -> Objective SVal -> m ()
    forall a b. (a -> b) -> a -> b
    $ SBV (MetricSpace a) -> SVal
    forall a. SBV a -> SVal
    unSBV (SBV (MetricSpace a) -> SVal)
    -> Objective (SBV (MetricSpace a)) -> Objective SVal
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` String -> SBV (MetricSpace a) -> Objective (SBV (MetricSpace a))
    forall a. String -> a -> Objective a
    Maximize String
    nm (SBV a -> SBV (MetricSpace a)
    forall a. Metric a => SBV a -> SBV (MetricSpace a)
    toMetricSpace SBV a
    o)

      -- if MetricSpace is the same, we can give a default definition
      default toMetricSpace :: (a ~ MetricSpace a) => SBV a -> SBV (MetricSpace a)
      toMetricSpace = SBV a -> SBV (MetricSpace a)
    forall a. a -> a
    id

      default fromMetricSpace :: (a ~ MetricSpace a) => SBV (MetricSpace a) -> SBV a
      fromMetricSpace = SBV (MetricSpace a) -> SBV a
    forall a. a -> a
    id

    -- Booleans assume True is greater than False
    instance Metric Bool where
      type MetricSpace Bool = Word8
      toMetricSpace :: SBV Bool -> SBV (MetricSpace Bool)
    toMetricSpace t :: SBV Bool
    t       = SBV Bool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBV Bool -> a -> a -> a
    ite SBV Bool
    t 1 0
      fromMetricSpace :: SBV (MetricSpace Bool) -> SBV Bool
    fromMetricSpace w :: SBV (MetricSpace Bool)
    w     = SBV Word8
    SBV (MetricSpace Bool)
    w SBV Word8 -> SBV Word8 -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    ./= 0

    -- | Generalization of 'Data.SBV.minimize'
    minimize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
    minimize :: String -> SBV a -> m ()
    minimize = String -> SBV a -> m ()
    forall a (m :: * -> *).
    (Metric a, MonadSymbolic m, SolverContext m) =>
    String -> SBV a -> m ()
    msMinimize

    -- | Generalization of 'Data.SBV.maximize'
    maximize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
    maximize :: String -> SBV a -> m ()
    maximize = String -> SBV a -> m ()
    forall a (m :: * -> *).
    (Metric a, MonadSymbolic m, SolverContext m) =>
    String -> SBV a -> m ()
    msMaximize

    -- Unsigned types, integers, and reals directly optimize
    instance Metric Word8
    instance Metric Word16
    instance Metric Word32
    instance Metric Word64
    instance Metric Integer
    instance Metric AlgReal

    -- To optimize signed bounded values, we have to adjust to the range
    instance Metric Int8 where
      type MetricSpace Int8 = Word8
      toMetricSpace :: SBV Int8 -> SBV (MetricSpace Int8)
    toMetricSpace    x :: SBV Int8
    x    = SBV Int8 -> SBV Word8
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Int8
    x SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Num a => a -> a -> a
    + 128  -- 2^7
      fromMetricSpace :: SBV (MetricSpace Int8) -> SBV Int8
    fromMetricSpace  x :: SBV (MetricSpace Int8)
    x    = SBV Word8 -> SBV Int8
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Word8
    SBV (MetricSpace Int8)
    x SBV Int8 -> SBV Int8 -> SBV Int8
    forall a. Num a => a -> a -> a
    - 128

    instance Metric Int16 where
      type MetricSpace Int16 = Word16
      toMetricSpace :: SBV Int16 -> SBV (MetricSpace Int16)
    toMetricSpace    x :: SBV Int16
    x     = SBV Int16 -> SBV Word16
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Int16
    x SBV Word16 -> SBV Word16 -> SBV Word16
    forall a. Num a => a -> a -> a
    + 32768  -- 2^15
      fromMetricSpace :: SBV (MetricSpace Int16) -> SBV Int16
    fromMetricSpace  x :: SBV (MetricSpace Int16)
    x     = SBV Word16 -> SBV Int16
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Word16
    SBV (MetricSpace Int16)
    x SBV Int16 -> SBV Int16 -> SBV Int16
    forall a. Num a => a -> a -> a
    - 32768

    instance Metric Int32 where
      type MetricSpace Int32 = Word32
      toMetricSpace :: SBV Int32 -> SBV (MetricSpace Int32)
    toMetricSpace    x :: SBV Int32
    x     = SBV Int32 -> SBV Word32
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Int32
    x SBV Word32 -> SBV Word32 -> SBV Word32
    forall a. Num a => a -> a -> a
    + 2147483648 -- 2^31
      fromMetricSpace :: SBV (MetricSpace Int32) -> SBV Int32
    fromMetricSpace  x :: SBV (MetricSpace Int32)
    x     = SBV Word32 -> SBV Int32
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Word32
    SBV (MetricSpace Int32)
    x SBV Int32 -> SBV Int32 -> SBV Int32
    forall a. Num a => a -> a -> a
    - 2147483648

    instance Metric Int64 where
      type MetricSpace Int64 = Word64
      toMetricSpace :: SBV Int64 -> SBV (MetricSpace Int64)
    toMetricSpace    x :: SBV Int64
    x     = SBV Int64 -> SBV Word64
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Int64
    x SBV Word64 -> SBV Word64 -> SBV Word64
    forall a. Num a => a -> a -> a
    + 9223372036854775808  -- 2^63
      fromMetricSpace :: SBV (MetricSpace Int64) -> SBV Int64
    fromMetricSpace  x :: SBV (MetricSpace Int64)
    x     = SBV Word64 -> SBV Int64
    forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral SBV Word64
    SBV (MetricSpace Int64)
    x SBV Int64 -> SBV Int64 -> SBV Int64
    forall a. Num a => a -> a -> a
    - 9223372036854775808

    -- Quickcheck interface on symbolic-booleans..
    instance Testable SBool where
      property :: SBV Bool -> Property
    property (SBV (SVal _ (Left b :: CV
    b))) = Bool -> Property
    forall prop. Testable prop => prop -> Property
    property (CV -> Bool
    cvToBool CV
    b)
      property _                       = String -> Property
    forall a. HasCallStack => String -> a
    error "Quick-check: Constant folding produced a symbolic value! Perhaps used a non-reducible expression? Please report!"

    instance Testable (Symbolic SBool) where
       property :: Symbolic (SBV Bool) -> Property
    property prop :: Symbolic (SBV Bool)
    prop = PropertyM IO () -> Property
    forall a. Testable a => PropertyM IO a -> Property
    QC.monadicIO (PropertyM IO () -> Property) -> PropertyM IO () -> Property
    forall a b. (a -> b) -> a -> b
    $ do (cond :: Bool
    cond, r :: Bool
    r, modelVals :: [(String, CV)]
    modelVals) <- IO (Bool, Bool, [(String, CV)])
    -> PropertyM IO (Bool, Bool, [(String, CV)])
    forall (m :: * -> *) a. Monad m => m a -> PropertyM m a
    QC.run IO (Bool, Bool, [(String, CV)])
    test
                                         Bool -> PropertyM IO ()
    forall (m :: * -> *). Monad m => Bool -> PropertyM m ()
    QC.pre Bool
    cond
                                         Bool -> PropertyM IO () -> PropertyM IO ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    unless (Bool
    r Bool -> Bool -> Bool
    || [(String, CV)] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [(String, CV)]
    modelVals) (PropertyM IO () -> PropertyM IO ())
    -> PropertyM IO () -> PropertyM IO ()
    forall a b. (a -> b) -> a -> b
    $ (Property -> Property) -> PropertyM IO ()
    forall (m :: * -> *).
    Monad m =>
    (Property -> Property) -> PropertyM m ()
    QC.monitor (String -> Property -> Property
    forall prop. Testable prop => String -> prop -> Property
    QC.counterexample ([(String, CV)] -> String
    complain [(String, CV)]
    modelVals))
                                         Bool -> PropertyM IO ()
    forall (m :: * -> *). Monad m => Bool -> PropertyM m ()
    QC.assert Bool
    r
         where test :: IO (Bool, Bool, [(String, CV)])
    test = do (r :: SBV Bool
    r, Result{resTraces :: Result -> [(String, CV)]
    resTraces=[(String, CV)]
    tvals, resObservables :: Result -> [(String, CV -> Bool, SV)]
    resObservables=[(String, CV -> Bool, SV)]
    ovals, resConsts :: Result -> [(SV, CV)]
    resConsts=[(SV, CV)]
    cs, resConstraints :: Result -> Seq (Bool, [(String, String)], SV)
    resConstraints=Seq (Bool, [(String, String)], SV)
    cstrs, resUIConsts :: Result -> [(String, SBVType)]
    resUIConsts=[(String, SBVType)]
    unints}) <- SBVRunMode -> Symbolic (SBV Bool) -> IO (SBV Bool, Result)
    forall (m :: * -> *) a.
    MonadIO m =>
    SBVRunMode -> SymbolicT m a -> m (a, Result)
    runSymbolic (Maybe (Bool, [((Quantifier, NamedSymVar), Maybe CV)]) -> SBVRunMode
    Concrete Maybe (Bool, [((Quantifier, NamedSymVar), Maybe CV)])
    forall a. Maybe a
    Nothing) Symbolic (SBV Bool)
    prop

                         let cval :: SV -> CV
    cval = CV -> Maybe CV -> CV
    forall a. a -> Maybe a -> a
    fromMaybe (String -> CV
    forall a. HasCallStack => String -> a
    error "Cannot quick-check in the presence of uninterpeted constants!") (Maybe CV -> CV) -> (SV -> Maybe CV) -> SV -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (SV -> [(SV, CV)] -> Maybe CV
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    `lookup` [(SV, CV)]
    cs)
                             cond :: Bool
    cond = [Bool] -> Bool
    forall (t :: * -> *). Foldable t => t Bool -> Bool
    and [CV -> Bool
    cvToBool (SV -> CV
    cval SV
    v) | (False, _, v :: SV
    v) <- Seq (Bool, [(String, String)], SV)
    -> [(Bool, [(String, String)], SV)]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    F.toList Seq (Bool, [(String, String)], SV)
    cstrs] -- Only pick-up "hard" constraints, as indicated by False in the fist component

                             getObservable :: (String, CV -> Bool, SV) -> Maybe (String, CV)
    getObservable (nm :: String
    nm, f :: CV -> Bool
    f, v :: SV
    v) = case SV
    v SV -> [(SV, CV)] -> Maybe CV
    forall a b. Eq a => a -> [(a, b)] -> Maybe b
    `lookup` [(SV, CV)]
    cs of
                                                          Just cv :: CV
    cv -> if CV -> Bool
    f CV
    cv then (String, CV) -> Maybe (String, CV)
    forall a. a -> Maybe a
    Just (String
    nm, CV
    cv) else Maybe (String, CV)
    forall a. Maybe a
    Nothing
                                                          Nothing -> String -> Maybe (String, CV)
    forall a. HasCallStack => String -> a
    error (String -> Maybe (String, CV)) -> String -> Maybe (String, CV)
    forall a b. (a -> b) -> a -> b
    $ "Quick-check: Observable " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String
    nm String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ " did not reduce to a constant!"

                         case ((String, SBVType) -> String) -> [(String, SBVType)] -> [String]
    forall a b. (a -> b) -> [a] -> [b]
    map (String, SBVType) -> String
    forall a b. (a, b) -> a
    fst [(String, SBVType)]
    unints of
                           [] -> case SBV Bool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV Bool
    r of
                                   Nothing -> String -> IO (Bool, Bool, [(String, CV)])
    forall a. HasCallStack => String -> a
    error (String -> IO (Bool, Bool, [(String, CV)]))
    -> String -> IO (Bool, Bool, [(String, CV)])
    forall a b. (a -> b) -> a -> b
    $ String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate "\n" [ "Quick-check: Calls to 'observe' not supported in quick-check mode. Please use 'sObserve' for full support."
                                                                       , "             (If you haven't used 'observe', please report this as a bug!)"
                                                                       ]
                                   Just b :: Bool
    b  -> (Bool, Bool, [(String, CV)]) -> IO (Bool, Bool, [(String, CV)])
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool
    cond, Bool
    b, [(String, CV)]
    tvals [(String, CV)] -> [(String, CV)] -> [(String, CV)]
    forall a. [a] -> [a] -> [a]
    ++ ((String, CV -> Bool, SV) -> Maybe (String, CV))
    -> [(String, CV -> Bool, SV)] -> [(String, CV)]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe (String, CV -> Bool, SV) -> Maybe (String, CV)
    getObservable [(String, CV -> Bool, SV)]
    ovals)
                           us :: [String]
    us -> String -> IO (Bool, Bool, [(String, CV)])
    forall a. HasCallStack => String -> a
    error (String -> IO (Bool, Bool, [(String, CV)]))
    -> String -> IO (Bool, Bool, [(String, CV)])
    forall a b. (a -> b) -> a -> b
    $ "Cannot quick-check in the presence of uninterpreted constants: " String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ String -> [String] -> String
    forall a. [a] -> [[a]] -> [a]
    intercalate ", " [String]
    us

               complain :: [(String, CV)] -> String
    complain qcInfo :: [(String, CV)]
    qcInfo = SMTConfig -> SMTModel -> String
    showModel SMTConfig
    defaultSMTCfg ([(String, GeneralizedCV)]
    -> Maybe [((Quantifier, NamedSymVar), Maybe CV)]
    -> [(String, CV)]
    -> [(String, (SBVType, ([([CV], CV)], CV)))]
    -> SMTModel
    SMTModel [] Maybe [((Quantifier, NamedSymVar), Maybe CV)]
    forall a. Maybe a
    Nothing [(String, CV)]
    qcInfo [])

    -- | Quick check an SBV property. Note that a regular @quickCheck@ call will work just as
    -- well. Use this variant if you want to receive the boolean result.
    sbvQuickCheck :: Symbolic SBool -> IO Bool
    sbvQuickCheck :: Symbolic (SBV Bool) -> IO Bool
    sbvQuickCheck prop :: Symbolic (SBV Bool)
    prop = Result -> Bool
    QC.isSuccess (Result -> Bool) -> IO Result -> IO Bool
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Symbolic (SBV Bool) -> IO Result
    forall prop. Testable prop => prop -> IO Result
    QC.quickCheckResult Symbolic (SBV Bool)
    prop

    -- Quickcheck interface on dynamically-typed values. A run-time check
    -- ensures that the value has boolean type.
    instance Testable (Symbolic SVal) where
      property :: Symbolic SVal -> Property
    property m :: Symbolic SVal
    m = Symbolic (SBV Bool) -> Property
    forall prop. Testable prop => prop -> Property
    property (Symbolic (SBV Bool) -> Property)
    -> Symbolic (SBV Bool) -> Property
    forall a b. (a -> b) -> a -> b
    $ do SVal
    s <- Symbolic SVal
    m
                                 Bool -> Symbolic () -> Symbolic ()
    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
    when (SVal -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SVal
    s Kind -> Kind -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Kind
    KBool) (Symbolic () -> Symbolic ()) -> Symbolic () -> Symbolic ()
    forall a b. (a -> b) -> a -> b
    $ String -> Symbolic ()
    forall a. HasCallStack => String -> a
    error "Cannot quickcheck non-boolean value"
                                 SBV Bool -> Symbolic (SBV Bool)
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SVal -> SBV Bool
    forall a. SVal -> SBV a
    SBV SVal
    s :: SBool)

    -- | Explicit sharing combinator. The SBV library has internal caching/hash-consing mechanisms
    -- built in, based on Andy Gill's type-safe obervable sharing technique (see: <http://ku-fpg.github.io/files/Gill-09-TypeSafeReification.pdf>).
    -- However, there might be times where being explicit on the sharing can help, especially in experimental code. The 'slet' combinator
    -- ensures that its first argument is computed once and passed on to its continuation, explicitly indicating the intent of sharing. Most
    -- use cases of the SBV library should simply use Haskell's @let@ construct for this purpose.
    slet :: forall a b. (HasKind a, HasKind b) => SBV a -> (SBV a -> SBV b) -> SBV b
    slet :: SBV a -> (SBV a -> SBV b) -> SBV b
    slet x :: SBV a
    x f :: SBV a -> SBV b
    f = SVal -> SBV b
    forall a. SVal -> SBV a
    SBV (SVal -> SBV b) -> SVal -> SBV b
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    k (Either CV (Cached SV) -> SVal) -> Either CV (Cached SV) -> SVal
    forall a b. (a -> b) -> a -> b
    $ Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right (Cached SV -> Either CV (Cached SV))
    -> Cached SV -> Either CV (Cached SV)
    forall a b. (a -> b) -> a -> b
    $ (State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache State -> IO SV
    r
        where k :: Kind
    k    = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (Proxy b
    forall k (t :: k). Proxy t
    Proxy @b)
              r :: State -> IO SV
    r st :: State
    st = do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                        let xsbv :: SBV a
    xsbv = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SBV a) -> SVal -> SBV a
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x) (Cached SV -> Either CV (Cached SV)
    forall a b. b -> Either a b
    Right ((State -> IO SV) -> Cached SV
    forall a. (State -> IO a) -> Cached a
    cache (IO SV -> State -> IO SV
    forall a b. a -> b -> a
    const (SV -> IO SV
    forall (m :: * -> *) a. Monad m => a -> m a
    return SV
    xsv))))
                            res :: SBV b
    res  = SBV a -> SBV b
    f SBV a
    xsbv
                        State -> SBV b -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV b
    res

    -- | Equality as a proof method. Allows for
    -- very concise construction of equivalence proofs, which is very typical in
    -- bit-precise proofs.
    infix 4 ===
    class Equality a where
      (===) :: a -> a -> IO ThmResult

    instance {-# OVERLAPPABLE #-} (SymVal a, EqSymbolic z) => Equality (SBV a -> z) where
      k :: SBV a -> z
    k === :: (SBV a -> z) -> (SBV a -> z) -> IO ThmResult
    === l :: SBV a -> z
    l = (SBV a -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a -> SBV a -> z
    k SBV a
    a z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> z
    l SBV a
    a

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality (SBV a -> SBV b -> z) where
      k :: SBV a -> SBV b -> z
    k === :: (SBV a -> SBV b -> z) -> (SBV a -> SBV b -> z) -> IO ThmResult
    === l :: SBV a -> SBV b -> z
    l = (SBV a -> SBV b -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b -> SBV a -> SBV b -> z
    k SBV a
    a SBV b
    b z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV b -> z
    l SBV a
    a SBV b
    b

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality ((SBV a, SBV b) -> z) where
      k :: (SBV a, SBV b) -> z
    k === :: ((SBV a, SBV b) -> z) -> ((SBV a, SBV b) -> z) -> IO ThmResult
    === l :: (SBV a, SBV b) -> z
    l = (SBV a -> SBV b -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b -> (SBV a, SBV b) -> z
    k (SBV a
    a, SBV b
    b) z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (SBV a, SBV b) -> z
    l (SBV a
    a, SBV b
    b)

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> z) where
      k :: SBV a -> SBV b -> SBV c -> z
    k === :: (SBV a -> SBV b -> SBV c -> z)
    -> (SBV a -> SBV b -> SBV c -> z) -> IO ThmResult
    === l :: SBV a -> SBV b -> SBV c -> z
    l = (SBV a -> SBV b -> SBV c -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c -> SBV a -> SBV b -> SBV c -> z
    k SBV a
    a SBV b
    b SBV c
    c z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV b -> SBV c -> z
    l SBV a
    a SBV b
    b SBV c
    c

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c) -> z) where
      k :: (SBV a, SBV b, SBV c) -> z
    k === :: ((SBV a, SBV b, SBV c) -> z)
    -> ((SBV a, SBV b, SBV c) -> z) -> IO ThmResult
    === l :: (SBV a, SBV b, SBV c) -> z
    l = (SBV a -> SBV b -> SBV c -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c -> (SBV a, SBV b, SBV c) -> z
    k (SBV a
    a, SBV b
    b, SBV c
    c) z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (SBV a, SBV b, SBV c) -> z
    l (SBV a
    a, SBV b
    b, SBV c
    c)

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> z) where
      k :: SBV a -> SBV b -> SBV c -> SBV d -> z
    k === :: (SBV a -> SBV b -> SBV c -> SBV d -> z)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> z) -> IO ThmResult
    === l :: SBV a -> SBV b -> SBV c -> SBV d -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d -> SBV a -> SBV b -> SBV c -> SBV d -> z
    k SBV a
    a SBV b
    b SBV c
    c SBV d
    d z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV b -> SBV c -> SBV d -> z
    l SBV a
    a SBV b
    b SBV c
    c SBV d
    d

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d) -> z) where
      k :: (SBV a, SBV b, SBV c, SBV d) -> z
    k === :: ((SBV a, SBV b, SBV c, SBV d) -> z)
    -> ((SBV a, SBV b, SBV c, SBV d) -> z) -> IO ThmResult
    === l :: (SBV a, SBV b, SBV c, SBV d) -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV Bool) -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV Bool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV Bool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d -> (SBV a, SBV b, SBV c, SBV d) -> z
    k (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d) z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (SBV a, SBV b, SBV c, SBV d) -> z
    l (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d)

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z) where
      k :: SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z
    k === :: (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z) -> IO ThmResult
    === l :: SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV Bool)
    -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV Bool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV Bool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d e :: SBV e
    e -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z
    k SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z
    l SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e) -> z) where
      k :: (SBV a, SBV b, SBV c, SBV d, SBV e) -> z
    k === :: ((SBV a, SBV b, SBV c, SBV d, SBV e) -> z)
    -> ((SBV a, SBV b, SBV c, SBV d, SBV e) -> z) -> IO ThmResult
    === l :: (SBV a, SBV b, SBV c, SBV d, SBV e) -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV Bool)
    -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV Bool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV Bool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d e :: SBV e
    e -> (SBV a, SBV b, SBV c, SBV d, SBV e) -> z
    k (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d, SBV e
    e) z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (SBV a, SBV b, SBV c, SBV d, SBV e) -> z
    l (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d, SBV e
    e)

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z) where
      k :: SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z
    k === :: (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z)
    -> IO ThmResult
    === l :: SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV Bool)
    -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV Bool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV Bool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d e :: SBV e
    e f :: SBV f
    f -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z
    k SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e SBV f
    f z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> z
    l SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e SBV f
    f

    instance {-# OVERLAPPABLE #-}
     (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z) where
      k :: (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z
    k === :: ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z)
    -> ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z)
    -> IO ThmResult
    === l :: (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV Bool)
    -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV Bool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV Bool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d e :: SBV e
    e f :: SBV f
    f -> (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z
    k (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d, SBV e
    e, SBV f
    f) z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f) -> z
    l (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d, SBV e
    e, SBV f
    f)

    instance {-# OVERLAPPABLE #-}
     (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, EqSymbolic z) => Equality (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z) where
      k :: SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z
    k === :: (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z)
    -> (SBV a
        -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z)
    -> IO ThmResult
    === l :: SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z
    l = (SBV a
     -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV Bool)
    -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a
      -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV Bool)
     -> IO ThmResult)
    -> (SBV a
        -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV Bool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d e :: SBV e
    e f :: SBV f
    f g :: SBV g
    g -> SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z
    k SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e SBV f
    f SBV g
    g z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> z
    l SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e SBV f
    f SBV g
    g

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, EqSymbolic z) => Equality ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z) where
      k :: (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z
    k === :: ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z)
    -> ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z)
    -> IO ThmResult
    === l :: (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z
    l = (SBV a
     -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV Bool)
    -> IO ThmResult
    forall (m :: * -> *) a. MProvable m a => a -> m ThmResult
    prove ((SBV a
      -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV Bool)
     -> IO ThmResult)
    -> (SBV a
        -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBV Bool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \a :: SBV a
    a b :: SBV b
    b c :: SBV c
    c d :: SBV d
    d e :: SBV e
    e f :: SBV f
    f g :: SBV g
    g -> (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z
    k (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d, SBV e
    e, SBV f
    f, SBV g
    g) z -> z -> SBV Bool
    forall a. EqSymbolic a => a -> a -> SBV Bool
    .== (SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> z
    l (SBV a
    a, SBV b
    b, SBV c
    c, SBV d
    d, SBV e
    e, SBV f
    f, SBV g
    g)

    {-# ANN module   ("HLint: ignore Reduce duplication" :: String) #-}
    {-# ANN module   ("HLint: ignore Eta reduce" :: String)         #-}