    -----------------------------------------------------------------------------
    -- |
    -- 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 ConstrainedClassMethods #-}
    {-# LANGUAGE DataKinds               #-}
    {-# LANGUAGE DefaultSignatures       #-}
    {-# LANGUAGE DeriveFunctor           #-}
    {-# LANGUAGE FlexibleContexts        #-}
    {-# LANGUAGE FlexibleInstances       #-}
    {-# LANGUAGE Rank2Types              #-}
    {-# LANGUAGE ScopedTypeVariables     #-}
    {-# LANGUAGE TypeApplications        #-}
    {-# LANGUAGE TypeFamilies            #-}
    {-# LANGUAGE TypeOperators           #-}
    {-# LANGUAGE UndecidableInstances    #-}

    {-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans -Wno-incomplete-uni-patterns #-}

    module Data.SBV.Core.Model (
        Mergeable(..), Equality(..), EqSymbolic(..), OrdSymbolic(..), SDivisible(..), SMTDefinable(..), Metric(..), minimize, maximize, assertWithPenalty, SIntegral, SFiniteBits(..)
      , ite, iteLazy, sFromIntegral, sShiftLeft, sShiftRight, sRotateLeft, sBarrelRotateLeft, sRotateRight, sBarrelRotateRight, sSignedShiftArithRight, (.^)
      , oneIf, genVar, genVar_
      , 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
      , sFPHalf, sFPHalf_, sFPHalfs, sFPBFloat, sFPBFloat_, sFPBFloats, sFPSingle, sFPSingle_, sFPSingles, sFPDouble, sFPDouble_, sFPDoubles, sFPQuad, sFPQuad_, sFPQuads
      , sFloatingPoint, sFloatingPoint_, sFloatingPoints
      , sChar, sChar_, sChars, sString, sString_, sStrings, sList, sList_, sLists
      , sRational, sRational_, sRationals
      , SymTuple, sTuple, sTuple_, sTuples
      , sEither, sEither_, sEithers, sMaybe, sMaybe_, sMaybes
      , sSet, sSet_, sSets
      , sEDivMod, sEDiv, sEMod
      , solve
      , slet
      , sRealToSInteger, label, observe, observeIf, sObserve
      , sAssert
      , liftQRem, liftDMod, symbolicMergeWithKind
      , genLiteral, genFromCV, genMkSymVar
      , sbvQuickCheck, lambdaAsArray
      )
      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 (M1(..), U1(..), (:*:)(..), 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.Kind   (Type)
    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.SizedFloats
    import Data.SBV.Core.Data
    import Data.SBV.Core.Symbolic
    import Data.SBV.Core.Operations
    import Data.SBV.Core.Kind
    import Data.SBV.Lambda

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

    import Data.SBV.Utils.Lib     (isKString)
    import Data.SBV.Utils.Numeric (fpIsEqualObjectH)

    import Data.IORef (readIORef)

    -- Symbolic-Word class instances

    -- | Generate a variable, named
    genVar :: MonadSymbolic m => VarContext -> Kind -> String -> m (SBV a)
    genVar :: forall (m :: * -> *) a.
    MonadSymbolic m =>
    VarContext -> Kind -> [Char] -> m (SBV a)
    genVar VarContext
    q Kind
    k = VarContext -> Kind -> Maybe [Char] -> m (SBV a)
    forall a (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Kind -> Maybe [Char] -> m (SBV a)
    mkSymSBV VarContext
    q Kind
    k (Maybe [Char] -> m (SBV a))
    -> ([Char] -> Maybe [Char]) -> [Char] -> m (SBV a)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just

    -- | Generate an unnamed variable
    genVar_ :: MonadSymbolic m => VarContext -> Kind -> m (SBV a)
    genVar_ :: forall (m :: * -> *) a.
    MonadSymbolic m =>
    VarContext -> Kind -> m (SBV a)
    genVar_ VarContext
    q Kind
    k = VarContext -> Kind -> Maybe [Char] -> m (SBV a)
    forall a (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Kind -> Maybe [Char] -> m (SBV a)
    mkSymSBV VarContext
    q Kind
    k Maybe [Char]
    forall a. Maybe a
    Nothing

    -- | Generate a finite constant bitvector
    genLiteral :: Integral a => Kind -> a -> SBV b
    genLiteral :: forall a b. Integral a => Kind -> a -> SBV b
    genLiteral 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 :: forall a. Integral a => CV -> a
    genFromCV (CV Kind
    _ (CInteger Integer
    x)) = Integer -> a
    forall a. Num a => Integer -> a
    fromInteger Integer
    x
    genFromCV CV
    c                   = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> a) -> [Char] -> a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "genFromCV: Unsupported non-integral value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    c

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

    instance SymVal Bool where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m SBool
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m SBool
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar Kind
    KBool
      literal :: Bool -> SBool
    literal  = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SBool) -> (Bool -> SVal) -> Bool -> SBool
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Word8)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Word8)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False Int
    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 Int
    8)
      fromCV :: CV -> Word8
    fromCV   = CV -> Word8
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int8 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Int8)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Int8)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True Int
    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 Int
    8)
      fromCV :: CV -> Int8
    fromCV   = CV -> Int8
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Word16 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Word16)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Word16)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False Int
    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 Int
    16)
      fromCV :: CV -> Word16
    fromCV   = CV -> Word16
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int16 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Int16)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Int16)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True Int
    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 Int
    16)
      fromCV :: CV -> Int16
    fromCV   = CV -> Int16
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Word32 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Word32)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Word32)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False Int
    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 Int
    32)
      fromCV :: CV -> Word32
    fromCV   = CV -> Word32
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int32 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Int32)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Int32)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True Int
    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 Int
    32)
      fromCV :: CV -> Int32
    fromCV   = CV -> Int32
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Word64 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Word64)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Word64)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    False Int
    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 Int
    64)
      fromCV :: CV -> Word64
    fromCV   = CV -> Word64
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Int64 where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Int64)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Int64)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Bool -> Int -> Kind
    KBounded Bool
    True Int
    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 Int
    64)
      fromCV :: CV -> Int64
    fromCV   = CV -> Int64
    forall a. Integral a => CV -> a
    genFromCV

    instance SymVal Integer where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Integer)
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV Integer)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> 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 Rational where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Rational)
    mkSymVal                    = Kind -> VarContext -> Maybe [Char] -> m (SBV Rational)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar Kind
    KRational
      literal :: Rational -> SBV Rational
    literal                     = SVal -> SBV Rational
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Rational)
    -> (Rational -> SVal) -> Rational -> SBV Rational
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KRational  (Either CV (Cached SV) -> SVal)
    -> (Rational -> Either CV (Cached SV)) -> Rational -> 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))
    -> (Rational -> CV) -> Rational -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KRational (CVal -> CV) -> (Rational -> CVal) -> Rational -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Rational -> CVal
    CRational
      fromCV :: CV -> Rational
    fromCV (CV Kind
    _ (CRational Rational
    r)) = Rational
    r
      fromCV CV
    c                    = [Char] -> Rational
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Rational) -> [Char] -> Rational
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.Rational: Unexpected non-rational value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    c

    instance SymVal AlgReal where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m SReal
    mkSymVal                   = Kind -> VarContext -> Maybe [Char] -> m SReal
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar Kind
    KReal
      literal :: AlgReal -> SReal
    literal                    = SVal -> SReal
    forall a. SVal -> SBV a
    SBV (SVal -> SReal) -> (AlgReal -> SVal) -> AlgReal -> SReal
    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 Kind
    _ (CAlgReal AlgReal
    a)) = AlgReal
    a
      fromCV CV
    c                   = [Char] -> AlgReal
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> AlgReal) -> [Char] -> AlgReal
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.AlgReal: Unexpected non-real value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    c

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

    instance SymVal Float where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Float)
    mkSymVal                 = Kind -> VarContext -> Maybe [Char] -> m (SBV Float)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> 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 Kind
    _ (CFloat Float
    a)) = Float
    a
      fromCV CV
    c                 = [Char] -> Float
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Float) -> [Char] -> Float
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.Float: Unexpected non-float value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    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 SBV Float
    _ Float -> Bool
    _ = Bool
    False

    instance SymVal Double where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Double)
    mkSymVal                  = Kind -> VarContext -> Maybe [Char] -> m (SBV Double)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> 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 Kind
    _ (CDouble Double
    a)) = Double
    a
      fromCV CV
    c                  = [Char] -> Double
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Double) -> [Char] -> Double
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.Double: Unexpected non-double value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    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 SBV Double
    _ Double -> Bool
    _ = Bool
    False

    instance SymVal Char where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV Char)
    mkSymVal                = Kind -> VarContext -> Maybe [Char] -> m (SBV Char)
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar Kind
    KChar
      literal :: Char -> SBV Char
    literal 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 Kind
    _ (CChar Char
    a)) = Char
    a
      fromCV CV
    c                = [Char] -> Char
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Char) -> [Char] -> Char
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.String: Unexpected non-char value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    c

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

      literal :: [a] -> SBV [a]
    literal [a]
    as
        | forall a. Typeable a => a -> Bool
    isKString @[a] [a]
    forall a. HasCallStack => a
    undefined = case Dynamic -> Maybe [Char]
    forall a. Typeable a => Dynamic -> Maybe a
    fromDynamic ([a] -> Dynamic
    forall a. Typeable a => a -> Dynamic
    toDyn [a]
    as) of
                                       Just [Char]
    s  -> SVal -> SBV [a]
    forall a. SVal -> SBV a
    SBV (SVal -> SBV [a]) -> ([Char] -> SVal) -> [Char] -> 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)
    -> ([Char] -> Either CV (Cached SV)) -> [Char] -> 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))
    -> ([Char] -> CV) -> [Char] -> Either CV (Cached SV)
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Kind -> CVal -> CV
    CV Kind
    KString (CVal -> CV) -> ([Char] -> CVal) -> [Char] -> CV
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [Char] -> CVal
    CString ([Char] -> SBV [a]) -> [Char] -> SBV [a]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    s
                                       Maybe [Char]
    Nothing -> [Char] -> SBV [a]
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "SString: Cannot construct literal string!"
        | Bool
    True                     = let k :: Kind
    k = Kind -> Kind
    KList (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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 Kind
    _ (CString [Char]
    a)) = [a] -> Maybe [a] -> [a]
    forall a. a -> Maybe a -> a
    fromMaybe ([Char] -> [a]
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "SString: Cannot extract a literal string!")
                                            (Dynamic -> Maybe [a]
    forall a. Typeable a => Dynamic -> Maybe a
    fromDynamic ([Char] -> Dynamic
    forall a. Typeable a => a -> Dynamic
    toDyn [Char]
    a))
      fromCV (CV Kind
    _ (CList [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 (forall t. Proxy t
    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 CV
    c                  = [Char] -> [a]
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> [a]) -> [Char] -> [a]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.fromCV: Unexpected non-list value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    c

    instance ValidFloat eb sb => HasKind (FloatingPoint eb sb) where
      kindOf :: FloatingPoint eb sb -> Kind
    kindOf FloatingPoint eb sb
    _ = Int -> Int -> Kind
    KFP (Proxy eb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @eb)) (Proxy sb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @sb))

    instance ValidFloat eb sb => SymVal (FloatingPoint eb sb) where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (FloatingPoint eb sb))
    mkSymVal                   = Kind -> VarContext -> Maybe [Char] -> m (SBV (FloatingPoint eb sb))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Int -> Int -> Kind
    KFP (Proxy eb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @eb)) (Proxy sb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @sb)))
      literal :: FloatingPoint eb sb -> SBV (FloatingPoint eb sb)
    literal (FloatingPoint FP
    r)  = let k :: Kind
    k = Int -> Int -> Kind
    KFP (Proxy eb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @eb)) (Proxy sb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @sb))
                                   in SVal -> SBV (FloatingPoint eb sb)
    forall a. SVal -> SBV a
    SBV (SVal -> SBV (FloatingPoint eb sb))
    -> SVal -> SBV (FloatingPoint eb sb)
    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 (FP -> CVal
    CFP FP
    r)
      fromCV :: CV -> FloatingPoint eb sb
    fromCV  (CV Kind
    _ (CFP FP
    r))     = FP -> FloatingPoint eb sb
    forall (eb :: Nat) (sb :: Nat). FP -> FloatingPoint eb sb
    FloatingPoint FP
    r
      fromCV  CV
    c                  = [Char] -> FloatingPoint eb sb
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> FloatingPoint eb sb) -> [Char] -> FloatingPoint eb sb
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.FPR: Unexpected non-arbitrary-precision value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    c

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

    mkCVTup :: Int -> Kind -> [CVal] -> SBV a
    mkCVTup :: forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    i k :: Kind
    k@(KTuple [Kind]
    ks) [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
      = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.mkCVTup: Impossible happened. Malformed tuple received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, Kind) -> [Char]
    forall a. Show a => a -> [Char]
    show (Int
    i, Kind
    k)
       where lks :: Int
    lks = [Kind] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Kind]
    ks
             lcs :: Int
    lcs = [CVal] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [CVal]
    cs
    mkCVTup Int
    i Kind
    k [CVal]
    _
      = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.mkCVTup: Impossible happened. Non-tuple received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, Kind) -> [Char]
    forall a. Show a => a -> [Char]
    show (Int
    i, Kind
    k)

    fromCVTup :: Int -> CV -> [CV]
    fromCVTup :: Int -> CV -> [CV]
    fromCVTup Int
    i inp :: CV
    inp@(CV (KTuple [Kind]
    ks) (CTuple [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
       = [Char] -> [CV]
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> [CV]) -> [Char] -> [CV]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.fromCTup: Impossible happened. Malformed tuple received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, CV) -> [Char]
    forall a. Show a => a -> [Char]
    show (Int
    i, CV
    inp)
       where lks :: Int
    lks = [Kind] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [Kind]
    ks
             lcs :: Int
    lcs = [CVal] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [CVal]
    cs
    fromCVTup Int
    i CV
    inp = [Char] -> [CV]
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> [CV]) -> [Char] -> [CV]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.fromCVTup: Impossible happened. Non-tuple received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, CV) -> [Char]
    forall a. Show a => a -> [Char]
    show (Int
    i, CV
    inp)

    instance (SymVal a, SymVal b) => SymVal (Either a b) where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (Either a b))
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV (Either a b))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (Either a b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(Either a b)))

      literal :: Either a b -> SBV (Either a b)
    literal Either a b
    s
        | Left  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 <- 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 (forall t. Proxy t
    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 Kind
    k1 Kind
    _ ) (CEither (Left 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 Kind
    _  Kind
    k2) (CEither (Right 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 CV
    bad                                   = [Char] -> Either a b
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Either a b) -> [Char] -> Either a b
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.fromCV (Either): Malformed either received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    bad

    instance SymVal a => SymVal (Maybe a) where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (Maybe a))
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV (Maybe a))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (Maybe a) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(Maybe a)))

      literal :: Maybe a -> SBV (Maybe a)
    literal 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 <- 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 (forall t. Proxy t
    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 Kind
    _) (CMaybe Maybe CVal
    Nothing))  = Maybe a
    forall a. Maybe a
    Nothing
      fromCV (CV (KMaybe Kind
    k) (CMaybe (Just 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 CV
    bad                               = [Char] -> Maybe a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Maybe a) -> [Char] -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.fromCV (Maybe): Malformed sum received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    bad

    instance (Ord a, SymVal a) => SymVal (RCSet a) where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (RCSet a))
    mkSymVal = Kind -> VarContext -> Maybe [Char] -> m (SBV (RCSet a))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (RCSet a) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(RCSet a)))

      literal :: RCSet a -> SBV (RCSet a)
    literal 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 (Set CVal -> RCSet CVal
    dir, Set a
    s) = case RCSet a
    eur of
                          RegularSet Set a
    x    -> (Set CVal -> RCSet CVal
    forall a. Set a -> RCSet a
    RegularSet,    Set a
    x)
                          ComplementSet 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(RCSet a))

      fromCV :: CV -> RCSet a
    fromCV (CV (KSet Kind
    a) (CSet (RegularSet    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 Kind
    a) (CSet (ComplementSet 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 CV
    bad                                    = [Char] -> RCSet a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> RCSet a) -> [Char] -> RCSet a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SymVal.fromCV (Set): Malformed set received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ CV -> [Char]
    forall a. Show a => a -> [Char]
    show CV
    bad

    -- | SymVal for 0-tuple (i.e., unit)
    instance SymVal () where
      mkSymVal :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV ())
    mkSymVal   = Kind -> VarContext -> Maybe [Char] -> m (SBV ())
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar ([Kind] -> Kind
    KTuple [])
      literal :: () -> SBV ()
    literal () = Int -> Kind -> [CVal] -> SBV ()
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    0   (Proxy () -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @())) []
      fromCV :: CV -> ()
    fromCV CV
    cv  = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b))
    mkSymVal         = Kind -> VarContext -> Maybe [Char] -> m (SBV (a, b))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(a, b)))
       literal :: (a, b) -> SBV (a, b)
    literal (a
    v1, b
    v2) = Int -> Kind -> [CVal] -> SBV (a, b)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    2   (Proxy (a, b) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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       = let ~[CV
    v1, CV
    v2] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b, c))
    mkSymVal             = Kind -> VarContext -> Maybe [Char] -> m (SBV (a, b, c))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b, c) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(a, b, c)))
       literal :: (a, b, c) -> SBV (a, b, c)
    literal (a
    v1, b
    v2, c
    v3) = Int -> Kind -> [CVal] -> SBV (a, b, c)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    3   (Proxy (a, b, c) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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           = let ~[CV
    v1, CV
    v2, CV
    v3] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b, c, d))
    mkSymVal                 = Kind -> VarContext -> Maybe [Char] -> m (SBV (a, b, c, d))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @(a, b, c, d)))
       literal :: (a, b, c, d) -> SBV (a, b, c, d)
    literal (a
    v1, b
    v2, c
    v3, d
    v4) = Int -> Kind -> [CVal] -> SBV (a, b, c, d)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    4   (Proxy (a, b, c, d) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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               = let ~[CV
    v1, CV
    v2, CV
    v3, CV
    v4] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e))
    mkSymVal                     = Kind -> VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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 (a
    v1, b
    v2, c
    v3, d
    v4, e
    v5) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    5   (Proxy (a, b, c, d, e) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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                   = let ~[CV
    v1, CV
    v2, CV
    v3, CV
    v4, CV
    v5] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e, f))
    mkSymVal                         = Kind -> VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e, f))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e, f) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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 (a
    v1, b
    v2, c
    v3, d
    v4, e
    v5, f
    v6) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e, f)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    6   (Proxy (a, b, c, d, e, f) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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                       = let ~[CV
    v1, CV
    v2, CV
    v3, CV
    v4, CV
    v5, CV
    v6] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e, f, g))
    mkSymVal                             = Kind -> VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e, f, g))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e, f, g) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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 (a
    v1, b
    v2, c
    v3, d
    v4, e
    v5, f
    v6, g
    v7) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e, f, g)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    7   (Proxy (a, b, c, d, e, f, g) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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                           = let ~[CV
    v1, CV
    v2, CV
    v3, CV
    v4, CV
    v5, CV
    v6, CV
    v7] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: forall (m :: * -> *).
    MonadSymbolic m =>
    VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e, f, g, h))
    mkSymVal                                 = Kind
    -> VarContext -> Maybe [Char] -> m (SBV (a, b, c, d, e, f, g, h))
    forall (m :: * -> *) a.
    MonadSymbolic m =>
    Kind -> VarContext -> Maybe [Char] -> m (SBV a)
    genMkSymVar (Proxy (a, b, c, d, e, f, g, h) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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 (a
    v1, b
    v2, c
    v3, d
    v4, e
    v5, f
    v6, g
    v7, h
    v8) = Int -> Kind -> [CVal] -> SBV (a, b, c, d, e, f, g, h)
    forall a. Int -> Kind -> [CVal] -> SBV a
    mkCVTup Int
    8   (Proxy (a, b, c, d, e, f, g, h) -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    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                               = let ~[CV
    v1, CV
    v2, CV
    v3, CV
    v4, CV
    v5, CV
    v6, CV
    v7, CV
    v8] = Int -> CV -> [CV]
    fromCVTup Int
    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 :: [Char] -> SString
    fromString = [Char] -> 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 :: forall (m :: * -> *). MonadSymbolic m => [Char] -> m SBool
    sBool = [Char] -> m SBool
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m SBool
    symbolic

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    -- | Generalization of 'Data.SBV.sFPHalf'
    sFPHalf :: String -> Symbolic SFPHalf
    sFPHalf :: [Char] -> Symbolic SFPHalf
    sFPHalf = [Char] -> Symbolic SFPHalf
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m SFPHalf
    symbolic

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

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

    -- | Generalization of 'Data.SBV.sFPBFloat'
    sFPBFloat :: String -> Symbolic SFPBFloat
    sFPBFloat :: [Char] -> Symbolic SFPBFloat
    sFPBFloat = [Char] -> Symbolic SFPBFloat
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m SFPBFloat
    symbolic

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

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

    -- | Generalization of 'Data.SBV.sFPSingle'
    sFPSingle :: String -> Symbolic SFPSingle
    sFPSingle :: [Char] -> Symbolic SFPSingle
    sFPSingle = [Char] -> Symbolic SFPSingle
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m SFPSingle
    symbolic

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

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

    -- | Generalization of 'Data.SBV.sFPDouble'
    sFPDouble :: String -> Symbolic SFPDouble
    sFPDouble :: [Char] -> Symbolic SFPDouble
    sFPDouble = [Char] -> Symbolic SFPDouble
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m SFPDouble
    symbolic

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

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

    -- | Generalization of 'Data.SBV.sFPQuad'
    sFPQuad :: String -> Symbolic SFPQuad
    sFPQuad :: [Char] -> Symbolic SFPQuad
    sFPQuad = [Char] -> Symbolic SFPQuad
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m SFPQuad
    symbolic

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

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

    -- | Generalization of 'Data.SBV.sFloatingPoint'
    sFloatingPoint :: ValidFloat eb sb => String -> Symbolic (SFloatingPoint eb sb)
    sFloatingPoint :: forall (eb :: Nat) (sb :: Nat).
    ValidFloat eb sb =>
    [Char] -> Symbolic (SFloatingPoint eb sb)
    sFloatingPoint = [Char] -> SymbolicT IO (SBV (FloatingPoint eb sb))
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *).
    MonadSymbolic m =>
    [Char] -> m (SBV (FloatingPoint eb sb))
    symbolic

    -- | Generalization of 'Data.SBV.sFloatingPoint_'
    sFloatingPoint_ :: ValidFloat eb sb => Symbolic (SFloatingPoint eb sb)
    sFloatingPoint_ :: forall (eb :: Nat) (sb :: Nat).
    ValidFloat eb sb =>
    Symbolic (SFloatingPoint eb sb)
    sFloatingPoint_ = SymbolicT IO (SBV (FloatingPoint eb sb))
    forall a (m :: * -> *). (SymVal a, MonadSymbolic m) => m (SBV a)
    forall (m :: * -> *).
    MonadSymbolic m =>
    m (SBV (FloatingPoint eb sb))
    free_

    -- | Generalization of 'Data.SBV.sFloatingPoints'
    sFloatingPoints :: ValidFloat eb sb => [String] -> Symbolic [SFloatingPoint eb sb]
    sFloatingPoints :: forall (eb :: Nat) (sb :: Nat).
    ValidFloat eb sb =>
    [[Char]] -> Symbolic [SFloatingPoint eb sb]
    sFloatingPoints = [[Char]] -> SymbolicT IO [SBV (FloatingPoint eb sb)]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [[Char]] -> m [SBV a]
    forall (m :: * -> *).
    MonadSymbolic m =>
    [[Char]] -> m [SBV (FloatingPoint eb sb)]
    symbolics

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

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

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

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

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

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

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

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

    -- | Generalization of 'Data.SBV.sLists'
    sLists :: (SymVal a, MonadSymbolic m) => [String] -> m [SList a]
    sLists :: forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [[Char]] -> m [SList a]
    sLists = [[Char]] -> m [SBV [a]]
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [[Char]] -> m [SBV a]
    forall (m :: * -> *). MonadSymbolic m => [[Char]] -> 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 :: forall tup (m :: * -> *).
    (SymTuple tup, SymVal tup, MonadSymbolic m) =>
    [Char] -> m (SBV tup)
    sTuple = [Char] -> m (SBV tup)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m (SBV tup)
    symbolic

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

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

    -- | Generalization of 'Data.SBV.sRational'
    sRational :: MonadSymbolic m => String -> m SRational
    sRational :: forall (m :: * -> *). MonadSymbolic m => [Char] -> m (SBV Rational)
    sRational = [Char] -> m (SBV Rational)
    forall a (m :: * -> *).
    (SymVal a, MonadSymbolic m) =>
    [Char] -> m (SBV a)
    forall (m :: * -> *). MonadSymbolic m => [Char] -> m (SBV Rational)
    symbolic

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

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

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

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

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

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

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

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

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

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

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

    -- | Generalization of 'Data.SBV.solve'
    solve :: MonadSymbolic m => [SBool] -> m SBool
    solve :: forall (m :: * -> *). MonadSymbolic m => [SBool] -> m SBool
    solve = SBool -> m SBool
    forall a. a -> m a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SBool -> m SBool) -> ([SBool] -> SBool) -> [SBool] -> m SBool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [SBool] -> SBool
    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 :: SReal -> SBV Integer
    sRealToSInteger SReal
    x
      | Just AlgReal
    i <- SReal -> Maybe AlgReal
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SReal
    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 b. Integral b => Rational -> b
    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 State
    st = do SV
    xsv <- State -> SReal -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SReal
    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 :: forall a. SymVal a => [Char] -> SBV a -> SBV a
    label [Char]
    m SBV a
    x
       | Just a
    _ <- 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 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 ([Char] -> Op
    Label [Char]
    m) [SV
    xsv])

    -- | Check if an observable name is good.
    checkObservableName :: String -> Maybe String
    checkObservableName :: [Char] -> Maybe [Char]
    checkObservableName [Char]
    lbl
      | [Char] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Char]
    lbl
      = [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just [Char]
    "SBV.observe: Bad empty name!"
      | (Char -> Char) -> [Char] -> [Char]
    forall a b. (a -> b) -> [a] -> [b]
    map Char -> Char
    toLower [Char]
    lbl [Char] -> [[Char]] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `elem` [[Char]]
    smtLibReservedNames
      = [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.observe: The name chosen is reserved, please change it!: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [Char]
    forall a. Show a => a -> [Char]
    show [Char]
    lbl
      | [Char]
    "s" [Char] -> [Char] -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isPrefixOf` [Char]
    lbl Bool -> Bool -> Bool
    && (Char -> Bool) -> [Char] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Char -> Bool
    isDigit (Int -> [Char] -> [Char]
    forall a. Int -> [a] -> [a]
    drop Int
    1 [Char]
    lbl)
      = [Char] -> Maybe [Char]
    forall a. a -> Maybe a
    Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.observe: Names of the form sXXX are internal to SBV, please use a different name: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char] -> [Char]
    forall a. Show a => a -> [Char]
    show [Char]
    lbl
      | Bool
    True
      = Maybe [Char]
    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 :: forall a. SymVal a => (a -> Bool) -> [Char] -> SBV a -> SBV a
    observeIf a -> Bool
    cond [Char]
    m SBV a
    x
      | Just [Char]
    bad <- [Char] -> Maybe [Char]
    checkObservableName [Char]
    m
      = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    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 State
    st = do SV
    xsv <- State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    x
                      State -> [Char] -> (CV -> Bool) -> SV -> IO ()
    recordObservable State
    st [Char]
    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 a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return SV
    xsv

    -- | Observe the value of an expression, unconditionally. See 'observeIf' for a generalized version.
    observe :: SymVal a => String -> SBV a -> SBV a
    observe :: forall a. SymVal a => [Char] -> SBV a -> SBV a
    observe = (a -> Bool) -> [Char] -> SBV a -> SBV a
    forall a. SymVal a => (a -> Bool) -> [Char] -> 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 :: forall a. SymVal a => [Char] -> SBV a -> Symbolic ()
    sObserve [Char]
    m SBV a
    x
      | Just [Char]
    bad <- [Char] -> Maybe [Char]
    checkObservableName [Char]
    m
      = [Char] -> Symbolic ()
    forall a. HasCallStack => [Char] -> a
    error [Char]
    bad
      | Bool
    True
      = do State
    st <- SymbolicT IO State
    forall (m :: * -> *). MonadSymbolic m => m State
    symbolicEnv
           IO () -> Symbolic ()
    forall a. IO a -> SymbolicT IO a
    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 -> [Char] -> (CV -> Bool) -> SV -> IO ()
    recordObservable State
    st [Char]
    m (Bool -> CV -> Bool
    forall a b. a -> b -> a
    const Bool
    True) SV
    xsv

    -- | 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 within the allowed /inclusive/ range?
      inRange    :: a -> (a, a) -> SBool

      {-# MINIMAL (.<) #-}

      a
    a .<= a
    b    = a
    a a -> a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .< a
    b SBool -> SBool -> SBool
    .|| a
    a a -> a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== a
    b
      a
    a .>  a
    b    = a
    b a -> a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .<  a
    a
      a
    a .>= a
    b    = a
    b a -> a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .<= a
    a

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

      inRange a
    x (a
    y, a
    z) = a
    x a -> a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .>= a
    y SBool -> SBool -> SBool
    .&& a
    x a -> a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .<= 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 SVal
    x .== :: SBV a -> SBV a -> SBool
    .== SBV SVal
    y = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svEqual SVal
    x SVal
    y)
      SBV SVal
    x ./= :: SBV a -> SBV a -> SBool
    ./= SBV SVal
    y = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svNotEqual SVal
    x SVal
    y)

      SBV SVal
    x .=== :: SBV a -> SBV a -> SBool
    .=== SBV SVal
    y = SVal -> SBool
    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] -> SBool
    distinct []                                             = SBool
    sTrue
      distinct [SBV a
    _]                                            = SBool
    sTrue
      distinct [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] -> SBool
    forall {a}. EqSymbolic a => [a] -> SBool
    checkDiff [SBV a]
    xs
                  | [SBV SVal
    a, SBV SVal
    b] <- [SBV a]
    xs, SVal
    a SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    True  = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SBool) -> SVal -> SBool
    forall a b. (a -> b) -> a -> b
    $ SVal -> SVal
    svNot SVal
    b
                  | [SBV SVal
    a, SBV SVal
    b] <- [SBV a]
    xs, SVal
    b SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    True  = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SBool) -> SVal -> SBool
    forall a b. (a -> b) -> a -> b
    $ SVal -> SVal
    svNot SVal
    a
                  | [SBV SVal
    a, SBV SVal
    b] <- [SBV a]
    xs, SVal
    a SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    False = SVal -> SBool
    forall a. SVal -> SBV a
    SBV SVal
    b
                  | [SBV SVal
    a, SBV SVal
    b] <- [SBV a]
    xs, SVal
    b SVal -> SVal -> Bool
    `is` Bool -> SVal
    svBool Bool
    False = SVal -> SBool
    forall a. SVal -> SBV a
    SBV SVal
    a
                  | [SBV a] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBV a]
    xs Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    2 Bool -> Bool -> Bool
    && SBV a -> Bool
    forall {a}. SBV a -> Bool
    isBool ([SBV a] -> SBV a
    forall a. HasCallStack => [a] -> a
    head [SBV a]
    xs)         = SBool
    sFalse
                  | Bool
    True                                      = SVal -> SBool
    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 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)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [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] -> SBool
    checkDiff []     = SBool
    sTrue
              checkDiff (a
    a:[a]
    as) = (a -> SBool) -> [a] -> SBool
    forall a. (a -> SBool) -> [a] -> SBool
    sAll (a
    a a -> a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    ./=) [a]
    as SBool -> SBool -> SBool
    .&& [a] -> SBool
    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 Kind
    _ (Left CV
    _))) = Bool
    True
              isConc SBV a
    _                       = Bool
    False

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

              isBool :: SBV a -> Bool
    isBool (SBV (SVal Kind
    KBool Either CV (Cached SV)
    _)) = Bool
    True
              isBool SBV a
    _                    = 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] -> SBool
    distinctExcept []  [SBV a]
    _       = SBool
    sTrue
      distinctExcept [SBV a
    _] [SBV a]
    _       = SBool
    sTrue
      distinctExcept [SBV a]
    es  [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] -> SBool
    forall {a}. EqSymbolic a => [a] -> SBool
    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 -> SBool
    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 SBV a
    x = case SBV a
    x SBV a -> [SBV a] -> SBool
    forall a. EqSymbolic a => a -> [a] -> SBool
    `sElem` [SBV a]
    ignored of
                               SBV (SVal Kind
    KBool (Left CV
    cv)) -> CV -> Bool
    cvToBool CV
    cv
                               SBool
    _                          -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "distinctExcept: Impossible happened, concrete sElem failed: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ ([SBV a], [SBV a], SBV a) -> [Char]
    forall a. Show a => a -> [Char]
    show ([SBV a]
    es, [SBV a]
    ignored, SBV a
    x)

              ek :: Kind
    ek = case [SBV a] -> SBV a
    forall a. HasCallStack => [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 Kind
    k Either CV (Cached SV)
    _) -> Kind
    k

              r :: State -> IO SV
    r State
    st = do let zero :: SBV Integer
    zero = SBV Integer
    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 -> [Char])
    -> Either (Maybe SVal) [Char]
    -> IO SArr
    newSArr State
    st (Kind
    ek, Kind
    KUnbounded) (\Int
    i -> [Char]
    "array_" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    i) (Maybe SVal -> Either (Maybe SVal) [Char]
    forall a b. a -> Either a b
    Left (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 SBV a
    x SArray a Integer
    table = SBool -> SBV Integer -> SBV Integer -> SBV Integer
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    x SBV a -> [SBV a] -> SBool
    forall a. EqSymbolic a => a -> [a] -> SBool
    `sElem` [SBV a]
    ignored) SBV Integer
    zero (SBV Integer
    1 SBV Integer -> SBV Integer -> SBV Integer
    forall a. Num a => a -> a -> a
    + SArray a Integer -> SBV a -> SBV Integer
    forall a b. SArray a b -> SBV a -> SBV b
    forall (array :: * -> * -> *) a b.
    SymArray array =>
    array a b -> SBV a -> SBV b
    readArray SArray a Integer
    table SBV a
    x)

                            finalArray :: SArray a Integer
    finalArray = (SArray a Integer -> SBV a -> SArray a Integer)
    -> SArray a Integer -> [SBV a] -> SArray a Integer
    forall b a. (b -> a -> b) -> b -> [a] -> b
    forall (t :: * -> *) b a.
    Foldable t =>
    (b -> a -> b) -> b -> t a -> b
    foldl (\SArray a Integer
    table SBV a
    x -> SArray a Integer -> SBV a -> SBV Integer -> SArray a Integer
    forall b a. SymVal b => SArray a b -> SBV a -> SBV b -> SArray a b
    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)) SArray a Integer
    arr [SBV a]
    es

                        State -> SBool -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBool -> IO SV) -> SBool -> IO SV
    forall a b. (a -> b) -> a -> b
    $ (SBV a -> SBool) -> [SBV a] -> SBool
    forall a. (a -> SBool) -> [a] -> SBool
    sAll (\SBV a
    e -> SArray a Integer -> SBV a -> SBV Integer
    forall a b. SArray a b -> SBV a -> SBV b
    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 -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .<= SBV Integer
    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 Kind
    _ (Left CV
    _))) = Bool
    True
              isConc SBV a
    _                       = 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 SVal
    x) .< :: SBV a -> SBV a -> SBool
    .<  b :: SBV a
    b@(SBV SVal
    y) | [Char] -> SBV a -> SBV a -> Bool
    forall a. (SymVal a, HasKind a) => [Char] -> SBV a -> SBV a -> Bool
    smtComparable [Char]
    "<"   SBV a
    a SBV a
    b = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svLessThan SVal
    x SVal
    y)
                              | Bool
    True                    = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svStructuralLessThan SVal
    x SVal
    y)

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

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

      a :: SBV a
    a@(SBV SVal
    x) .>= :: SBV a -> SBV a -> SBool
    .>= b :: SBV a
    b@(SBV SVal
    y) | [Char] -> SBV a -> SBV a -> Bool
    forall a. (SymVal a, HasKind a) => [Char] -> SBV a -> SBV a -> Bool
    smtComparable [Char]
    ">="  SBV a
    a SBV a
    b = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svGreaterEq SVal
    x SVal
    y)
                              | Bool
    True                    = SBV a
    b SBV a -> SBV a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .<= 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 :: forall a. (SymVal a, HasKind a) => [Char] -> SBV a -> SBV a -> Bool
    smtComparable [Char]
    op SBV a
    x 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
          Kind
    KBool         -> Bool
    True
          KBounded   {} -> Bool
    True
          KUnbounded {} -> Bool
    True
          KReal      {} -> Bool
    True
          KUserSort  {} -> Bool
    True
          Kind
    KFloat        -> Bool
    True
          Kind
    KDouble       -> Bool
    True
          KRational  {} -> Bool
    True
          KFP        {} -> Bool
    True
          Kind
    KChar         -> Bool
    True
          Kind
    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 = [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Data.SBV.OrdSymbolic: SMTLib does not support " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    op [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " for " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k

    -- Bool
    instance EqSymbolic Bool where
      Bool
    x .== :: Bool -> Bool -> SBool
    .== Bool
    y = Bool -> SBool
    fromBool (Bool -> SBool) -> Bool -> SBool
    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] -> SBool
    .== []     = SBool
    sTrue
      (a
    x:[a]
    xs) .== (a
    y:[a]
    ys) = a
    x a -> a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== a
    y SBool -> SBool -> SBool
    .&& [a]
    xs [a] -> [a] -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== [a]
    ys
      [a]
    _      .== [a]
    _      = SBool
    sFalse

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    -- | Regular expressions can be compared for equality. Note that we diverge here from the equality
    -- in the concrete sense; i.e., the Eq instance does not match the symbolic case. This is a bit unfortunate,
    -- but unavoidable with the current design of how we "distinguish" operators. Hopefully shouldn't be a big deal,
    -- though one should be careful.
    instance EqSymbolic RegExp where
      RegExp
    r1 .== :: RegExp -> RegExp -> SBool
    .== RegExp
    r2 = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SBool) -> SVal -> SBool
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KBool (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 r :: State -> IO SV
    r State
    st = State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    KBool (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (RegExOp -> Op
    RegExOp (RegExp -> RegExp -> RegExOp
    RegExEq RegExp
    r1 RegExp
    r2))  []

      RegExp
    r1 ./= :: RegExp -> RegExp -> SBool
    ./= RegExp
    r2 = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> SBool) -> SVal -> SBool
    forall a b. (a -> b) -> a -> b
    $ Kind -> Either CV (Cached SV) -> SVal
    SVal Kind
    KBool (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 r :: State -> IO SV
    r State
    st = State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    KBool (SBVExpr -> IO SV) -> SBVExpr -> IO SV
    forall a b. (a -> b) -> a -> b
    $ Op -> [SV] -> SBVExpr
    SBVApp (RegExOp -> Op
    RegExOp (RegExp -> RegExp -> RegExOp
    RegExNEq RegExp
    r1 RegExp
    r2)) []

    -- | 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 multiplier, 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 SVal
    v) = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svTestBit SVal
    v Int
    0)
        msb SBV a
    x       = SBV a -> Int -> SBool
    forall a. SFiniteBits a => SBV a -> Int -> SBool
    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
    - Int
    1)

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

        fromBitsBE = [SBool] -> SBV a
    forall a. SFiniteBits a => [SBool] -> SBV a
    fromBitsLE ([SBool] -> SBV a) -> ([SBool] -> [SBool]) -> [SBool] -> SBV a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [SBool] -> [SBool]
    forall a. [a] -> [a]
    reverse
        fromBitsLE [SBool]
    bs
           | [SBool] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBool]
    bs Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Int
    w
           = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.SFiniteBits.fromBitsLE/BE: Expected: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    w [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " bits, received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show ([SBool] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length [SBool]
    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 -> [SBool] -> SBV a
    forall {t}. (Mergeable t, Bits t) => t -> Int -> [SBool] -> t
    go SBV a
    0 Int
    0 [SBool]
    bs

                 go :: t -> Int -> [SBool] -> t
    go !t
    acc Int
    _  []     = t
    acc
                 go !t
    acc !Int
    i (SBool
    x:[SBool]
    xs) = t -> Int -> [SBool] -> t
    go (SBool -> t -> t -> t
    forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    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
    +Int
    1) [SBool]
    xs

        sTestBit (SBV SVal
    x) Int
    i = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svTestBit SVal
    x Int
    i)
        sExtractBits SBV a
    x     = (Int -> SBool) -> [Int] -> [SBool]
    forall a b. (a -> b) -> [a] -> [b]
    map (SBV a -> Int -> SBool
    forall a. SFiniteBits a => SBV a -> Int -> SBool
    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 SBV a
    x
          | Just a
    v <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    x = SBV Word8 -> a -> SBV Word8
    forall {t} {t}. (Num t, Num t, Bits t) => t -> t -> t
    go SBV Word8
    0 a
    v
          | Bool
    True                  = [SBV Word8] -> SBV Word8
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum [SBool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    b SBV Word8
    1 SBV Word8
    0 | SBool
    b <- SBV a -> [SBool]
    forall a. SFiniteBits a => SBV a -> [SBool]
    blastLE SBV a
    x]
          where -- concrete case
                go :: t -> t -> t
    go !t
    c t
    0 = t
    c
                go !t
    c t
    w = t -> t -> t
    go (t
    ct -> t -> t
    forall a. Num a => a -> a -> a
    +t
    1) (t
    w t -> t -> t
    forall a. Bits a => a -> a -> a
    .&. (t
    wt -> t -> t
    forall a. Num a => a -> a -> a
    -t
    1))

        setBitTo SBV a
    x Int
    i SBool
    b = SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    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 SBV a
    a SBV a
    b
          | SBV a -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV a
    a = [Char] -> (SBool, SBV a)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "fullAdder: only works on unsigned numbers"
          | Bool
    True       = (SBV a
    a SBV a -> SBV a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .> SBV a
    s SBool -> SBool -> SBool
    .|| SBV a
    b SBV a -> SBV a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .> 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 SBV a
    a SBV a
    b
          | SBV a -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV a
    a = [Char] -> (SBV a, SBV a)
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "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) SBV 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 Int
    0 SBV a
    p SBV a
    _ = SBV a
    p
                go Int
    n SBV a
    p SBV a
    x = let (SBool
    c, SBV a
    p')  = SBool -> (SBool, SBV a) -> (SBool, SBV a) -> (SBool, SBV a)
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a -> SBool
    forall a. SFiniteBits a => SBV a -> SBool
    lsb SBV a
    x) (SBV a -> SBV a -> (SBool, SBV a)
    forall a. SFiniteBits a => SBV a -> SBV a -> (SBool, SBV a)
    fullAdder SBV a
    p SBV a
    b) (SBool
    sFalse, SBV a
    p)
                               (SBool
    o, SBV a
    p'') = SBool -> SBV a -> (SBool, SBV a)
    forall {a}. SFiniteBits a => SBool -> SBV a -> (SBool, SBV a)
    shiftIn SBool
    c SBV a
    p'
                               (SBool
    _, SBV a
    x')  = SBool -> SBV a -> (SBool, SBV a)
    forall {a}. SFiniteBits a => SBool -> SBV a -> (SBool, SBV a)
    shiftIn SBool
    o SBV a
    x
                           in Int -> SBV a -> SBV a -> SBV a
    go (Int
    nInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    1) SBV a
    p'' SBV a
    x'
                shiftIn :: SBool -> SBV a -> (SBool, SBV a)
    shiftIn SBool
    k SBV a
    v = (SBV a -> SBool
    forall a. SFiniteBits a => SBV a -> SBool
    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` Int
    1))
                   where mask :: SBV a
    mask = SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    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
    - Int
    1)) SBV a
    0

        -- See the note for 'sPopCount' for a comment on why we return 'SWord8'
        sCountLeadingZeros 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
    - Int
    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 Int
    i | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0 = SBV Word8
    i8
                     | Bool
    True  = SBool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a -> Int -> SBool
    forall a. SFiniteBits a => SBV a -> Int -> SBool
    sTestBit SBV a
    x Int
    i) SBV Word8
    i8 (Int -> SBV Word8
    go (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    -Int
    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 SBV a
    x = Int -> SBV Word8
    go Int
    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 Int
    i | Int
    i Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Int
    m = SBV Word8
    i8
                      | Bool
    True   = SBool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a -> Int -> SBool
    forall a. SFiniteBits a => SBV a -> Int -> SBool
    sTestBit SBV a
    x Int
    i) SBV Word8
    i8 (Int -> SBV Word8
    go (Int
    iInt -> Int -> Int
    forall a. Num a => a -> a -> a
    +Int
    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 SBV Word8
    _ =  Int
    8
    instance SFiniteBits Word16 where sFiniteBitSize :: SBV Word16 -> Int
    sFiniteBitSize SBV Word16
    _ = Int
    16
    instance SFiniteBits Word32 where sFiniteBitSize :: SBV Word32 -> Int
    sFiniteBitSize SBV Word32
    _ = Int
    32
    instance SFiniteBits Word64 where sFiniteBitSize :: SBV Word64 -> Int
    sFiniteBitSize SBV Word64
    _ = Int
    64
    instance SFiniteBits Int8   where sFiniteBitSize :: SBV Int8 -> Int
    sFiniteBitSize SBV Int8
    _ =  Int
    8
    instance SFiniteBits Int16  where sFiniteBitSize :: SBV Int16 -> Int
    sFiniteBitSize SBV Int16
    _ = Int
    16
    instance SFiniteBits Int32  where sFiniteBitSize :: SBV Int32 -> Int
    sFiniteBitSize SBV Int32
    _ = Int
    32
    instance SFiniteBits Int64  where sFiniteBitSize :: SBV Int64 -> Int
    sFiniteBitSize SBV Int64
    _ = Int
    64

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

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

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

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

            result :: SBool
    result = SVal -> SBool
    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 State
    st   = do [SV]
    xsv <- (SBool -> IO SV) -> [SBool] -> IO [SV]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM (State -> SBool -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st) [SBool]
    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 :: [SBool] -> Int -> SBool
    pbAtMost [SBool]
    xs Int
    k
     | Int
    k Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < Int
    0             = [Char] -> SBool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBool) -> [Char] -> SBool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.pbAtMost: Non-negative value required, received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    k
     | (SBool -> Bool) -> [SBool] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all SBool -> Bool
    forall a. SymVal a => SBV a -> Bool
    isConcrete [SBool]
    xs = Bool -> SBool
    forall a. SymVal a => a -> SBV a
    literal (Bool -> SBool) -> Bool -> SBool
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Integer
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    sum ((SBool -> Integer) -> [SBool] -> [Integer]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char] -> Int -> SBool -> Integer
    pbToInteger [Char]
    "pbAtMost" Int
    1) [SBool]
    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              = [Char] -> PBOp -> [SBool] -> SBool
    liftPB [Char]
    "pbAtMost" (Int -> PBOp
    PB_AtMost Int
    k) [SBool]
    xs

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

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

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

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

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

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

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

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

    -- | Predicate for optimizing word operations like (+) and (*).
    isConcreteOne :: SBV a -> Bool
    isConcreteOne :: forall {a}. SBV a -> Bool
    isConcreteOne (SBV (SVal Kind
    _     (Left (CV Kind
    _     (CInteger Integer
    1))))) = Bool
    True
    isConcreteOne (SBV (SVal Kind
    KReal (Left (CV Kind
    KReal (CAlgReal AlgReal
    v))))) = AlgReal -> Bool
    isExactRational AlgReal
    v Bool -> Bool -> Bool
    && AlgReal
    v AlgReal -> AlgReal -> Bool
    forall a. Eq a => a -> a -> Bool
    == AlgReal
    1
    isConcreteOne SBV a
    _                                                 = 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 SVal
    x + :: SBV a -> SBV a -> SBV a
    + SBV SVal
    y = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svPlus SVal
    x SVal
    y)
      SBV SVal
    x * :: SBV a -> SBV a -> SBV a
    * SBV SVal
    y = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svTimes SVal
    x SVal
    y)
      SBV SVal
    x - :: SBV a -> SBV a -> SBV a
    - SBV 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 SVal
    x) = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal
    svAbs SVal
    x)
      signum :: SBV a -> SBV a
    signum 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 = SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    a SBV a -> SBV a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .> SBV a
    z) SBV a
    i
                    (SBV a -> SBV a) -> SBV a -> SBV a
    forall a b. (a -> b) -> a -> b
    $ SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    a SBV a -> SBV a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .< SBV a
    z) (SBV a -> SBV a
    forall a. Num a => a -> a
    negate SBV a
    i) SBV a
    a
        | Bool
    True      = SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    a SBV a -> SBV a -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .> 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) (Integer
    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) (Integer
    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 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 .^ :: forall b e. (Mergeable b, Num b, SIntegral e) => b -> SBV e -> b
    .^ 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
    >= Integer
    0 then let go :: t -> a -> a
    go t
    n a
    v
                            | t
    n t -> t -> Bool
    forall a. Eq a => a -> a -> Bool
    == t
    0 = a
    1
                            | t -> Bool
    forall a. Integral a => a -> Bool
    even t
    n =     t -> a -> a
    go (t
    n t -> t -> t
    forall a. Integral a => a -> a -> a
    `div` t
    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
    * t -> a -> a
    go (t
    n t -> t -> t
    forall a. Integral a => a -> a -> a
    `div` t
    2) (a
    v a -> a -> a
    forall a. Num a => a -> a -> a
    * a
    v)
                       in  Integer -> b -> b
    forall {t} {a}. (Num a, Integral t) => t -> a -> a
    go Integer
    x b
    b
                  else [Char] -> b
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> b) -> [Char] -> b
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "(.^): exponentiation: negative exponent: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Integer -> [Char]
    forall a. Show a => a -> [Char]
    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
      = [Char] -> b
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> b) -> [Char] -> b
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "(.^): exponentiation only works with unsigned bounded symbolic exponents, kind: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    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 SVal
    expt = SBV e
    e
             expBit :: Int -> SBool
    expBit Int
    i = SVal -> SBool
    forall a. SVal -> SBV a
    SBV (SVal -> Int -> SVal
    svTestBit SVal
    expt Int
    i)
             blasted :: [SBool]
    blasted  = (Int -> SBool) -> [Int] -> [SBool]
    forall a b. (a -> b) -> [a] -> [b]
    map Int -> SBool
    expBit [Int
    0 .. SBV e -> Int
    forall a. HasKind a => a -> Int
    intSizeOf SBV e
    e Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1]
         in [b] -> b
    forall a. Num a => [a] -> a
    forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
    product ([b] -> b) -> [b] -> b
    forall a b. (a -> b) -> a -> b
    $ (SBool -> b -> b) -> [SBool] -> [b] -> [b]
    forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
    zipWith (\SBool
    use b
    n -> SBool -> b -> b -> b
    forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    use b
    n b
    1)
                              [SBool]
    blasted
                              ((b -> b) -> b -> [b]
    forall a. (a -> a) -> a -> [a]
    iterate (\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 SVal
    x / :: SBV a -> SBV a -> SBV a
    / sy :: SBV a
    sy@(SBV SVal
    y) | Bool
    div0 = SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    sy SBV a -> SBV a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== SBV a
    0) SBV a
    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
                          Kind
    KFloat             -> Bool
    False
                          Kind
    KDouble            -> Bool
    False
                          KFP{}              -> Bool
    False
                          Kind
    KReal              -> Bool
    True
                          Kind
    KRational          -> Bool
    True
                          -- Following cases should not happen since these types should *not* be instances of Fractional
                          k :: Kind
    k@KBounded{}  -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@Kind
    KUnbounded  -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@Kind
    KBool       -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@Kind
    KString     -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@Kind
    KChar       -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@KList{}     -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@KSet{}      -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@KUserSort{} -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@KTuple{}    -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@KMaybe{}    -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k
                          k :: Kind
    k@KEither{}   -> [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Unexpected Fractional case for: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show Kind
    k

    -- | Define Floating instance on SBV's; only for base types that are already floating; i.e., 'SFloat', 'SDouble', and 'SReal'.
    -- (See the separate definition below for 'SFloatingPoint'.)  Note that unless you use delta-sat via 'Data.SBV.Provers.dReal' on 'SReal', most
    -- of the fields are "undefined" for symbolic values. We will add methods as they are supported by SMTLib. Currently, the
    -- only symbolically available function in this class is 'sqrt' for 'SFloat', 'SDouble' and 'SFloatingPoint'.
    instance (Ord a, SymVal a, Fractional a, Floating a) => Floating (SBV a) where
      pi :: SBV a
    pi      = Rational -> SBV a
    forall a. Fractional a => Rational -> a
    fromRational (Rational -> SBV a) -> (Double -> Rational) -> Double -> SBV a
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Rational
    forall a. Real a => a -> Rational
    toRational (Double -> SBV a) -> Double -> SBV a
    forall a b. (a -> b) -> a -> b
    $ (Double
    forall a. Floating a => a
    pi :: Double)
      exp :: SBV a -> SBV a
    exp     = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "exp"     a -> a
    forall a. Floating a => a -> a
    exp
      log :: SBV a -> SBV a
    log     = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "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     = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "sin"     a -> a
    forall a. Floating a => a -> a
    sin
      cos :: SBV a -> SBV a
    cos     = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "cos"     a -> a
    forall a. Floating a => a -> a
    cos
      tan :: SBV a -> SBV a
    tan     = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "tan"     a -> a
    forall a. Floating a => a -> a
    tan
      asin :: SBV a -> SBV a
    asin    = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "asin"    a -> a
    forall a. Floating a => a -> a
    asin
      acos :: SBV a -> SBV a
    acos    = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "acos"    a -> a
    forall a. Floating a => a -> a
    acos
      atan :: SBV a -> SBV a
    atan    = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "atan"    a -> a
    forall a. Floating a => a -> a
    atan
      sinh :: SBV a -> SBV a
    sinh    = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "sinh"    a -> a
    forall a. Floating a => a -> a
    sinh
      cosh :: SBV a -> SBV a
    cosh    = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "cosh"    a -> a
    forall a. Floating a => a -> a
    cosh
      tanh :: SBV a -> SBV a
    tanh    = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "tanh"    a -> a
    forall a. Floating a => a -> a
    tanh
      asinh :: SBV a -> SBV a
    asinh   = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "asinh"   a -> a
    forall a. Floating a => a -> a
    asinh
      acosh :: SBV a -> SBV a
    acosh   = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "acosh"   a -> a
    forall a. Floating a => a -> a
    acosh
      atanh :: SBV a -> SBV a
    atanh   = [Char] -> (a -> a) -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "atanh"   a -> a
    forall a. Floating a => a -> a
    atanh
      ** :: SBV a -> SBV a -> SBV a
    (**)    = [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS [Char]
    "**"      a -> a -> a
    forall a. Floating a => a -> a -> a
    (**)
      logBase :: SBV a -> SBV a -> SBV a
    logBase = [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS [Char]
    "logBase" a -> a -> a
    forall a. Floating a => a -> a -> a
    logBase

    unsupported :: String -> a
    unsupported :: forall a. [Char] -> a
    unsupported [Char]
    w = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> a) -> [Char] -> a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Data.SBV.FloatingPoint: Unsupported operation: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    w [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ". Please request this as a feature!"

    -- | We give a specific instance for 'SFloatingPoint', because the underlying floating-point type doesn't support
    -- fromRational directly. The overlap with the above instance is unfortunate.
    instance {-# OVERLAPPING #-} ValidFloat eb sb => Floating (SFloatingPoint eb sb) where
      -- Try from double; if there's enough precision this'll work, otherwise will bail out.
      pi :: SFloatingPoint eb sb
    pi
       | Int
    ei Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    11 Bool -> Bool -> Bool
    || Int
    si Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    53 = [Char] -> SFloatingPoint eb sb
    forall a. [Char] -> a
    unsupported ([Char] -> SFloatingPoint eb sb) -> [Char] -> SFloatingPoint eb sb
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Floating.SFloatingPoint.pi (not-enough-precision for " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> [Char]
    forall a. Show a => a -> [Char]
    show (Int
    ei, Int
    si) [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ")"
       | Bool
    True               = FloatingPoint eb sb -> SFloatingPoint eb sb
    forall a. SymVal a => a -> SBV a
    literal (FloatingPoint eb sb -> SFloatingPoint eb sb)
    -> FloatingPoint eb sb -> SFloatingPoint eb sb
    forall a b. (a -> b) -> a -> b
    $ FP -> FloatingPoint eb sb
    forall (eb :: Nat) (sb :: Nat). FP -> FloatingPoint eb sb
    FloatingPoint (FP -> FloatingPoint eb sb) -> FP -> FloatingPoint eb sb
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> Rational -> FP
    fpFromRational Int
    ei Int
    si (Double -> Rational
    forall a. Real a => a -> Rational
    toRational (Double
    forall a. Floating a => a
    pi :: Double))
       where ei :: Int
    ei = Proxy eb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @eb)
             si :: Int
    si = Proxy sb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @sb)

      -- Likewise, exponentiation is again limited to precision of double
      exp :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    exp SFloatingPoint eb sb
    i
       | Int
    ei Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    11 Bool -> Bool -> Bool
    || Int
    si Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    53 = [Char] -> SFloatingPoint eb sb
    forall a. [Char] -> a
    unsupported ([Char] -> SFloatingPoint eb sb) -> [Char] -> SFloatingPoint eb sb
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Floating.SFloatingPoint.exp (not-enough-precision for " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> [Char]
    forall a. Show a => a -> [Char]
    show (Int
    ei, Int
    si) [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ")"
       | Bool
    True               = FloatingPoint eb sb -> SFloatingPoint eb sb
    forall a. SymVal a => a -> SBV a
    literal FloatingPoint eb sb
    e SFloatingPoint eb sb
    -> SFloatingPoint eb sb -> SFloatingPoint eb sb
    forall a. Floating a => a -> a -> a
    ** SFloatingPoint eb sb
    i
       where ei :: Int
    ei = Proxy eb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @eb)
             si :: Int
    si = Proxy sb -> Int
    forall (n :: Nat). KnownNat n => Proxy n -> Int
    intOfProxy (forall (t :: Nat). Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @sb)
             e :: FloatingPoint eb sb
    e  = FP -> FloatingPoint eb sb
    forall (eb :: Nat) (sb :: Nat). FP -> FloatingPoint eb sb
    FloatingPoint (FP -> FloatingPoint eb sb) -> FP -> FloatingPoint eb sb
    forall a b. (a -> b) -> a -> b
    $ Int -> Int -> Rational -> FP
    fpFromRational Int
    ei Int
    si (Double -> Rational
    forall a. Real a => a -> Rational
    toRational (Double -> Double
    forall a. Floating a => a -> a
    exp Double
    1 :: Double))

      log :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    log     = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "log"     FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    log
      sqrt :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    sqrt    = FPOp
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a. SymVal a => FPOp -> (a -> a) -> SBV a -> SBV a
    lift1F   FPOp
    FP_Sqrt   FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    sqrt
      sin :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    sin     = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "sin"     FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    sin
      cos :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    cos     = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "cos"     FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    cos
      tan :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    tan     = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "tan"     FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    tan
      asin :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    asin    = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "asin"    FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    asin
      acos :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    acos    = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "acos"    FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    acos
      atan :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    atan    = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "atan"    FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    atan
      sinh :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    sinh    = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "sinh"    FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    sinh
      cosh :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    cosh    = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "cosh"    FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    cosh
      tanh :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    tanh    = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "tanh"    FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    tanh
      asinh :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    asinh   = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "asinh"   FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    asinh
      acosh :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    acosh   = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "acosh"   FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    acosh
      atanh :: SFloatingPoint eb sb -> SFloatingPoint eb sb
    atanh   = [Char]
    -> (FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    "atanh"   FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a
    atanh
      ** :: SFloatingPoint eb sb
    -> SFloatingPoint eb sb -> SFloatingPoint eb sb
    (**)    = [Char]
    -> (FloatingPoint eb sb
        -> FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS [Char]
    "**"      FloatingPoint eb sb -> FloatingPoint eb sb -> FloatingPoint eb sb
    forall a. Floating a => a -> a -> a
    (**)
      logBase :: SFloatingPoint eb sb
    -> SFloatingPoint eb sb -> SFloatingPoint eb sb
    logBase = [Char]
    -> (FloatingPoint eb sb
        -> FloatingPoint eb sb -> FloatingPoint eb sb)
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    -> SFloatingPoint eb sb
    forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS [Char]
    "logBase" FloatingPoint eb sb -> FloatingPoint eb sb -> FloatingPoint eb sb
    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 :: forall a. SymVal a => FPOp -> (a -> a) -> SBV a -> SBV a
    lift1F FPOp
    w a -> a
    op SBV a
    a
      | Just 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 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 :: forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a) -> SBV a -> SBV a
    lift1FNS [Char]
    nm a -> a
    f SBV a
    sv
      | Just 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                   = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV." [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    nm [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ": not supported for symbolic values of type " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    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 :: forall a.
    (SymVal a, Floating a) =>
    [Char] -> (a -> a -> a) -> SBV a -> SBV a -> SBV a
    lift2FNS [Char]
    nm a -> a -> a
    f SBV a
    sv1 SBV a
    sv2
      | Just a
    v1 <- SBV a -> Maybe a
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBV a
    sv1
      , Just 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                     = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV." [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    nm [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ": not supported for symbolic values of type " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    sv1)

    -- | SReal Floating instance, used in conjunction with the dReal solver for delta-satisfiability. Note that
    -- we do not constant fold these values (except for pi), as Haskell doesn't really have any means of computing
    -- them for arbitrary rationals.
    instance {-# OVERLAPPING #-} Floating SReal where
      pi :: SReal
    pi      = Rational -> SReal
    forall a. Fractional a => Rational -> a
    fromRational (Rational -> SReal) -> (Double -> Rational) -> Double -> SReal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Double -> Rational
    forall a. Real a => a -> Rational
    toRational (Double -> SReal) -> Double -> SReal
    forall a b. (a -> b) -> a -> b
    $ (Double
    forall a. Floating a => a
    pi :: Double)  -- Perhaps not good enough?
      exp :: SReal -> SReal
    exp     = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Exp
      log :: SReal -> SReal
    log     = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Log
      sqrt :: SReal -> SReal
    sqrt    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Sqrt
      sin :: SReal -> SReal
    sin     = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Sin
      cos :: SReal -> SReal
    cos     = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Cos
      tan :: SReal -> SReal
    tan     = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Tan
      asin :: SReal -> SReal
    asin    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_ASin
      acos :: SReal -> SReal
    acos    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_ACos
      atan :: SReal -> SReal
    atan    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_ATan
      sinh :: SReal -> SReal
    sinh    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Sinh
      cosh :: SReal -> SReal
    cosh    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Cosh
      tanh :: SReal -> SReal
    tanh    = NROp -> SReal -> SReal
    lift1SReal NROp
    NR_Tanh
      asinh :: SReal -> SReal
    asinh   = [Char] -> SReal -> SReal
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Data.SBV.SReal: asinh is currently not supported. Please request this as a feature!"
      acosh :: SReal -> SReal
    acosh   = [Char] -> SReal -> SReal
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Data.SBV.SReal: acosh is currently not supported. Please request this as a feature!"
      atanh :: SReal -> SReal
    atanh   = [Char] -> SReal -> SReal
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Data.SBV.SReal: atanh is currently not supported. Please request this as a feature!"
      ** :: SReal -> SReal -> SReal
    (**)    = NROp -> SReal -> SReal -> SReal
    lift2SReal NROp
    NR_Pow

      logBase :: SReal -> SReal -> SReal
    logBase SReal
    x SReal
    y = SReal -> SReal
    forall a. Floating a => a -> a
    log SReal
    y  SReal -> SReal -> SReal
    forall a. Fractional a => a -> a -> a
    / SReal -> SReal
    forall a. Floating a => a -> a
    log SReal
    x

    -- | Lift an sreal unary function
    lift1SReal :: NROp -> SReal -> SReal
    lift1SReal :: NROp -> SReal -> SReal
    lift1SReal NROp
    w SReal
    a = SVal -> SReal
    forall a. SVal -> SBV a
    SBV (SVal -> SReal) -> SVal -> SReal
    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    = SReal -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SReal
    a
            r :: State -> IO SV
    r State
    st = do SV
    swa <- State -> SReal -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SReal
    a
                      State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    k (Op -> [SV] -> SBVExpr
    SBVApp (NROp -> Op
    NonLinear NROp
    w) [SV
    swa])

    -- | Lift an sreal binary function
    lift2SReal :: NROp -> SReal -> SReal -> SReal
    lift2SReal :: NROp -> SReal -> SReal -> SReal
    lift2SReal NROp
    w SReal
    a SReal
    b = SVal -> SReal
    forall a. SVal -> SBV a
    SBV (SVal -> SReal) -> SVal -> SReal
    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    = SReal -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SReal
    a
            r :: State -> IO SV
    r State
    st = do SV
    swa <- State -> SReal -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SReal
    a
                      SV
    swb <- State -> SReal -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SReal
    b
                      State -> Kind -> SBVExpr -> IO SV
    newExpr State
    st Kind
    k (Op -> [SV] -> SBVExpr
    SBVApp (NROp -> Op
    NonLinear NROp
    w) [SV
    swa, SV
    swb])

    -- 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 SVal
    x .&. :: SBV a -> SBV a -> SBV a
    .&. SBV SVal
    y    = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svAnd SVal
    x SVal
    y)
      SBV SVal
    x .|. :: SBV a -> SBV a -> SBV a
    .|. SBV SVal
    y    = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal -> SVal
    svOr SVal
    x SVal
    y)
      SBV SVal
    x xor :: SBV a -> SBV a -> SBV a
    `xor` SBV 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 SVal
    x) = SVal -> SBV a
    forall a. SVal -> SBV a
    SBV (SVal -> SVal
    svNot SVal
    x)
      bitSize :: SBV a -> Int
    bitSize  SBV a
    x         = SBV a -> Int
    forall a. HasKind a => a -> Int
    intSizeOf SBV a
    x
      bitSizeMaybe :: SBV a -> Maybe Int
    bitSizeMaybe 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 SBV a
    x         = SBV a -> Bool
    forall a. HasKind a => a -> Bool
    hasSign SBV a
    x
      bit :: Int -> SBV a
    bit Int
    i              = SBV a
    1 SBV a -> Int -> SBV a
    forall a. Bits a => a -> Int -> a
    `shiftL` Int
    i
      setBit :: SBV a -> Int -> SBV a
    setBit        SBV a
    x 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      SBV a
    x 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 SBV a
    x 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 SVal
    x) 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 SVal
    x) 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 SVal
    x) 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 SVal
    x) 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
      SBV a
    x testBit :: SBV a -> Int -> Bool
    `testBit` Int
    i
        | SBV (SVal Kind
    _ (Left (CV Kind
    _ (CInteger Integer
    n)))) <- SBV a
    x
        = Integer -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    testBit Integer
    n Int
    i
        | Bool
    True
        = [Char] -> Bool
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Bool) -> [Char] -> Bool
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.testBit: Called on symbolic value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> [Char]
    forall a. Show a => a -> [Char]
    show SBV a
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ". Use sTestBit instead."
      -- NB. popCount is *not* implementable on non-concrete symbolic words
      popCount :: SBV a -> Int
    popCount SBV a
    x
        | SBV (SVal Kind
    _ (Left (CV (KBounded Bool
    _ Int
    w) (CInteger 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
    - Integer
    1))
        | Bool
    True
        = [Char] -> Int
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Int) -> [Char] -> Int
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.popCount: Called on symbolic value: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> [Char]
    forall a. Show a => a -> [Char]
    show SBV a
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    ". 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 :: forall a b.
    (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b,
     SymVal b) =>
    SBV a -> SBV b
    sFromIntegral 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
      = [Char] -> SBV b
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "SBV.sFromIntegral: Called on a real value" -- can't really happen due to types, but being overcautious
      | Just 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
            y :: State -> IO SV
    y 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 :: forall a b c. (SVal -> SVal -> SVal) -> SBV a -> SBV b -> SBV c
    liftViaSVal SVal -> SVal -> SVal
    f (SBV SVal
    a) (SBV 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 :: forall a b. (SIntegral a, SIntegral b) => 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 :: forall a b. (SIntegral a, SIntegral b) => 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 :: forall a b. (SFiniteBits a, SIntegral b) => SBV a -> SBV b -> SBV a
    sSignedShiftArithRight SBV a
    x SBV b
    i
      | SBV b -> Bool
    forall a. Bits a => a -> Bool
    isSigned SBV b
    i = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "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       = SBool -> SBV a -> SBV a -> SBV a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a -> SBool
    forall a. SFiniteBits a => SBV a -> SBool
    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 :: forall a b. (SIntegral a, SIntegral b) => 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`.
    sBarrelRotateLeft :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
    sBarrelRotateLeft :: forall a b.
    (SFiniteBits a, SFiniteBits b) =>
    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 :: forall a b. (SIntegral a, SIntegral b) => 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.
    sBarrelRotateRight :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a
    sBarrelRotateRight :: forall a b.
    (SFiniteBits a, SFiniteBits b) =>
    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 SBV a
    x
        | a
    v a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == (a
    forall a. Bounded a => a
    maxBound :: a) = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Enum.succ{" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> [Char]
    forall a. HasKind a => a -> [Char]
    showType SBV a
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "}: 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
    + a
    1
        where v :: a
    v = [Char] -> SBV a -> a
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "succ" SBV a
    x
      pred :: SBV a -> SBV a
    pred SBV a
    x
        | a
    v a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == (a
    forall a. Bounded a => a
    minBound :: a) = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Enum.pred{" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> [Char]
    forall a. HasKind a => a -> [Char]
    showType SBV a
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "}: 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
    - a
    1
        where v :: a
    v = [Char] -> SBV a -> a
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "pred" SBV a
    x
      toEnum :: Int -> SBV a
    toEnum 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)
        = [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Enum.toEnum{" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> [Char]
    forall a. HasKind a => a -> [Char]
    showType SBV a
    r [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "}: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Int -> [Char]
    forall a. Show a => a -> [Char]
    show Int
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is out-of-bounds " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (a, a) -> [Char]
    forall a. Show a => a -> [Char]
    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 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)
         = [Char] -> Int
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> Int) -> [Char] -> Int
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "Enum.fromEnum{" [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ SBV a -> [Char]
    forall a. HasKind a => a -> [Char]
    showType SBV a
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    "}:  value " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Integer -> [Char]
    forall a. Show a => a -> [Char]
    show Integer
    r [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " is outside of Int's bounds " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> [Char]
    forall a. Show a => a -> [Char]
    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 = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "fromEnum" SBV a
    x
      enumFrom :: SBV a -> [SBV a]
    enumFrom 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 = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "enumFrom" SBV a
    x
      enumFromThen :: SBV a -> SBV a -> [SBV a]
    enumFromThen SBV a
    x 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 = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "enumFromThen.x" SBV a
    x
                 yi :: Integer
    yi = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "enumFromThen.y" SBV a
    y
      enumFromThenTo :: SBV a -> SBV a -> SBV a -> [SBV a]
    enumFromThenTo SBV a
    x SBV a
    y 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 = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "enumFromThenTo.x" SBV a
    x
                 yi :: Integer
    yi = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "enumFromThenTo.y" SBV a
    y
                 zi :: Integer
    zi = [Char] -> SBV a -> Integer
    forall a b. (SymVal a, Integral a, Num b) => [Char] -> SBV a -> b
    enumCvt [Char]
    "enumFromThenTo.z" SBV a
    z

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

      a
    x `sQuot` 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
      a
    x `sRem`  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
      a
    x `sDiv`  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
      a
    x `sMod`  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 Word64
    x Word64
    0 = (Word64
    0, Word64
    x)
      sQuotRem Word64
    x 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  Word64
    x Word64
    0 = (Word64
    0, Word64
    x)
      sDivMod  Word64
    x 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 Int64
    x Int64
    0 = (Int64
    0, Int64
    x)
      sQuotRem Int64
    x 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  Int64
    x Int64
    0 = (Int64
    0, Int64
    x)
      sDivMod  Int64
    x 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 Word32
    x Word32
    0 = (Word32
    0, Word32
    x)
      sQuotRem Word32
    x 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  Word32
    x Word32
    0 = (Word32
    0, Word32
    x)
      sDivMod  Word32
    x 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 Int32
    x Int32
    0 = (Int32
    0, Int32
    x)
      sQuotRem Int32
    x 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  Int32
    x Int32
    0 = (Int32
    0, Int32
    x)
      sDivMod  Int32
    x 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 Word16
    x Word16
    0 = (Word16
    0, Word16
    x)
      sQuotRem Word16
    x 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  Word16
    x Word16
    0 = (Word16
    0, Word16
    x)
      sDivMod  Word16
    x 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 Int16
    x Int16
    0 = (Int16
    0, Int16
    x)
      sQuotRem Int16
    x 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  Int16
    x Int16
    0 = (Int16
    0, Int16
    x)
      sDivMod  Int16
    x 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 Word8
    x Word8
    0 = (Word8
    0, Word8
    x)
      sQuotRem Word8
    x 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  Word8
    x Word8
    0 = (Word8
    0, Word8
    x)
      sDivMod  Word8
    x 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 Int8
    x Int8
    0 = (Int8
    0, Int8
    x)
      sQuotRem Int8
    x 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  Int8
    x Int8
    0 = (Int8
    0, Int8
    x)
      sDivMod  Int8
    x 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 Integer
    x Integer
    0 = (Integer
    0, Integer
    x)
      sQuotRem Integer
    x 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  Integer
    x Integer
    0 = (Integer
    0, Integer
    x)
      sDivMod  Integer
    x 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 CV
    a CV
    b
        | CInteger Integer
    x <- CV -> CVal
    cvVal CV
    a, CInteger Integer
    y <- CV -> CVal
    cvVal CV
    b
        = let (Integer
    r1, 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 = CInteger r1 }, CV -> CV
    normCV CV
    b{ cvVal = CInteger r2 })
      sQuotRem CV
    a CV
    b = [Char] -> (CV, CV)
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> (CV, CV)) -> [Char] -> (CV, CV)
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.sQuotRem: impossible, unexpected args received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (CV, CV) -> [Char]
    forall a. Show a => a -> [Char]
    show (CV
    a, CV
    b)
      sDivMod :: CV -> CV -> (CV, CV)
    sDivMod CV
    a CV
    b
        | CInteger Integer
    x <- CV -> CVal
    cvVal CV
    a, CInteger Integer
    y <- CV -> CVal
    cvVal CV
    b
        = let (Integer
    r1, 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 = CInteger r1 }, CV -> CV
    normCV CV
    b{ cvVal = CInteger r2 })
      sDivMod CV
    a CV
    b = [Char] -> (CV, CV)
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> (CV, CV)) -> [Char] -> (CV, CV)
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.sDivMod: impossible, unexpected args received: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (CV, CV) -> [Char]
    forall a. Show a => a -> [Char]
    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 :: forall a. (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)
    liftQRem SBV a
    x 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
      = SBool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    y SBV a -> SBV a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== SBV a
    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 Kind
    sgnsz (Left CV
    a))) (SBV (SVal Kind
    _ (Left CV
    b))) = let (CV
    q, 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 Kind
    sgnsz Either CV (Cached SV)
    _))      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 Op
    o 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) (Integer
    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 :: forall a.
    (Ord a, SymVal a, Num a, SDivisible (SBV a)) =>
    SBV a -> SBV a -> (SBV a, SBV a)
    liftDMod SBV a
    x 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
      = SBool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a
    y SBV a -> SBV a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== SBV a
    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
    $ SBool -> (SBV a, SBV a) -> (SBV a, SBV a) -> (SBV a, SBV a)
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV a -> SBV a
    forall a. Num a => a -> a
    signum SBV a
    r SBV a -> SBV a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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@(SBV a
    q, 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) (Integer
    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) (Integer
    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 SBV Integer
    x 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
        = SBool
    -> (SBV Integer, SBV Integer)
    -> (SBV Integer, SBV Integer)
    -> (SBV Integer, SBV Integer)
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV Integer
    y SBV Integer -> SBV Integer -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== SBV Integer
    0) (SBV Integer
    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 (SBV Integer
    qE, 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 = SBool -> SBV Integer -> SBV Integer -> SBV Integer
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV Integer
    x SBV Integer -> SBV Integer -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .>= SBV Integer
    0 SBool -> SBool -> SBool
    .|| SBV Integer
    rE SBV Integer -> SBV Integer -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== SBV Integer
    0) SBV Integer
    0
                (SBV Integer -> SBV Integer) -> SBV Integer -> SBV Integer
    forall a b. (a -> b) -> a -> b
    $ SBool -> SBV Integer -> SBV Integer -> SBV Integer
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV Integer
    y SBV Integer -> SBV Integer -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .>  SBV Integer
    0)              SBV Integer
    1 (-SBV Integer
    1)

    -- | Euclidian division and modulus.
    sEDivMod :: SInteger -> SInteger -> (SInteger, SInteger)
    sEDivMod :: SBV Integer -> SBV Integer -> (SBV Integer, SBV Integer)
    sEDivMod SBV Integer
    a SBV Integer
    b = (SBV Integer
    a SBV Integer -> SBV Integer -> SBV Integer
    `sEDiv` SBV Integer
    b, SBV Integer
    a SBV Integer -> SBV Integer -> SBV Integer
    `sEMod` SBV Integer
    b)

    -- | Euclidian division.
    sEDiv :: SInteger -> SInteger -> SInteger
    sEDiv :: SBV Integer -> SBV Integer -> SBV Integer
    sEDiv (SBV SVal
    a) (SBV SVal
    b) = SVal -> SBV Integer
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Integer) -> SVal -> SBV Integer
    forall a b. (a -> b) -> a -> b
    $ SVal
    a SVal -> SVal -> SVal
    `svQuot` SVal
    b

    -- | Euclidian modulus.
    sEMod :: SInteger -> SInteger -> SInteger
    sEMod :: SBV Integer -> SBV Integer -> SBV Integer
    sEMod (SBV SVal
    a) (SBV SVal
    b) = SVal -> SBV Integer
    forall a. SVal -> SBV a
    SBV (SVal -> SBV Integer) -> SVal -> SBV Integer
    forall a b. (a -> b) -> a -> b
    $ SVal
    a SVal -> SVal -> SVal
    `svRem` SVal
    b

    -- 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 a b. (a -> b) -> Gen a -> Gen b
    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 [a]
    xs a
    err SBV b
    ind
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    isReal   SBV b
    ind = [Char] -> a
    forall a. [Char] -> a
    bad [Char]
    "real"
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    isFloat  SBV b
    ind = [Char] -> a
    forall a. [Char] -> a
    bad [Char]
    "float"
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    isDouble SBV b
    ind = [Char] -> a
    forall a. [Char] -> a
    bad [Char]
    "double"
        | SBV b -> Bool
    forall a. HasKind a => a -> Bool
    hasSign  SBV b
    ind = SBool -> a -> a -> a
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (SBV b
    ind SBV b -> SBV b -> SBool
    forall a. OrdSymbolic a => a -> a -> SBool
    .< SBV b
    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 :: [Char] -> a
    bad [Char]
    w = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> a) -> [Char] -> a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.select: unsupported " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    w [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " valued select/index expression"
              walk :: [t] -> a -> t -> t
    walk []     a
    _ t
    acc = t
    acc
              walk (t
    e:[t]
    es) a
    i t
    acc = [t] -> a -> t -> t
    walk [t]
    es (a
    ia -> a -> a
    forall a. Num a => a -> a -> a
    -a
    1) (SBool -> t -> t -> t
    forall a. Mergeable a => SBool -> a -> a -> a
    ite (a
    i a -> a -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== a
    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 -> SBool -> a -> a -> a
    forall a.
    (Generic a, GMergeable (Rep a)) =>
    Bool -> SBool -> 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 :: forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    t a
    a a
    b
      | Just Bool
    r <- SBool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBool
    t = if Bool
    r then a
    a else a
    b
      | Bool
    True                  = Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    True SBool
    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 :: forall a. Mergeable a => SBool -> a -> a -> a
    iteLazy SBool
    t a
    a a
    b
      | Just Bool
    r <- SBool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBool
    t = if Bool
    r then a
    a else a
    b
      | Bool
    True                  = Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    False SBool
    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 :: forall a.
    HasKind a =>
    Maybe CallStack -> [Char] -> SBool -> SBV a -> SBV a
    sAssert Maybe CallStack
    cs [Char]
    msg SBool
    cond SBV a
    x
       | Just Bool
    mustHold <- SBool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBool
    cond
       = if Bool
    mustHold
         then SBV a
    x
         else [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ SafeResult -> [Char]
    forall a. Show a => a -> [Char]
    show (SafeResult -> [Char]) -> SafeResult -> [Char]
    forall a b. (a -> b) -> a -> b
    $ (Maybe [Char], [Char], SMTResult) -> SafeResult
    SafeResult (([([Char], SrcLoc)] -> [Char]
    locInfo ([([Char], SrcLoc)] -> [Char])
    -> (CallStack -> [([Char], SrcLoc)]) -> CallStack -> [Char]
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . CallStack -> [([Char], SrcLoc)]
    getCallStack) (CallStack -> [Char]) -> Maybe CallStack -> Maybe [Char]
    forall a b. (a -> b) -> Maybe a -> Maybe b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Maybe CallStack
    cs, [Char]
    msg, SMTConfig -> SMTModel -> SMTResult
    Satisfiable SMTConfig
    defaultSMTCfg ([([Char], GeneralizedCV)]
    -> Maybe [(NamedSymVar, CV)]
    -> [([Char], CV)]
    -> [([Char], (SBVType, Either [Char] ([([CV], CV)], CV)))]
    -> SMTModel
    SMTModel [] Maybe [(NamedSymVar, 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 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 :: SBool
    pc = State -> SBool
    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 :: SBool
    mustNeverHappen = SBool
    pc SBool -> SBool -> SBool
    .&& SBool -> SBool
    sNot SBool
    cond
                       SV
    cnd <- State -> SBool -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBool
    mustNeverHappen
                       State -> Maybe CallStack -> [Char] -> SV -> IO ()
    addAssertion State
    st Maybe CallStack
    cs [Char]
    msg SV
    cnd
                       SV -> IO SV
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return SV
    xsv

            locInfo :: [([Char], SrcLoc)] -> [Char]
    locInfo [([Char], SrcLoc)]
    ps = [Char] -> [[Char]] -> [Char]
    forall a. [a] -> [[a]] -> [a]
    intercalate [Char]
    ",\n " ((([Char], SrcLoc) -> [Char]) -> [([Char], SrcLoc)] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char], SrcLoc) -> [Char]
    loc [([Char], SrcLoc)]
    ps)
              where loc :: ([Char], SrcLoc) -> [Char]
    loc ([Char]
    f, SrcLoc
    sl) = [[Char]] -> [Char]
    forall (t :: * -> *) a. Foldable t => t [a] -> [a]
    concat [SrcLoc -> [Char]
    srcLocFile SrcLoc
    sl, [Char]
    ":", Int -> [Char]
    forall a. Show a => a -> [Char]
    show (SrcLoc -> Int
    srcLocStartLine SrcLoc
    sl), [Char]
    ":", Int -> [Char]
    forall a. Show a => a -> [Char]
    show (SrcLoc -> Int
    srcLocStartCol SrcLoc
    sl), [Char]
    ":", [Char]
    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 :: forall a. Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind Kind
    k Bool
    force (SBV SVal
    t) (SBV SVal
    a) (SBV 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 -> SBool -> SBV a -> SBV a -> SBV a
    symbolicMerge Bool
    force SBool
    t SBV a
    x SBV a
    y
        -- Carefully use the kindOf instance to avoid strictness issues.
           | Bool
    force = Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
    forall a. Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind (SBV a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV a
    x)          Bool
    True  SBool
    t SBV a
    x SBV a
    y
           | Bool
    True  = Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
    forall a. Kind -> Bool -> SBool -> SBV a -> SBV a -> SBV a
    symbolicMergeWithKind (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)) Bool
    False SBool
    t SBV a
    x SBV a
    y
        -- Custom version of select that translates to SMT-Lib tables at the base type of words
        select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [SBV a] -> SBV a -> SBV b -> SBV a
    select [SBV a]
    xs SBV a
    err SBV b
    ind
          | SBV (SVal Kind
    _ (Left CV
    c)) <- SBV b
    ind = case CV -> CVal
    cvVal CV
    c of
                                             CInteger Integer
    i -> if Integer
    i Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    < Integer
    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
                                             CVal
    _          -> [Char] -> SBV a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> SBV a) -> [Char] -> SBV a
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.select: unsupported " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show (SBV b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV b
    ind) [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " valued select/index expression"
        select [SBV a]
    xsOrig SBV a
    err 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 Bool
    False Int
    i -> Integer -> [SBV a] -> [SBV a]
    forall i a. Integral i => i -> [a] -> [a]
    genericTake ((Integer
    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 Bool
    True  Int
    i -> Integer -> [SBV a] -> [SBV a]
    forall i a. Integral i => i -> [a] -> [a]
    genericTake ((Integer
    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
    -Int
    1) :: Integer)) [SBV a]
    xsOrig
                         Kind
    KUnbounded       -> [SBV a]
    xsOrig
                         Kind
    _                -> [Char] -> [SBV a]
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> [SBV a]) -> [Char] -> [SBV a]
    forall a b. (a -> b) -> a -> b
    $ [Char]
    "SBV.select: unsupported " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ Kind -> [Char]
    forall a. Show a => a -> [Char]
    show (SBV b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf SBV b
    ind) [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " valued select/index expression"
                r :: State -> IO SV
    r 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)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [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 a. a -> IO a
    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 a. [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) [])

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

    -- | Merge concrete values that can be checked for equality
    concreteMerge :: Show a => String -> String -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge :: forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    t [Char]
    st a -> a -> Bool
    eq a
    x a
    y
      | a
    x a -> a -> Bool
    `eq` a
    y = a
    x
      | Bool
    True     = [Char] -> [Char] -> [Char] -> a
    forall a. [Char] -> [Char] -> [Char] -> a
    cannotMerge [Char]
    t
                               ([Char]
    "Concrete values can only be merged when equal. Got: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    x [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " vs. " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ a -> [Char]
    forall a. Show a => a -> [Char]
    show a
    y)
                               ([Char]
    "Use an " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    st [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ [Char]
    " field if the values can differ.")

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

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

    -- Maybe
    instance Mergeable a => Mergeable (Maybe a) where
      symbolicMerge :: Bool -> SBool -> Maybe a -> Maybe a -> Maybe a
    symbolicMerge Bool
    _ SBool
    _ Maybe a
    Nothing  Maybe a
    Nothing  = Maybe a
    forall a. Maybe a
    Nothing
      symbolicMerge Bool
    f SBool
    t (Just a
    a) (Just 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 -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    a a
    b
      symbolicMerge Bool
    _ SBool
    _ Maybe a
    a Maybe a
    b = [Char] -> [Char] -> [Char] -> Maybe a
    forall a. [Char] -> [Char] -> [Char] -> a
    cannotMerge [Char]
    "'Maybe' values"
                                          ([Char]
    "Branches produce different constructors: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ ([Char], [Char]) -> [Char]
    forall a. Show a => a -> [Char]
    show (Maybe a -> [Char]
    forall {a}. Maybe a -> [Char]
    k Maybe a
    a, Maybe a -> [Char]
    forall {a}. Maybe a -> [Char]
    k Maybe a
    b))
                                          [Char]
    "Instead of an option type, try using a valid bit to indicate when a result is valid."
          where k :: Maybe a -> [Char]
    k Maybe a
    Nothing = [Char]
    "Nothing"
                k Maybe a
    _       = [Char]
    "Just"

    -- Either
    instance (Mergeable a, Mergeable b) => Mergeable (Either a b) where
      symbolicMerge :: Bool -> SBool -> Either a b -> Either a b -> Either a b
    symbolicMerge Bool
    f SBool
    t (Left a
    a)  (Left 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 -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    a a
    b
      symbolicMerge Bool
    f SBool
    t (Right b
    a) (Right 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 -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    a b
    b
      symbolicMerge Bool
    _ SBool
    _ Either a b
    a Either a b
    b = [Char] -> [Char] -> [Char] -> Either a b
    forall a. [Char] -> [Char] -> [Char] -> a
    cannotMerge [Char]
    "'Either' values"
                                          ([Char]
    "Branches produce different constructors: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ ([Char], [Char]) -> [Char]
    forall a. Show a => a -> [Char]
    show (Either a b -> [Char]
    forall {a} {b}. Either a b -> [Char]
    k Either a b
    a, Either a b -> [Char]
    forall {a} {b}. Either a b -> [Char]
    k Either a b
    b))
                                          [Char]
    "Consider using a product type by a tag instead."
         where k :: Either a b -> [Char]
    k (Left a
    _)  = [Char]
    "Left"
               k (Right b
    _) = [Char]
    "Right"

    -- Arrays
    instance (Ix a, Mergeable b) => Mergeable (Array a b) where
      symbolicMerge :: Bool -> SBool -> Array a b -> Array a b -> Array a b
    symbolicMerge Bool
    f SBool
    t Array a b
    a 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 -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    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     = [Char] -> [Char] -> [Char] -> Array a b
    forall a. [Char] -> [Char] -> [Char] -> a
    cannotMerge [Char]
    "'Array' values"
                                 ([Char]
    "Branches produce different ranges: " [Char] -> [Char] -> [Char]
    forall a. [a] -> [a] -> [a]
    ++ (Int, Int) -> [Char]
    forall a. Show a => a -> [Char]
    show ((a, a) -> Int
    k (a, a)
    ba, (a, a) -> Int
    k (a, a)
    bb))
                                 [Char]
    "Consider using SBV's native 'SArray' abstraction."
        where [(a, a)
    ba, (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 -> SBool -> (a -> b) -> (a -> b) -> a -> b
    symbolicMerge Bool
    f SBool
    t a -> b
    g a -> b
    h a
    x = Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    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 -> SBool -> (a, b) -> (a, b) -> (a, b)
    symbolicMerge Bool
    f SBool
    t (a
    i0, b
    i1) (a
    j0, b
    j1) = ( Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    i0 a
    j0
                                            , Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    i1 b
    j1
                                            )

      select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [(a, b)] -> (a, b) -> SBV b -> (a, b)
    select [(a, b)]
    xs (a
    err1, b
    err2) SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 ([a]
    as, [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 -> SBool -> (a, b, c) -> (a, b, c) -> (a, b, c)
    symbolicMerge Bool
    f SBool
    t (a
    i0, b
    i1, c
    i2) (a
    j0, b
    j1, c
    j2) = ( Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    i0 a
    j0
                                                    , Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    i1 b
    j1
                                                    , Bool -> SBool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t c
    i2 c
    j2
                                                    )

      select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [(a, b, c)] -> (a, b, c) -> SBV b -> (a, b, c)
    select [(a, b, c)]
    xs (a
    err1, b
    err2, c
    err3) SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 ([a]
    as, [b]
    bs, [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 -> SBool -> (a, b, c, d) -> (a, b, c, d) -> (a, b, c, d)
    symbolicMerge Bool
    f SBool
    t (a
    i0, b
    i1, c
    i2, d
    i3) (a
    j0, b
    j1, c
    j2, d
    j3) = ( Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    i0 a
    j0
                                                            , Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    i1 b
    j1
                                                            , Bool -> SBool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t c
    i2 c
    j2
                                                            , Bool -> SBool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t d
    i3 d
    j3
                                                            )

      select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [(a, b, c, d)] -> (a, b, c, d) -> SBV b -> (a, b, c, d)
    select [(a, b, c, d)]
    xs (a
    err1, b
    err2, c
    err3, d
    err4) SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 ([a]
    as, [b]
    bs, [c]
    cs, [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
    -> SBool -> (a, b, c, d, e) -> (a, b, c, d, e) -> (a, b, c, d, e)
    symbolicMerge Bool
    f SBool
    t (a
    i0, b
    i1, c
    i2, d
    i3, e
    i4) (a
    j0, b
    j1, c
    j2, d
    j3, e
    j4) = ( Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    i0 a
    j0
                                                                    , Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    i1 b
    j1
                                                                    , Bool -> SBool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t c
    i2 c
    j2
                                                                    , Bool -> SBool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t d
    i3 d
    j3
                                                                    , Bool -> SBool -> e -> e -> e
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t e
    i4 e
    j4
                                                                    )

      select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [(a, b, c, d, e)] -> (a, b, c, d, e) -> SBV b -> (a, b, c, d, e)
    select [(a, b, c, d, e)]
    xs (a
    err1, b
    err2, c
    err3, d
    err4, e
    err5) SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 ([a]
    as, [b]
    bs, [c]
    cs, [d]
    ds, [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
    -> SBool
    -> (a, b, c, d, e, f)
    -> (a, b, c, d, e, f)
    -> (a, b, c, d, e, f)
    symbolicMerge Bool
    f SBool
    t (a
    i0, b
    i1, c
    i2, d
    i3, e
    i4, f
    i5) (a
    j0, b
    j1, c
    j2, d
    j3, e
    j4, f
    j5) = ( Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    i0 a
    j0
                                                                            , Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    i1 b
    j1
                                                                            , Bool -> SBool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t c
    i2 c
    j2
                                                                            , Bool -> SBool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t d
    i3 d
    j3
                                                                            , Bool -> SBool -> e -> e -> e
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t e
    i4 e
    j4
                                                                            , Bool -> SBool -> f -> f -> f
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t f
    i5 f
    j5
                                                                            )

      select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [(a, b, c, d, e, f)]
    -> (a, b, c, d, e, f) -> SBV b -> (a, b, c, d, e, f)
    select [(a, b, c, d, e, f)]
    xs (a
    err1, b
    err2, c
    err3, d
    err4, e
    err5, f
    err6) SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 ([a]
    as, [b]
    bs, [c]
    cs, [d]
    ds, [e]
    es, [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
    -> SBool
    -> (a, b, c, d, e, f, g)
    -> (a, b, c, d, e, f, g)
    -> (a, b, c, d, e, f, g)
    symbolicMerge Bool
    f SBool
    t (a
    i0, b
    i1, c
    i2, d
    i3, e
    i4, f
    i5, g
    i6) (a
    j0, b
    j1, c
    j2, d
    j3, e
    j4, f
    j5, g
    j6) = ( Bool -> SBool -> a -> a -> a
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t a
    i0 a
    j0
                                                                                    , Bool -> SBool -> b -> b -> b
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t b
    i1 b
    j1
                                                                                    , Bool -> SBool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t c
    i2 c
    j2
                                                                                    , Bool -> SBool -> d -> d -> d
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t d
    i3 d
    j3
                                                                                    , Bool -> SBool -> e -> e -> e
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t e
    i4 e
    j4
                                                                                    , Bool -> SBool -> f -> f -> f
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t f
    i5 f
    j5
                                                                                    , Bool -> SBool -> g -> g -> g
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    f SBool
    t g
    i6 g
    j6
                                                                                    )

      select :: forall b.
    (Ord b, SymVal b, Num b) =>
    [(a, b, c, d, e, f, g)]
    -> (a, b, c, d, e, f, g) -> SBV b -> (a, b, c, d, e, f, g)
    select [(a, b, c, d, e, f, g)]
    xs (a
    err1, b
    err2, c
    err3, d
    err4, e
    err5, f
    err6, g
    err7) SBV b
    ind = ( [a] -> a -> SBV b -> a
    forall b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 b. (Ord b, SymVal b, Num b) => [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 ([a]
    as, [b]
    bs, [c]
    cs, [d]
    ds, [e]
    es, [f]
    fs, [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

    -- Base types are mergeable so long as they are equal
    instance Mergeable ()      where symbolicMerge :: Bool -> SBool -> () -> () -> ()
    symbolicMerge Bool
    _ SBool
    _ = [Char] -> [Char] -> (() -> () -> Bool) -> () -> () -> ()
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "()"      [Char]
    "()"        () -> () -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Integer where symbolicMerge :: Bool -> SBool -> Integer -> Integer -> Integer
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char]
    -> (Integer -> Integer -> Bool)
    -> Integer
    -> Integer
    -> Integer
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Integer" [Char]
    "SInteger"  Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Bool    where symbolicMerge :: Bool -> SBool -> Bool -> Bool -> Bool
    symbolicMerge Bool
    _ SBool
    _ = [Char] -> [Char] -> (Bool -> Bool -> Bool) -> Bool -> Bool -> Bool
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Bool"    [Char]
    "SBool"     Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Char    where symbolicMerge :: Bool -> SBool -> Char -> Char -> Char
    symbolicMerge Bool
    _ SBool
    _ = [Char] -> [Char] -> (Char -> Char -> Bool) -> Char -> Char -> Char
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Char"    [Char]
    "SChar"     Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Float   where symbolicMerge :: Bool -> SBool -> Float -> Float -> Float
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char] -> (Float -> Float -> Bool) -> Float -> Float -> Float
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Float"   [Char]
    "SFloat"    Float -> Float -> Bool
    forall a. RealFloat a => a -> a -> Bool
    fpIsEqualObjectH
    instance Mergeable Double  where symbolicMerge :: Bool -> SBool -> Double -> Double -> Double
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char]
    -> (Double -> Double -> Bool)
    -> Double
    -> Double
    -> Double
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Double"  [Char]
    "SDouble"   Double -> Double -> Bool
    forall a. RealFloat a => a -> a -> Bool
    fpIsEqualObjectH
    instance Mergeable Word8   where symbolicMerge :: Bool -> SBool -> Word8 -> Word8 -> Word8
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char] -> (Word8 -> Word8 -> Bool) -> Word8 -> Word8 -> Word8
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Word8"   [Char]
    "SWord8"    Word8 -> Word8 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Word16  where symbolicMerge :: Bool -> SBool -> Word16 -> Word16 -> Word16
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char]
    -> (Word16 -> Word16 -> Bool)
    -> Word16
    -> Word16
    -> Word16
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Word16"  [Char]
    "SWord16"   Word16 -> Word16 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Word32  where symbolicMerge :: Bool -> SBool -> Word32 -> Word32 -> Word32
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char]
    -> (Word32 -> Word32 -> Bool)
    -> Word32
    -> Word32
    -> Word32
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Word32"  [Char]
    "SWord32"   Word32 -> Word32 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Word64  where symbolicMerge :: Bool -> SBool -> Word64 -> Word64 -> Word64
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char]
    -> (Word64 -> Word64 -> Bool)
    -> Word64
    -> Word64
    -> Word64
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Word64"  [Char]
    "SWord64"   Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Int8    where symbolicMerge :: Bool -> SBool -> Int8 -> Int8 -> Int8
    symbolicMerge Bool
    _ SBool
    _ = [Char] -> [Char] -> (Int8 -> Int8 -> Bool) -> Int8 -> Int8 -> Int8
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Int8"    [Char]
    "SInt8"     Int8 -> Int8 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Int16   where symbolicMerge :: Bool -> SBool -> Int16 -> Int16 -> Int16
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char] -> (Int16 -> Int16 -> Bool) -> Int16 -> Int16 -> Int16
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Int16"   [Char]
    "SInt16"    Int16 -> Int16 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Int32   where symbolicMerge :: Bool -> SBool -> Int32 -> Int32 -> Int32
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char] -> (Int32 -> Int32 -> Bool) -> Int32 -> Int32 -> Int32
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Int32"   [Char]
    "SInt32"    Int32 -> Int32 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)
    instance Mergeable Int64   where symbolicMerge :: Bool -> SBool -> Int64 -> Int64 -> Int64
    symbolicMerge Bool
    _ SBool
    _ = [Char]
    -> [Char] -> (Int64 -> Int64 -> Bool) -> Int64 -> Int64 -> Int64
    forall a.
    Show a =>
    [Char] -> [Char] -> (a -> a -> Bool) -> a -> a -> a
    concreteMerge [Char]
    "Int64"   [Char]
    "SInt64"    Int64 -> Int64 -> Bool
    forall a. Eq a => a -> a -> Bool
    (==)

    -- 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 :: forall a.
    (Generic a, GMergeable (Rep a)) =>
    Bool -> SBool -> a -> a -> a
    symbolicMergeDefault Bool
    force SBool
    t a
    x a
    y = Rep a Any -> a
    forall a x. Generic a => Rep a x -> a
    forall x. Rep a x -> a
    G.to (Rep a Any -> a) -> Rep a Any -> a
    forall a b. (a -> b) -> a -> b
    $ Bool -> SBool -> Rep a Any -> Rep a Any -> Rep a Any
    forall a. Bool -> SBool -> Rep a a -> Rep a a -> Rep a a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBool
    t (a -> Rep a Any
    forall x. a -> Rep a x
    forall a x. Generic a => a -> Rep a x
    G.from a
    x) (a -> Rep a Any
    forall x. a -> Rep a x
    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

    {-
     - N.B. A V1 instance like the below would be wrong!
     - Why? Because inSBV, we use empty data to mean "uninterpreted" sort; not
     - something that has no constructors. Perhaps that was a bad design
     - decision. So, do not allow merging of such values!
    instance GMergeable V1 where
      symbolicMerge' _ _ x _ = x
    -}

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

    instance (Mergeable c) => GMergeable (K1 i c) where
      symbolicMerge' :: forall a. Bool -> SBool -> K1 i c a -> K1 i c a -> K1 i c a
    symbolicMerge' Bool
    force SBool
    t (K1 c
    x) (K1 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 -> SBool -> c -> c -> c
    forall a. Mergeable a => Bool -> SBool -> a -> a -> a
    symbolicMerge Bool
    force SBool
    t c
    x c
    y

    instance (GMergeable f) => GMergeable (M1 i c f) where
      symbolicMerge' :: forall a. Bool -> SBool -> M1 i c f a -> M1 i c f a -> M1 i c f a
    symbolicMerge' Bool
    force SBool
    t (M1 f a
    x) (M1 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 -> SBool -> f a -> f a -> f a
    forall a. Bool -> SBool -> f a -> f a -> f a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBool
    t f a
    x f a
    y

    instance (GMergeable f, GMergeable g) => GMergeable (f :*: g) where
      symbolicMerge' :: forall a.
    Bool -> SBool -> (:*:) f g a -> (:*:) f g a -> (:*:) f g a
    symbolicMerge' Bool
    force SBool
    t (f a
    x1 :*: g a
    y1) (f a
    x2 :*: g a
    y2) = Bool -> SBool -> f a -> f a -> f a
    forall a. Bool -> SBool -> f a -> f a -> f a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBool
    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 -> SBool -> g a -> g a -> g a
    forall a. Bool -> SBool -> g a -> g a -> g a
    forall (f :: * -> *) a.
    GMergeable f =>
    Bool -> SBool -> f a -> f a -> f a
    symbolicMerge' Bool
    force SBool
    t g a
    y1 g a
    y2

    {- A mergeable instance for sum-types isn't possible. Why? It would something like:

    instance (GMergeable f, GMergeable g) => GMergeable (f :+: g) where
      symbolicMerge' force t (L1 x) (L1 y) = L1 $ symbolicMerge' force t x y
      symbolicMerge' force t (R1 x) (R1 y) = R1 $ symbolicMerge' force t x y
      symbolicMerge' force t l r
        | Just tv <- unliteral t = if tv then l else r
        | True                   = ????

    There's really no good code to put in ????. We have no way to ask the SMT solver to merge composite values that
    have different constructors. Calling "error" here would pass the type-checker, but that simply postpones the problem
    to run-time. If you need mergeable on sum-types, you better write one yourself, possibly using the SEither type yourself.
    As we have it, you'll get a type-error; which can be hard to read, but is preferable.

    NB. This isn't a problem with the generic version of symbolic equality; since we can simply return sFalse if we
    see different constructors. Such isn't the case when merging.
    -}

    -- 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 SArr
    a .== :: SArray a b -> SArray a b -> SBool
    .== SArray SArr
    b = SVal -> SBool
    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 -> SBool -> SArray a b -> SArray a b -> SArray a b
    symbolicMerge Bool
    _ = SBool -> SArray a b -> SArray a b -> SArray a b
    forall b a.
    SymVal b =>
    SBool -> SArray a b -> SArray a b -> SArray a b
    forall (array :: * -> * -> *) b a.
    (SymArray array, SymVal b) =>
    SBool -> array a b -> array a b -> array a b
    mergeArrays

    -- | SMT definable constants and functions, which can also be uninterpeted.
    -- This class captures functions that we can generate standalone-code for
    -- in the SMT solver. Note that we also allow uninterpreted constants and
    -- functions too. 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: 'sbvDefineValue'. However, most instances in
    -- practice are already provided by SBV, so end-users should not need to define their
    -- own instances.
    class SMTDefinable a where
      -- | Generate the code for this value as an SMTLib function, instead of
      -- the usual unrolling semantics. This is useful for generating sub-functions
      -- in generated SMTLib problem, or handling recursive (and mutually-recursive)
      -- definitions that wouldn't terminate in an unrolling symbolic simulation context.
      --
      -- __IMPORTANT NOTE__ The string argument names this function. Note that SBV will identify
      -- this function with that name, i.e., if you use this function twice (or use it recursively),
      -- it will simply assume this name uniquely identifies the function being defined. Hence,
      -- the user has to assure that this string is unique amongst all the functions you use.
      -- Furthermore, if the call to 'smtFunction' happens in the scope of a parameter, you
      -- must make sure the string is chosen to keep it unique per parameter value. For instance,
      -- if you have:
      --
      -- @
      --   bar :: SInteger -> SInteger -> SInteger
      --   bar k = smtFunction "bar" (\x -> x+k)   -- Note the capture of k!
      -- @
      --
      -- and you call @bar 2@ and @bar 3@, you *will* get the same SMTLib function. Obviously
      -- this is unsound. The reason is that the parameter value isn't captured by the name. In general,
      -- you should simply not do this, but if you must, have a concrete argument to make sure you can
      -- create a unique name. Something like:
      --
      -- @
      --   bar :: String -> SInteger -> SInteger -> SInteger
      --   bar tag k = smtFunction ("bar_" ++ tag) (\x -> x+k)   -- Tag should make the name unique!
      -- @
      --
      -- Then, make sure you use @bar "two" 2@ and @bar "three" 3@ etc. to preserve the invariant.
      --
      -- Note that this is a design choice, to keep function creation as easy to use as possible. SBV
      -- could've made 'smtFunction' a monadic call and generated the name itself to avoid all these issues.
      -- But the ergonomics of that is worse, and doesn't fit with the general design philosophy. If you
      -- can think of a solution (perhaps using some nifty GHC tricks?) to avoid this issue without making
      -- 'smtFunction' return a monadic result, please get in touch!
      smtFunction :: Lambda Symbolic a => String -> a -> a

      -- | Uninterpret a value, i.e., add this value as a completely undefined value/function that
      -- the solver is free to instantiate to satisfy other constraints.
      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.
      sbvDefineValue :: String -> UIKind a -> a

      -- | A synonym for 'uninterpret'. Allows us to create variables without
      -- having to call 'free' explicitly, i.e., without being in the symbolic monad.
      sym :: String -> a

      {-# MINIMAL sbvDefineValue #-}

      -- defaults:
      uninterpret    [Char]
    nm        = [Char] -> UIKind a -> a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm   UIKind a
    forall a. UIKind a
    UIFree
      smtFunction    [Char]
    nm      a
    v = [Char] -> UIKind a -> a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (UIKind a -> a) -> UIKind a -> a
    forall a b. (a -> b) -> a -> b
    $ (a, State -> Kind -> IO SMTDef) -> UIKind a
    forall a. (a, State -> Kind -> IO SMTDef) -> UIKind a
    UIFun   (a
    v, \State
    st Kind
    fk -> State -> [Char] -> Kind -> a -> IO SMTDef
    forall (m :: * -> *) a.
    (MonadIO m, Lambda (SymbolicT m) a) =>
    State -> [Char] -> Kind -> a -> m SMTDef
    namedLambda State
    st [Char]
    nm Kind
    fk a
    v)
      cgUninterpret  [Char]
    nm [[Char]]
    code a
    v = [Char] -> UIKind a -> a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (UIKind a -> a) -> UIKind a -> a
    forall a b. (a -> b) -> a -> b
    $ (a, [[Char]]) -> UIKind a
    forall a. (a, [[Char]]) -> UIKind a
    UICodeC (a
    v, [[Char]]
    code)
      sym                      = [Char] -> a
    forall a. SMTDefinable a => [Char] -> a
    uninterpret

    -- | Kind of uninterpretation
    data UIKind a = UIFree                                  -- ^ completely uninterpreted
                  | UIFun   (a, State -> Kind -> IO SMTDef) -- ^ has code for SMTLib, with final type of kind (note this is the result
                                                            -- , not the arguments), which can be generated by calling the function on the state.
                  | UICodeC (a, [String])                   -- ^ has code for code-generation, i.e., C
                  deriving (forall a b. (a -> b) -> UIKind a -> UIKind b)
    -> (forall a b. a -> UIKind b -> UIKind a) -> Functor UIKind
    forall a b. a -> UIKind b -> UIKind a
    forall a b. (a -> b) -> UIKind a -> UIKind b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall a b. (a -> b) -> UIKind a -> UIKind b
    fmap :: forall a b. (a -> b) -> UIKind a -> UIKind b
    $c<$ :: forall a b. a -> UIKind b -> UIKind a
    <$ :: forall a b. a -> UIKind b -> UIKind a
    Functor

    -- Get the code associated with the UI, unless we've already did this once. (To support recursive defs.)
    retrieveUICode :: String -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode :: forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    _  State
    _  Kind
    _  UIKind a
    UIFree           = UICodeKind -> IO UICodeKind
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure UICodeKind
    UINone
    retrieveUICode [Char]
    nm State
    st Kind
    fk (UIFun   (a
    _, State -> Kind -> IO SMTDef
    f)) = do Set [Char]
    userFuncs <- IORef (Set [Char]) -> IO (Set [Char])
    forall a. IORef a -> IO a
    readIORef (State -> IORef (Set [Char])
    rUserFuncs State
    st)
                                                  if [Char]
    nm [Char] -> Set [Char] -> Bool
    forall a. Ord a => a -> Set a -> Bool
    `Set.member` Set [Char]
    userFuncs
                                                     then UICodeKind -> IO UICodeKind
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure UICodeKind
    UINone
                                                     else do State
    -> (State -> IORef (Set [Char]))
    -> (Set [Char] -> Set [Char])
    -> IO ()
    -> IO ()
    forall a. State -> (State -> IORef a) -> (a -> a) -> IO () -> IO ()
    modifyState State
    st State -> IORef (Set [Char])
    rUserFuncs ([Char] -> Set [Char] -> Set [Char]
    forall a. Ord a => a -> Set a -> Set a
    Set.insert [Char]
    nm) (() -> IO ()
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ())
                                                             SMTDef -> UICodeKind
    UISMT (SMTDef -> UICodeKind) -> IO SMTDef -> IO UICodeKind
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> State -> Kind -> IO SMTDef
    f State
    st Kind
    fk
    retrieveUICode [Char]
    _  State
    _  Kind
    _  (UICodeC (a
    _, [[Char]]
    c)) = UICodeKind -> IO UICodeKind
    forall a. a -> IO a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (UICodeKind -> IO UICodeKind) -> UICodeKind -> IO UICodeKind
    forall a b. (a -> b) -> a -> b
    $ [[Char]] -> UICodeKind
    UICgC [[Char]]
    c

    -- Get the constant value associated with the UI
    retrieveConstCode :: UIKind a -> Maybe a
    retrieveConstCode :: forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind a
    UIFree           = Maybe a
    forall a. Maybe a
    Nothing
    retrieveConstCode (UIFun   (a
    v, State -> Kind -> IO SMTDef
    _)) = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    v
    retrieveConstCode (UICodeC (a
    v, [[Char]]
    _)) = a -> Maybe a
    forall a. a -> Maybe a
    Just a
    v

    -- Plain constants
    instance HasKind a => SMTDefinable (SBV a) where
      sbvDefineValue :: [Char] -> UIKind (SBV a) -> SBV a
    sbvDefineValue [Char]
    nm UIKind (SBV a)
    uiKind
         | Just SBV a
    v <- UIKind (SBV a) -> Maybe (SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind (SBV a)
    uiKind
         = 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
              result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                             case (Bool
    isSMT, UIKind (SBV a)
    uiKind) of
                               (Bool
    True, UICodeC (SBV a
    v, [[Char]]
    _)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st SBV a
    v
                               (Bool, UIKind (SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char] -> State -> Kind -> UIKind (SBV a) -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind (SBV a)
    uiKind
                                                            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 ([Char] -> Op
    Uninterpreted [Char]
    nm) []

    -- Functions of one argument
    instance (SymVal b, HasKind a) => SMTDefinable (SBV b -> SBV a) where
      sbvDefineValue :: [Char] -> UIKind (SBV b -> SBV a) -> SBV b -> SBV a
    sbvDefineValue [Char]
    nm UIKind (SBV b -> SBV a)
    uiKind = SBV b -> SBV a
    f
        where f :: SBV b -> SBV a
    f SBV b
    arg0
               | Just SBV b -> SBV a
    v <- UIKind (SBV b -> SBV a) -> Maybe (SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind (SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind (SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV b -> SBV a
    v, [[Char]]
    _)) -> State -> SBV a -> IO SV
    forall a. State -> SBV a -> IO SV
    sbvToSV State
    st (SBV b -> SBV a
    v SBV b
    arg0)
                                      (Bool, UIKind (SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char] -> State -> Kind -> UIKind (SBV b -> SBV a) -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind (SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    nm) [SV
    sw0]

    -- Functions of two arguments
    instance (SymVal c, SymVal b, HasKind a) => SMTDefinable (SBV c -> SBV b -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind (SBV c -> SBV b -> SBV a) -> SBV c -> SBV b -> SBV a
    sbvDefineValue [Char]
    nm UIKind (SBV c -> SBV b -> SBV a)
    uiKind = SBV c -> SBV b -> SBV a
    f
        where f :: SBV c -> SBV b -> SBV a
    f SBV c
    arg0 SBV b
    arg1
               | Just SBV c -> SBV b -> SBV a
    v <- UIKind (SBV c -> SBV b -> SBV a) -> Maybe (SBV c -> SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind (SBV c -> SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @c)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind (SBV c -> SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV c -> SBV b -> SBV a
    v, [[Char]]
    _)) -> 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)
                                      (Bool, UIKind (SBV c -> SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    kc, Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char]
    -> State
    -> Kind
    -> UIKind (SBV c -> SBV b -> SBV a)
    -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind (SBV c -> SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    nm) [SV
    sw0, SV
    sw1]

    -- Functions of three arguments
    instance (SymVal d, SymVal c, SymVal b, HasKind a) => SMTDefinable (SBV d -> SBV c -> SBV b -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    uiKind = SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV d -> SBV c -> SBV b -> SBV a
    f SBV d
    arg0 SBV c
    arg1 SBV b
    arg2
               | Just SBV d -> SBV c -> SBV b -> SBV a
    v <- UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe (SBV d -> SBV c -> SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @d)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV d -> SBV c -> SBV b -> SBV a
    v, [[Char]]
    _)) -> 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)
                                      (Bool, UIKind (SBV d -> SBV c -> SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char]
    -> State
    -> Kind
    -> UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    nm) [SV
    sw0, SV
    sw1, SV
    sw2]

    -- Functions of four arguments
    instance (SymVal e, SymVal d, SymVal c, SymVal b, HasKind a) => SMTDefinable (SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind = SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f
        where f :: SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV e
    arg0 SBV d
    arg1 SBV c
    arg2 SBV b
    arg3
               | Just SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v <- UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @e)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v, [[Char]]
    _)) -> 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)
                                      (Bool, UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char]
    -> State
    -> Kind
    -> UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    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) => SMTDefinable (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind = 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 SBV f
    arg0 SBV e
    arg1 SBV d
    arg2 SBV c
    arg3 SBV b
    arg4
               | Just SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v <- UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @e)
                     kf :: Kind
    kf = Proxy f -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @f)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v, [[Char]]
    _)) -> 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)
                                      (Bool, UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    kf, Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char]
    -> State
    -> Kind
    -> UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    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) => SMTDefinable (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind
         (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind
      (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind = 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 SBV g
    arg0 SBV f
    arg1 SBV e
    arg2 SBV d
    arg3 SBV c
    arg4 SBV b
    arg5
               | Just SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v <- UIKind
      (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe
         (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind
      (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @e)
                     kf :: Kind
    kf = Proxy f -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @f)
                     kg :: Kind
    kg = Proxy g -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @g)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind
      (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v, [[Char]]
    _)) -> 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)
                                      (Bool,
     UIKind
       (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    kg, Kind
    kf, Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char]
    -> State
    -> Kind
    -> UIKind
         (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind
      (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    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)
                => SMTDefinable (SBV h -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind
         (SBV h
          -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV h
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind
      (SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind = 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 SBV h
    arg0 SBV g
    arg1 SBV f
    arg2 SBV e
    arg3 SBV d
    arg4 SBV c
    arg5 SBV b
    arg6
               | Just SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v <- UIKind
      (SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> Maybe
         (SBV h
          -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall a. UIKind a -> Maybe a
    retrieveConstCode UIKind
      (SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind, 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a)
                     kb :: Kind
    kb = Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
                     kc :: Kind
    kc = Proxy c -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @c)
                     kd :: Kind
    kd = Proxy d -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @d)
                     ke :: Kind
    ke = Proxy e -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @e)
                     kf :: Kind
    kf = Proxy f -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @f)
                     kg :: Kind
    kg = Proxy g -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @g)
                     kh :: Kind
    kh = Proxy h -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @h)
                     result :: State -> IO SV
    result State
    st = do Bool
    isSMT <- State -> IO Bool
    inSMTMode State
    st
                                    case (Bool
    isSMT, UIKind
      (SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind) of
                                      (Bool
    True, UICodeC (SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    v, [[Char]]
    _)) -> 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)
                                      (Bool,
     UIKind
       (SBV h
        -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a))
    _                      -> do State -> ([Char], Maybe [[Char]]) -> SBVType -> UICodeKind -> IO ()
    newUninterpreted State
    st ([Char]
    nm, Maybe [[Char]]
    forall a. Maybe a
    Nothing) ([Kind] -> SBVType
    SBVType [Kind
    kh, Kind
    kg, Kind
    kf, Kind
    ke, Kind
    kd, Kind
    kc, Kind
    kb, Kind
    ka]) (UICodeKind -> IO ()) -> IO UICodeKind -> IO ()
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< [Char]
    -> State
    -> Kind
    -> UIKind
         (SBV h
          -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> IO UICodeKind
    forall a. [Char] -> State -> Kind -> UIKind a -> IO UICodeKind
    retrieveUICode [Char]
    nm State
    st Kind
    ka UIKind
      (SBV h
       -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    uiKind
                                                                   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 ([Char] -> Op
    Uninterpreted [Char]
    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) => SMTDefinable ((SBV c, SBV b) -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind ((SBV c, SBV b) -> SBV a) -> (SBV c, SBV b) -> SBV a
    sbvDefineValue [Char]
    nm UIKind ((SBV c, SBV b) -> SBV a)
    uiKind = let f :: SBV c -> SBV b -> SBV a
    f = [Char]
    -> UIKind (SBV c -> SBV b -> SBV a) -> SBV c -> SBV b -> SBV a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (((SBV c, SBV b) -> SBV a) -> SBV c -> SBV b -> SBV a
    forall a b c. ((a, b) -> c) -> a -> b -> c
    curry (((SBV c, SBV b) -> SBV a) -> SBV c -> SBV b -> SBV a)
    -> UIKind ((SBV c, SBV b) -> SBV a)
    -> UIKind (SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> UIKind ((SBV c, SBV b) -> SBV a)
    uiKind) 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

    -- Uncurried functions of three arguments
    instance (SymVal d, SymVal c, SymVal b, HasKind a) => SMTDefinable ((SBV d, SBV c, SBV b) -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind ((SBV d, SBV c, SBV b) -> SBV a)
    -> (SBV d, SBV c, SBV b)
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind ((SBV d, SBV c, SBV b) -> SBV a)
    uiKind = let f :: SBV d -> SBV c -> SBV b -> SBV a
    f = [Char]
    -> UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (((SBV d, SBV c, SBV b) -> SBV a)
    -> SBV d -> SBV c -> SBV b -> SBV a
    forall {a} {b} {c} {t}. ((a, b, c) -> t) -> a -> b -> c -> t
    uc3 (((SBV d, SBV c, SBV b) -> SBV a)
     -> SBV d -> SBV c -> SBV b -> SBV a)
    -> UIKind ((SBV d, SBV c, SBV b) -> SBV a)
    -> UIKind (SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> UIKind ((SBV d, SBV c, SBV b) -> SBV a)
    uiKind) in \(SBV d
    arg0, SBV c
    arg1, SBV b
    arg2) -> SBV d -> SBV c -> SBV b -> SBV a
    f SBV d
    arg0 SBV c
    arg1 SBV b
    arg2
        where uc3 :: ((a, b, c) -> t) -> a -> b -> c -> t
    uc3 (a, b, c) -> t
    fn a
    a b
    b 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)
                => SMTDefinable ((SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind ((SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> (SBV e, SBV d, SBV c, SBV b)
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind ((SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind = let f :: SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = [Char]
    -> UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (((SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    forall {a} {b} {c} {d} {t}.
    ((a, b, c, d) -> t) -> a -> b -> c -> d -> t
    uc4 (((SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> UIKind ((SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> UIKind (SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> UIKind ((SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind) in \(SBV e
    arg0, SBV d
    arg1, SBV c
    arg2, 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, b, c, d) -> t) -> a -> b -> c -> d -> t
    uc4 (a, b, c, d) -> t
    fn a
    a b
    b c
    c 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)
                => SMTDefinable ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> (SBV f, SBV e, SBV d, SBV c, SBV b)
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind = let f :: SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = [Char]
    -> UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    forall {a} {b} {c} {d} {e} {t}.
    ((a, b, c, d, e) -> t) -> a -> b -> c -> d -> e -> t
    uc5 (((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> UIKind ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> UIKind (SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> UIKind ((SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind) in \(SBV f
    arg0, SBV e
    arg1, SBV d
    arg2, SBV c
    arg3, 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, b, c, d, e) -> t) -> a -> b -> c -> d -> e -> t
    uc5 (a, b, c, d, e) -> t
    fn a
    a b
    b c
    c d
    d 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)
                => SMTDefinable ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> (SBV g, SBV f, SBV e, SBV d, SBV c, SBV b)
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind = let f :: SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = [Char]
    -> UIKind
         (SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    forall {a} {b} {c} {d} {e} {f} {t}.
    ((a, b, c, d, e, f) -> t) -> a -> b -> c -> d -> e -> f -> t
    uc6 (((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> UIKind ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> UIKind
         (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
    <$> UIKind ((SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind) in \(SBV g
    arg0, SBV f
    arg1, SBV e
    arg2, SBV d
    arg3, SBV c
    arg4, 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, b, c, d, e, f) -> t) -> a -> b -> c -> d -> e -> f -> t
    uc6 (a, b, c, d, e, f) -> t
    fn a
    a b
    b c
    c d
    d e
    e 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)
                => SMTDefinable ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a) where
      sbvDefineValue :: [Char]
    -> UIKind
         ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> (SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b)
    -> SBV a
    sbvDefineValue [Char]
    nm UIKind ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind = let f :: SBV h
    -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a
    f = [Char]
    -> UIKind
         (SBV h
          -> SBV g -> SBV f -> SBV e -> SBV d -> SBV c -> SBV b -> SBV a)
    -> SBV h
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall a. SMTDefinable a => [Char] -> UIKind a -> a
    sbvDefineValue [Char]
    nm (((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> SBV h
    -> SBV g
    -> SBV f
    -> SBV e
    -> SBV d
    -> SBV c
    -> SBV b
    -> SBV a
    forall {a} {b} {c} {d} {e} {f} {g} {t}.
    ((a, b, c, d, e, f, g) -> t)
    -> a -> b -> c -> d -> e -> f -> g -> t
    uc7 (((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
     -> SBV h
     -> SBV g
     -> SBV f
     -> SBV e
     -> SBV d
     -> SBV c
     -> SBV b
     -> SBV a)
    -> UIKind
         ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    -> UIKind
         (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
    <$> UIKind ((SBV h, SBV g, SBV f, SBV e, SBV d, SBV c, SBV b) -> SBV a)
    uiKind) in \(SBV h
    arg0, SBV g
    arg1, SBV f
    arg2, SBV e
    arg3, SBV d
    arg4, SBV c
    arg5, 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, b, c, d, e, f, g) -> t)
    -> a -> b -> c -> d -> e -> f -> g -> t
    uc7 (a, b, c, d, e, f, g) -> t
    fn a
    a b
    b c
    c d
    d e
    e f
    f 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 :: forall a. QuantifiedBool a => a -> SymbolicT m ()
    constrain                   = Bool -> [([Char], [Char])] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [([Char], [Char])] -> SVal -> m ()
    imposeConstraint Bool
    False []               (SVal -> SymbolicT m ()) -> (a -> SVal) -> a -> SymbolicT m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SBool -> SVal
    forall a. SBV a -> SVal
    unSBV (SBool -> SVal) -> (a -> SBool) -> a -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> SBool
    forall a. QuantifiedBool a => a -> SBool
    quantifiedBool
       softConstrain :: forall a. QuantifiedBool a => a -> SymbolicT m ()
    softConstrain               = Bool -> [([Char], [Char])] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [([Char], [Char])] -> SVal -> m ()
    imposeConstraint Bool
    True  []               (SVal -> SymbolicT m ()) -> (a -> SVal) -> a -> SymbolicT m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SBool -> SVal
    forall a. SBV a -> SVal
    unSBV (SBool -> SVal) -> (a -> SBool) -> a -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> SBool
    forall a. QuantifiedBool a => a -> SBool
    quantifiedBool
       namedConstraint :: forall a. QuantifiedBool a => [Char] -> a -> SymbolicT m ()
    namedConstraint        [Char]
    nm   = Bool -> [([Char], [Char])] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [([Char], [Char])] -> SVal -> m ()
    imposeConstraint Bool
    False [([Char]
    ":named", [Char]
    nm)] (SVal -> SymbolicT m ()) -> (a -> SVal) -> a -> SymbolicT m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SBool -> SVal
    forall a. SBV a -> SVal
    unSBV (SBool -> SVal) -> (a -> SBool) -> a -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> SBool
    forall a. QuantifiedBool a => a -> SBool
    quantifiedBool
       constrainWithAttribute :: forall a.
    QuantifiedBool a =>
    [([Char], [Char])] -> a -> SymbolicT m ()
    constrainWithAttribute [([Char], [Char])]
    atts = Bool -> [([Char], [Char])] -> SVal -> SymbolicT m ()
    forall (m :: * -> *).
    MonadSymbolic m =>
    Bool -> [([Char], [Char])] -> SVal -> m ()
    imposeConstraint Bool
    False [([Char], [Char])]
    atts             (SVal -> SymbolicT m ()) -> (a -> SVal) -> a -> SymbolicT m ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . SBool -> SVal
    forall a. SBV a -> SVal
    unSBV (SBool -> SVal) -> (a -> SBool) -> a -> SVal
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> SBool
    forall a. QuantifiedBool a => a -> SBool
    quantifiedBool

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

    -- | Generalization of 'Data.SBV.assertWithPenalty'
    assertWithPenalty :: MonadSymbolic m => String -> SBool -> Penalty -> m ()
    assertWithPenalty :: forall (m :: * -> *).
    MonadSymbolic m =>
    [Char] -> SBool -> Penalty -> m ()
    assertWithPenalty [Char]
    nm SBool
    o 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
    $ SBool -> SVal
    forall a. SBV a -> SVal
    unSBV (SBool -> SVal) -> Objective SBool -> Objective SVal
    forall a b. (a -> b) -> Objective a -> Objective b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` [Char] -> SBool -> Penalty -> Objective SBool
    forall a. [Char] -> a -> Penalty -> Objective a
    AssertWithPenalty [Char]
    nm SBool
    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
      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 [Char]
    nm 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 a b. (a -> b) -> Objective a -> Objective b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` [Char] -> SBV (MetricSpace a) -> Objective (SBV (MetricSpace a))
    forall a. [Char] -> a -> Objective a
    Minimize [Char]
    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 [Char]
    nm 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 a b. (a -> b) -> Objective a -> Objective b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` [Char] -> SBV (MetricSpace a) -> Objective (SBV (MetricSpace a))
    forall a. [Char] -> a -> Objective a
    Maximize [Char]
    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 a
    SBV a -> SBV (MetricSpace a)
    forall a. a -> a
    id

      default fromMetricSpace :: (a ~ MetricSpace a) => SBV (MetricSpace a) -> SBV a
      fromMetricSpace = SBV a -> SBV a
    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 :: SBool -> SBV (MetricSpace Bool)
    toMetricSpace SBool
    t       = SBool -> SBV Word8 -> SBV Word8 -> SBV Word8
    forall a. Mergeable a => SBool -> a -> a -> a
    ite SBool
    t SBV Word8
    1 SBV Word8
    0
      fromMetricSpace :: SBV (MetricSpace Bool) -> SBool
    fromMetricSpace SBV (MetricSpace Bool)
    w     = SBV Word8
    SBV (MetricSpace Bool)
    w SBV Word8 -> SBV Word8 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    ./= SBV Word8
    0

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

    -- | Generalization of 'Data.SBV.maximize'
    maximize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()
    maximize :: forall a (m :: * -> *).
    (Metric a, MonadSymbolic m, SolverContext m) =>
    [Char] -> SBV a -> m ()
    maximize = [Char] -> SBV a -> m ()
    forall a (m :: * -> *).
    (Metric a, MonadSymbolic m, SolverContext m) =>
    [Char] -> SBV a -> m ()
    forall (m :: * -> *).
    (MonadSymbolic m, SolverContext m) =>
    [Char] -> 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    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
    + SBV Word8
    128  -- 2^7
      fromMetricSpace :: SBV (MetricSpace Int8) -> SBV Int8
    fromMetricSpace  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
    - SBV Int8
    128

    instance Metric Int16 where
      type MetricSpace Int16 = Word16
      toMetricSpace :: SBV Int16 -> SBV (MetricSpace Int16)
    toMetricSpace    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
    + SBV Word16
    32768  -- 2^15
      fromMetricSpace :: SBV (MetricSpace Int16) -> SBV Int16
    fromMetricSpace  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
    - SBV Int16
    32768

    instance Metric Int32 where
      type MetricSpace Int32 = Word32
      toMetricSpace :: SBV Int32 -> SBV (MetricSpace Int32)
    toMetricSpace    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
    + SBV Word32
    2147483648 -- 2^31
      fromMetricSpace :: SBV (MetricSpace Int32) -> SBV Int32
    fromMetricSpace  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
    - SBV Int32
    2147483648

    instance Metric Int64 where
      type MetricSpace Int64 = Word64
      toMetricSpace :: SBV Int64 -> SBV (MetricSpace Int64)
    toMetricSpace    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
    + SBV Word64
    9223372036854775808  -- 2^63
      fromMetricSpace :: SBV (MetricSpace Int64) -> SBV Int64
    fromMetricSpace  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
    - SBV Int64
    9223372036854775808

    -- Quickcheck interface on symbolic-booleans..
    instance Testable SBool where
      property :: SBool -> Property
    property (SBV (SVal Kind
    _ (Left CV
    b))) = Bool -> Property
    forall prop. Testable prop => prop -> Property
    property (CV -> Bool
    cvToBool CV
    b)
      property SBool
    _                       = Property
    forall a. a
    cantQuickCheck

    instance Testable (Symbolic SBool) where
       property :: Symbolic SBool -> Property
    property Symbolic SBool
    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 (Bool
    cond, Bool
    r, [([Char], CV)]
    modelVals) <- IO (Bool, Bool, [([Char], CV)])
    -> PropertyM IO (Bool, Bool, [([Char], CV)])
    forall (m :: * -> *) a. Monad m => m a -> PropertyM m a
    QC.run IO (Bool, Bool, [([Char], 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
    || [([Char], CV)] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [([Char], 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 ([Char] -> Property -> Property
    forall prop. Testable prop => [Char] -> prop -> Property
    QC.counterexample ([([Char], CV)] -> [Char]
    complain [([Char], CV)]
    modelVals))
                                         Bool -> PropertyM IO ()
    forall (m :: * -> *). Monad m => Bool -> PropertyM m ()
    QC.assert Bool
    r
         where test :: IO (Bool, Bool, [([Char], CV)])
    test = do (SBool
    r, Result{resTraces :: Result -> [([Char], CV)]
    resTraces=[([Char], CV)]
    tvals, resObservables :: Result -> [([Char], CV -> Bool, SV)]
    resObservables=[([Char], CV -> Bool, SV)]
    ovals, resConsts :: Result -> (CnstMap, [(SV, CV)])
    resConsts=(CnstMap
    _, [(SV, CV)]
    cs), resConstraints :: Result -> Seq (Bool, [([Char], [Char])], SV)
    resConstraints=Seq (Bool, [([Char], [Char])], SV)
    cstrs, resUIConsts :: Result -> [([Char], (Maybe [[Char]], SBVType))]
    resUIConsts=[([Char], (Maybe [[Char]], SBVType))]
    unints}) <- SMTConfig -> SBVRunMode -> Symbolic SBool -> IO (SBool, Result)
    forall (m :: * -> *) a.
    MonadIO m =>
    SMTConfig -> SBVRunMode -> SymbolicT m a -> m (a, Result)
    runSymbolic SMTConfig
    defaultSMTCfg (Maybe (Bool, [(NamedSymVar, CV)]) -> SBVRunMode
    Concrete Maybe (Bool, [(NamedSymVar, CV)])
    forall a. Maybe a
    Nothing) Symbolic SBool
    prop

                         let cval :: SV -> CV
    cval = CV -> Maybe CV -> CV
    forall a. a -> Maybe a -> a
    fromMaybe CV
    forall a. a
    cantQuickCheck (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 = -- Only pick-up "hard" constraints, as indicated by False in the fist component
                                    [Bool] -> Bool
    forall (t :: * -> *). Foldable t => t Bool -> Bool
    and [CV -> Bool
    cvToBool (SV -> CV
    cval SV
    v) | (Bool
    False, [([Char], [Char])]
    _, SV
    v) <- Seq (Bool, [([Char], [Char])], SV)
    -> [(Bool, [([Char], [Char])], SV)]
    forall a. Seq a -> [a]
    forall (t :: * -> *) a. Foldable t => t a -> [a]
    F.toList Seq (Bool, [([Char], [Char])], SV)
    cstrs]

                             getObservable :: ([Char], CV -> Bool, SV) -> Maybe ([Char], CV)
    getObservable ([Char]
    nm, CV -> Bool
    f, 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 -> if CV -> Bool
    f CV
    cv then ([Char], CV) -> Maybe ([Char], CV)
    forall a. a -> Maybe a
    Just ([Char]
    nm, CV
    cv) else Maybe ([Char], CV)
    forall a. Maybe a
    Nothing
                                                          Maybe CV
    Nothing -> Maybe ([Char], CV)
    forall a. a
    cantQuickCheck

                         case (([Char], (Maybe [[Char]], SBVType)) -> [Char])
    -> [([Char], (Maybe [[Char]], SBVType))] -> [[Char]]
    forall a b. (a -> b) -> [a] -> [b]
    map ([Char], (Maybe [[Char]], SBVType)) -> [Char]
    forall a b. (a, b) -> a
    fst [([Char], (Maybe [[Char]], SBVType))]
    unints of
                           [] -> case SBool -> Maybe Bool
    forall a. SymVal a => SBV a -> Maybe a
    unliteral SBool
    r of
                                   Maybe Bool
    Nothing -> IO (Bool, Bool, [([Char], CV)])
    forall a. a
    cantQuickCheck
                                   Just Bool
    b  -> (Bool, Bool, [([Char], CV)]) -> IO (Bool, Bool, [([Char], CV)])
    forall a. a -> IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (Bool
    cond, Bool
    b, [([Char], CV)]
    tvals [([Char], CV)] -> [([Char], CV)] -> [([Char], CV)]
    forall a. [a] -> [a] -> [a]
    ++ (([Char], CV -> Bool, SV) -> Maybe ([Char], CV))
    -> [([Char], CV -> Bool, SV)] -> [([Char], CV)]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe ([Char], CV -> Bool, SV) -> Maybe ([Char], CV)
    getObservable [([Char], CV -> Bool, SV)]
    ovals)
                           [[Char]]
    _  -> IO (Bool, Bool, [([Char], CV)])
    forall a. a
    cantQuickCheck

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

    -- Complain if what we got isn't something we can quick-check
    cantQuickCheck :: a
    cantQuickCheck :: forall a. a
    cantQuickCheck = [Char] -> a
    forall a. HasCallStack => [Char] -> a
    error ([Char] -> a) -> [Char] -> a
    forall a b. (a -> b) -> a -> b
    $ [[Char]] -> [Char]
    unlines [ [Char]
    "*** Data.SBV: Cannot quickcheck the given property."
                                     , [Char]
    "***"
                                     , [Char]
    "*** Certain SBV properties cannot be quick-checked. In particular,"
                                     , [Char]
    "*** SBV can't quick-check in the presence of:"
                                     , [Char]
    "***"
                                     , [Char]
    "***   - Uninterpreted constants."
                                     , [Char]
    "***   - Floating point operations with rounding modes other than RNE."
                                     , [Char]
    "***   - Floating point FMA operation, regardless of rounding mode."
                                     , [Char]
    "***   - Quantified booleans, i.e., uses of Forall/Exists/ExistsUnique."
                                     , [Char]
    "***   - Calls to 'observe' (use 'sObserve' instead)"
                                     , [Char]
    "***"
                                     , [Char]
    "*** If you can't avoid the above features or run into an issue with"
                                     , [Char]
    "*** quickcheck even though you haven't used these features, please report this as a bug!"
                                     ]

    -- | 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 SBool -> IO Bool
    sbvQuickCheck Symbolic SBool
    prop = Result -> Bool
    QC.isSuccess (Result -> Bool) -> IO Result -> IO Bool
    forall a b. (a -> b) -> IO a -> IO b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    `fmap` Symbolic SBool -> IO Result
    forall prop. Testable prop => prop -> IO Result
    QC.quickCheckResult Symbolic SBool
    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 Symbolic SVal
    m = Symbolic SBool -> Property
    forall prop. Testable prop => prop -> Property
    property (Symbolic SBool -> Property) -> Symbolic SBool -> 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
    $ [Char] -> Symbolic ()
    forall a. HasCallStack => [Char] -> a
    error [Char]
    "Cannot quickcheck non-boolean value"
                                 SBool -> Symbolic SBool
    forall a. a -> SymbolicT IO a
    forall (m :: * -> *) a. Monad m => a -> m a
    return (SVal -> SBool
    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 observable 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 :: forall a b.
    (HasKind a, HasKind b) =>
    SBV a -> (SBV a -> SBV b) -> SBV b
    slet SBV a
    x 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 (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)
              r :: State -> IO SV
    r 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 a. a -> IO a
    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
      SBV a -> z
    k === :: (SBV a -> z) -> (SBV a -> z) -> IO ThmResult
    === SBV a -> z
    l = (SBV a -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBool) -> IO ThmResult)
    -> (SBV a -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a -> SBV a -> z
    k SBV a
    a z -> z -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== SBV a -> z
    l SBV a
    a

    instance {-# OVERLAPPABLE #-} (SymVal a, SymVal b, EqSymbolic z) => Equality (SBV a -> SBV b -> z) where
      SBV a -> SBV b -> z
    k === :: (SBV a -> SBV b -> z) -> (SBV a -> SBV b -> z) -> IO ThmResult
    === SBV a -> SBV b -> z
    l = (SBV a -> SBV b -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b -> SBV a -> SBV b -> z
    k SBV a
    a SBV b
    b z -> z -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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
      (SBV a, SBV b) -> z
    k === :: ((SBV a, SBV b) -> z) -> ((SBV a, SBV b) -> z) -> IO ThmResult
    === (SBV a, SBV b) -> z
    l = (SBV a -> SBV b -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b -> (SBV a, SBV b) -> z
    k (SBV a
    a, SBV b
    b) z -> z -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== (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
      SBV a -> SBV b -> SBV c -> z
    k === :: (SBV a -> SBV b -> SBV c -> z)
    -> (SBV a -> SBV b -> SBV c -> z) -> IO ThmResult
    === SBV a -> SBV b -> SBV c -> z
    l = (SBV a -> SBV b -> SBV c -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c -> SBV a -> SBV b -> SBV c -> z
    k SBV a
    a SBV b
    b SBV c
    c z -> z -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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
      (SBV a, SBV b, SBV c) -> z
    k === :: ((SBV a, SBV b, SBV c) -> z)
    -> ((SBV a, SBV b, SBV c) -> z) -> IO ThmResult
    === (SBV a, SBV b, SBV c) -> z
    l = (SBV a -> SBV b -> SBV c -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c -> (SBV a, SBV b, SBV c) -> z
    k (SBV a
    a, SBV b
    b, SBV c
    c) z -> z -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== (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
      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
    === SBV a -> SBV b -> SBV c -> SBV d -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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
      (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
    === (SBV a, SBV b, SBV c, SBV d) -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBool) -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBool) -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBool) -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== (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
      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
    === SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool)
    -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c SBV d
    d 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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
      (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
    === (SBV a, SBV b, SBV c, SBV d, SBV e) -> z
    l = (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool)
    -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c SBV d
    d 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== (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
      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
    === 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 -> SBool)
    -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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
      (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
    === (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 -> SBool)
    -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBool)
     -> IO ThmResult)
    -> (SBV a -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== (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
      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
    === 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 -> SBool)
    -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a
      -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBool)
     -> IO ThmResult)
    -> (SBV a
        -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e SBV f
    f 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== 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
      (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
    === (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 -> SBool)
    -> IO ThmResult
    forall (m :: * -> *) a. ProvableM m a => a -> m ThmResult
    prove ((SBV a
      -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBool)
     -> IO ThmResult)
    -> (SBV a
        -> SBV b -> SBV c -> SBV d -> SBV e -> SBV f -> SBV g -> SBool)
    -> IO ThmResult
    forall a b. (a -> b) -> a -> b
    $ \SBV a
    a SBV b
    b SBV c
    c SBV d
    d SBV e
    e SBV f
    f 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 -> SBool
    forall a. EqSymbolic a => a -> a -> SBool
    .== (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)

    -- | Using a lambda as an array
    lambdaAsArray :: forall a b. (SymVal a, HasKind b) => (SBV a -> SBV b) -> SArray a b
    lambdaAsArray :: forall a b. (SymVal a, HasKind b) => (SBV a -> SBV b) -> SArray a b
    lambdaAsArray SBV a -> SBV b
    f = SArr -> SArray a b
    forall a b. SArr -> SArray a b
    SArray (SArr -> SArray a b) -> SArr -> SArray a b
    forall a b. (a -> b) -> a -> b
    $ (Kind, Kind) -> Cached ArrayIndex -> SArr
    SArr (Proxy a -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @a), Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)) (Cached ArrayIndex -> SArr) -> Cached ArrayIndex -> SArr
    forall a b. (a -> b) -> a -> b
    $ (State -> IO ArrayIndex) -> Cached ArrayIndex
    forall a. (State -> IO a) -> Cached a
    cache State -> IO ArrayIndex
    g
      where g :: State -> IO ArrayIndex
    g State
    st = do [Char]
    def  <- State -> Kind -> (SBV a -> SBV b) -> IO [Char]
    forall (m :: * -> *) a.
    (MonadIO m, Lambda (SymbolicT m) a) =>
    State -> Kind -> a -> m [Char]
    lambdaStr State
    st (Proxy b -> Kind
    forall a. HasKind a => a -> Kind
    kindOf (forall t. Proxy t
    forall {k} (t :: k). Proxy t
    Proxy @b)) SBV a -> SBV b
    f

                      let extract :: SArray a b -> IO ArrayIndex
                          extract :: SArray a b -> IO ArrayIndex
    extract (SArray (SArr (Kind, Kind)
    _ Cached ArrayIndex
    ci)) = Cached ArrayIndex -> State -> IO ArrayIndex
    uncacheAI Cached ArrayIndex
    ci State
    st

                      SArray a b -> IO ArrayIndex
    extract (SArray a b -> IO ArrayIndex) -> IO (SArray a b) -> IO ArrayIndex
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
    =<< Maybe [Char]
    -> Either (Maybe (SBV b)) [Char] -> State -> IO (SArray a b)
    forall a b.
    (HasKind a, HasKind b) =>
    Maybe [Char]
    -> Either (Maybe (SBV b)) [Char] -> State -> IO (SArray a b)
    forall (array :: * -> * -> *) a b.
    (SymArray array, HasKind a, HasKind b) =>
    Maybe [Char]
    -> Either (Maybe (SBV b)) [Char] -> State -> IO (array a b)
    newArrayInState Maybe [Char]
    forall a. Maybe a
    Nothing ([Char] -> Either (Maybe (SBV b)) [Char]
    forall a b. b -> Either a b
    Right [Char]
    def) State
    st

    {- HLint ignore module   "Reduce duplication" -}
    {- HLint ignore module   "Eta reduce"         -}