diff --git a/CHANGES.md b/CHANGES.md
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,7 +1,19 @@
 * Hackage: <http://hackage.haskell.org/package/sbv>
 * GitHub:  <http://leventerkok.github.io/sbv/>
 
-* Latest Hackage released version: 10.1, 2023-04-14
+* Latest Hackage released version: 10.2, 2023-06-09
+
+### Version 10.2, 2023-06-09
+
+  * Improve HLint pragmas. Thanks to George Thomas for the patch.
+
+  * Added an implementation of the Prince encryption algorithm. See Documentation/SBV/Examples/Crypto/Prince.hs.
+
+  * Added on-the-fly decryption mode for AES. See Documentation/SBV/Examples/Crypto/AES.hs for details.
+
+  * Added functions `sEDivMod`, `sEDiv`, and `sEMod` which perform euclidian division over symbolic integers.
+
+  * Added 'Data.SBV.Tools.NaturalInduction' which provides a proof method to perform induction over natural numbers. See the functions 'inductNat' and 'inductNatWith'.
 
 ### Version 10.1, 2023-04-14
 
diff --git a/Data/SBV.hs b/Data/SBV.hs
--- a/Data/SBV.hs
+++ b/Data/SBV.hs
@@ -263,6 +263,8 @@
   , SIntegral
   -- * Division and Modulus
   , SDivisible(..)
+  -- $euclidianNote
+  , sEDivMod, sEDiv, sEMod
   -- * Bit-vector operations
   -- ** Conversions
   , sFromIntegral
@@ -883,7 +885,7 @@
 -}
 
 {- $quantifiers
-You can write quantified formulas, and reason with them as in first-order logic. Here is a simple example is:
+You can write quantified formulas, and reason with them as in first-order logic. Here is a simple example:
 
 @
     constrain $ \\(Forall x) (Exists y) -> y .> (x :: SInteger)
@@ -1141,6 +1143,32 @@
 Q.E.D.
 -}
 
+{- $euclidianNote
+=== Euclidian division and modulus
+
+Euclidian division and modulus for integers differ from regular division modulus when
+the divisor is negative. It satisfies the following desirable property: For any @m@, @n@, we have:
+
+@
+  Given @m@, @n@, s.t., n /= 0
+  Let (q, r) = m `sEDivMod` n
+  Then: m = n * q + r
+   and 0 <= r <= |n| - 1
+@
+
+That is, the modulus is always positive.
+There's no standard Haskell function that performs this operation. The main reason to prefer this
+function is that SMT solvers can deal with them better.
+Compare:
+
+>>> sDivMod @SInteger 3 (-2)
+(-2 :: SInteger,-1 :: SInteger)
+>>> sEDivMod 3 (-2)
+(-1 :: SInteger,1 :: SInteger)
+>>> prove $ \x y -> y .> 0 .=> x `sDivMod` y .== x `sEDivMod` y
+Q.E.D.
+-}
+
 {- $conversionNote
 Capture convertability from/to FloatingPoint representations.
 
@@ -1613,4 +1641,4 @@
 
                        newExpr st KBool $ SBVApp (SpecialRelOp ka iop) []
 
-{-# ANN module ("HLint: ignore Use import/export shortcut" :: String) #-}
+{- HLint ignore module "Use import/export shortcut" -}
diff --git a/Data/SBV/Compilers/C.hs b/Data/SBV/Compilers/C.hs
--- a/Data/SBV/Compilers/C.hs
+++ b/Data/SBV/Compilers/C.hs
@@ -1069,4 +1069,4 @@
                        , FP_IsZero
                        ]
 
-{-# ANN module ("HLint: ignore Redundant lambda" :: String) #-}
+{- HLint ignore module "Redundant lambda" -}
diff --git a/Data/SBV/Control/Query.hs b/Data/SBV/Control/Query.hs
--- a/Data/SBV/Control/Query.hs
+++ b/Data/SBV/Control/Query.hs
@@ -838,4 +838,4 @@
 
              return $ Satisfiable queryConfig m
 
-{-# ANN getModelAtIndex ("HLint: ignore Use forM_" :: String) #-}
+{- HLint ignore getModelAtIndex "Use forM_" -}
diff --git a/Data/SBV/Control/Types.hs b/Data/SBV/Control/Types.hs
--- a/Data/SBV/Control/Types.hs
+++ b/Data/SBV/Control/Types.hs
@@ -251,5 +251,5 @@
   show Logic_NONE      = "Logic_NONE"
   show (CustomLogic l) = l
 
-{-# ANN type SMTInfoResponse ("HLint: ignore Use camelCase" :: String) #-}
-{-# ANN type Logic           ("HLint: ignore Use camelCase" :: String) #-}
+{- HLint ignore type SMTInfoResponse "Use camelCase" -}
+{- HLint ignore type Logic           "Use camelCase" -}
diff --git a/Data/SBV/Control/Utils.hs b/Data/SBV/Control/Utils.hs
--- a/Data/SBV/Control/Utils.hs
+++ b/Data/SBV/Control/Utils.hs
@@ -19,7 +19,9 @@
 {-# LANGUAGE ScopedTypeVariables    #-}
 {-# LANGUAGE TupleSections          #-}
 {-# LANGUAGE TypeApplications       #-}
+{-# LANGUAGE TypeFamilies           #-}
 {-# LANGUAGE ViewPatterns           #-}
+{-# LANGUAGE UndecidableInstances   #-}
 
 {-# OPTIONS_GHC -Wall -Werror -fno-warn-orphans #-}
 
@@ -217,13 +219,15 @@
                       return r
 
 -- | Generic 'Queriable' instance for 'SymVal' values
-instance (MonadIO m, SymVal a) => Queriable m (SBV a) a where
+instance (MonadIO m, SymVal a) => Queriable m (SBV a) where
+  type QueryResult (SBV a) = a
   create  = freshVar_
   project = getValue
   embed   = return . literal
 
 -- | Generic 'Queriable' instance for things that are 'Fresh' and look like containers:
-instance (MonadIO m, SymVal a, Foldable t, Traversable t, Fresh m (t (SBV a))) => Queriable m (t (SBV a)) (t a) where
+instance (MonadIO m, SymVal a, Foldable t, Traversable t, Fresh m (t (SBV a))) => Queriable m (t (SBV a)) where
+  type QueryResult (t (SBV a)) = t a
   create  = fresh
   project = mapM getValue
   embed   = return . fmap literal
@@ -850,7 +854,8 @@
              | Just (Right assocs) <- mbAssocs = decode assocs
              | True                            = tbd "Expected a set value, but couldn't decipher the solver output."
 
-           where tbd w = error $ unlines [ ""
+           where tbd :: String -> a
+                 tbd w = error $ unlines [ ""
                                          , "*** Data.SBV.interpretSet: Unable to process solver output."
                                          , "***"
                                          , "*** Kind    : " ++ show (KSet ke)
@@ -1763,5 +1768,5 @@
                                           , "*** and each call to runSMT should have only one query call inside."
                                           ]
 
-{-# ANN module          ("HLint: ignore Reduce duplication" :: String) #-}
-{-# ANN getAllSatResult ("HLint: ignore Use forM_"          :: String) #-}
+{- HLint ignore module          "Reduce duplication" -}
+{- HLint ignore getAllSatResult "Use forM_"          -}
diff --git a/Data/SBV/Core/Concrete.hs b/Data/SBV/Core/Concrete.hs
--- a/Data/SBV/Core/Concrete.hs
+++ b/Data/SBV/Core/Concrete.hs
@@ -523,4 +523,4 @@
 randomCV :: Kind -> IO CV
 randomCV k = CV k <$> randomCVal k
 
-{-# ANN module ("HLint: ignore Redundant if" :: String) #-}
+{- HLint ignore module "Redundant if" -}
diff --git a/Data/SBV/Core/Data.hs b/Data/SBV/Core/Data.hs
--- a/Data/SBV/Core/Data.hs
+++ b/Data/SBV/Core/Data.hs
@@ -85,7 +85,6 @@
 import qualified GHC.Generics  as G
 import qualified Data.Generics as G (Data(..))
 
-
 import qualified Data.IORef         as R    (readIORef)
 import qualified Data.IntMap.Strict as IMap (size, insert)
 
@@ -840,6 +839,15 @@
 -- | Not exported, used for implementing generic equality.
 class GEqSymbolic f where
   symbolicEq :: f a -> f a -> SBool
+
+{-
+ - N.B. A V1 instance like the below would be wrong!
+ - Why? Because in SBV, 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 equality checking of such values.
+instance GEqSymbolic V1 where
+  symbolicEq _ _ = sTrue
+-}
 
 instance GEqSymbolic U1 where
   symbolicEq _ _ = sTrue
diff --git a/Data/SBV/Core/Floating.hs b/Data/SBV/Core/Floating.hs
--- a/Data/SBV/Core/Floating.hs
+++ b/Data/SBV/Core/Floating.hs
@@ -763,4 +763,4 @@
   --       fpIsPositiveZero :: SBV a -> SBool
   --       fpIsPoint        :: SBV a -> SBool
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Data/SBV/Core/Model.hs b/Data/SBV/Core/Model.hs
--- a/Data/SBV/Core/Model.hs
+++ b/Data/SBV/Core/Model.hs
@@ -40,6 +40,7 @@
   , SymTuple, sTuple, sTuple_, sTuples
   , sEither, sEither_, sEithers, sMaybe, sMaybe_, sMaybes
   , sSet, sSet_, sSets
+  , sEDivMod, sEDiv, sEMod
   , solve
   , slet
   , sRealToSInteger, label, observe, observeIf, sObserve
@@ -55,7 +56,7 @@
 import Control.Monad.Trans    (liftIO)
 import Control.Monad.IO.Class (MonadIO)
 
-import GHC.Generics (U1(..), M1(..), (:*:)(..), K1(..))
+import GHC.Generics (M1(..), U1(..), (:*:)(..), K1(..))
 import qualified GHC.Generics as G
 
 import GHC.Stack
@@ -1842,6 +1843,18 @@
           i = ite (x .>= 0 .|| rE .== 0) 0
             $ ite (y .>  0)              1 (-1)
 
+-- | Euclidian division and modulus.
+sEDivMod :: SInteger -> SInteger -> (SInteger, SInteger)
+sEDivMod a b = (a `sEDiv` b, a `sEMod` b)
+
+-- | Euclidian division.
+sEDiv :: SInteger -> SInteger -> SInteger
+sEDiv (SBV a) (SBV b) = SBV $ a `svQuot` b
+
+-- | Euclidian modulus.
+sEMod :: SInteger -> SInteger -> SInteger
+sEMod (SBV a) (SBV b) = SBV $ a `svRem` b
+
 -- Quickcheck interface
 instance (SymVal a, Arbitrary a) => Arbitrary (SBV a) where
   arbitrary = literal `fmap` arbitrary
@@ -2185,6 +2198,15 @@
 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' _ _ _ _ = U1
 
@@ -2772,5 +2794,5 @@
 
                   extract =<< newArrayInState Nothing (Right def) st
 
-{-# ANN module   ("HLint: ignore Reduce duplication" :: String) #-}
-{-# ANN module   ("HLint: ignore Eta reduce" :: String)         #-}
+{- HLint ignore module   "Reduce duplication" -}
+{- HLint ignore module   "Eta reduce"         -}
diff --git a/Data/SBV/Core/Operations.hs b/Data/SBV/Core/Operations.hs
--- a/Data/SBV/Core/Operations.hs
+++ b/Data/SBV/Core/Operations.hs
@@ -41,7 +41,7 @@
   , svBarrelRotateLeft, svBarrelRotateRight
   , svBlastLE, svBlastBE
   , svAddConstant, svIncrement, svDecrement
-  , svFloatAsSWord32, svDoubleAsSWord64, svFloatingPointAsSWord 
+  , svFloatAsSWord32, svDoubleAsSWord64, svFloatingPointAsSWord
   -- ** Basic array operations
   , SArr(..), readSArr, writeSArr, mergeSArr, newSArr, eqSArr
   -- Utils
@@ -49,8 +49,9 @@
   )
   where
 
+import Prelude hiding (Foldable(..))
 import Data.Bits (Bits(..))
-import Data.List (genericIndex, genericLength, genericTake, foldl')
+import Data.List (genericIndex, genericLength, genericTake, foldr, length, foldl')
 
 import qualified Data.IORef         as R    (readIORef)
 import qualified Data.IntMap.Strict as IMap (size, insert)
@@ -1452,6 +1453,6 @@
                              return n
 svFloatingPointAsSWord (SVal k _) = error $ "svFloatingPointAsSWord: non-float type: " ++ show k
 
-{-# ANN svIte     ("HLint: ignore Eta reduce" :: String)         #-}
-{-# ANN svLazyIte ("HLint: ignore Eta reduce" :: String)         #-}
-{-# ANN module    ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore svIte     "Eta reduce"         -}
+{- HLint ignore svLazyIte "Eta reduce"         -}
+{- HLint ignore module    "Reduce duplication" -}
diff --git a/Data/SBV/Core/Symbolic.hs b/Data/SBV/Core/Symbolic.hs
--- a/Data/SBV/Core/Symbolic.hs
+++ b/Data/SBV/Core/Symbolic.hs
@@ -16,14 +16,15 @@
 {-# LANGUAGE DeriveFunctor              #-}
 {-# LANGUAGE DeriveGeneric              #-}
 {-# LANGUAGE FlexibleInstances          #-}
-{-# LANGUAGE FunctionalDependencies     #-}
 {-# LANGUAGE GADTs                      #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
+{-# LANGUAGE MultiParamTypeClasses      #-}
 {-# LANGUAGE NamedFieldPuns             #-}
 {-# LANGUAGE OverloadedStrings          #-}
 {-# LANGUAGE PatternGuards              #-}
 {-# LANGUAGE Rank2Types                 #-}
 {-# LANGUAGE ScopedTypeVariables        #-}
+{-# LANGUAGE TypeFamilies               #-}
 {-# LANGUAGE TypeOperators              #-}
 {-# LANGUAGE UndecidableInstances       #-}
 {-# LANGUAGE ViewPatterns               #-}
@@ -77,6 +78,7 @@
 import Data.List                   (intercalate, sortBy, isPrefixOf)
 import Data.Maybe                  (fromMaybe, mapMaybe)
 import Data.String                 (IsString(fromString))
+import Data.Kind                   (Type)
 
 import Data.Time (getCurrentTime, UTCTime)
 
@@ -784,14 +786,18 @@
 
 -- | An queriable value. This is a generalization of the 'Fresh' class, in case one needs
 -- to be more specific about how projections/embeddings are done.
-class Queriable m a b | a -> b where
+class Queriable m a where
+  type QueryResult a :: Type
+
   -- | ^ Create a new symbolic value of type @a@
   create  :: QueryT m a
+
   -- | ^ Extract the current value in a SAT context
-  project :: a -> QueryT m b
+  project :: a -> QueryT m (QueryResult a)
+
   -- | ^ Create a literal value. Morally, 'embed' and 'project' are inverses of each other
   -- via the 'QueryT' monad transformer.
-  embed   :: b -> QueryT m a
+  embed   :: QueryResult a -> QueryT m a
 
 -- Have to define this one by hand, because we use ReaderT in the implementation
 instance MonadReader r m => MonadReader r (QueryT m) where
@@ -2262,7 +2268,7 @@
    show QueryInternal = "Internal Query"
    show QueryExternal = "User Query"
 
-{-# ANN type FPOp ("HLint: ignore Use camelCase" :: String) #-}
-{-# ANN type PBOp ("HLint: ignore Use camelCase" :: String) #-}
-{-# ANN type OvOp ("HLint: ignore Use camelCase" :: String) #-}
-{-# ANN type NROp ("HLint: ignore Use camelCase" :: String) #-}
+{- HLint ignore type FPOp "Use camelCase" -}
+{- HLint ignore type PBOp "Use camelCase" -}
+{- HLint ignore type OvOp "Use camelCase" -}
+{- HLint ignore type NROp "Use camelCase" -}
diff --git a/Data/SBV/Either.hs b/Data/SBV/Either.hs
--- a/Data/SBV/Either.hs
+++ b/Data/SBV/Either.hs
@@ -201,29 +201,8 @@
   | True
   = SBV $ SVal ka $ Right $ cache res
   where ka      = kindOf (Proxy @a)
-        kb      = kindOf (Proxy @b)
-        kEither = KEither ka kb
-
-        -- We play the usual trick here of creating a left value and asserting equivalence
-        -- under implication. This will be underspecified as required should the value
-        -- received be a right thing.
-        res st = do -- grab an internal variable and make a left out of it
-                    e  <- internalVariable st ka
-                    es <- newExpr st kEither (SBVApp (EitherConstructor ka kb False) [e])
-
-                    -- Create the condition that it is equal to the input
-                    ms <- sbvToSV st sab
-                    eq <- newExpr st KBool (SBVApp Equal [es, ms])
-
-                    -- Gotta make sure we do this only when input is not right
-                    caseRight <- sbvToSV st (isRight sab)
-                    require   <- newExpr st KBool (SBVApp Or [caseRight, eq])
-
-                    -- register the constraint:
-                    internalConstraint st False [] $ SVal KBool $ Right $ cache $ \_ -> return require
-
-                    -- We're good to go
-                    return e
+        res st = do ms <- sbvToSV st sab
+                    newExpr st ka (SBVApp (EitherAccess False) [ms])
 
 -- | Return the value from the right component. The behavior is undefined if
 -- passed a left value, i.e., it can return any value.
@@ -232,9 +211,9 @@
 -- 'a' :: SChar
 -- >>> prove $ \x -> fromRight (sRight x :: SEither Char Integer) .== (x :: SInteger)
 -- Q.E.D.
--- >>> sat $ \x -> x .== (fromRight (sLeft (literal 'a') :: SEither Char Integer))
+-- >>> sat $ \x -> x .== (fromRight (sLeft (literal 2) :: SEither Integer Char))
 -- Satisfiable. Model:
---   s0 = 0 :: Integer
+--   s0 = 'A' :: Char
 --
 -- Note how we get a satisfying assignment in the last case: The behavior
 -- is unspecified, thus the SMT solver picks whatever satisfies the
@@ -245,29 +224,8 @@
   = literal b
   | True
   = SBV $ SVal kb $ Right $ cache res
-  where ka      = kindOf (Proxy @a)
-        kb      = kindOf (Proxy @b)
-        kEither = KEither ka kb
-
-        -- We play the usual trick here of creating a right value and asserting equivalence
-        -- under implication. This will be underspecified as required should the value
-        -- received be a right thing.
-        res st = do -- grab an internal variable and make a right out of it
-                    e  <- internalVariable st kb
-                    es <- newExpr st kEither (SBVApp (EitherConstructor ka kb True) [e])
-
-                    -- Create the condition that it is equal to the input
-                    ms <- sbvToSV st sab
-                    eq <- newExpr st KBool (SBVApp Equal [es, ms])
-
-                    -- Gotta make sure we do this only when input is not left
-                    caseLeft <- sbvToSV st (isLeft sab)
-                    require  <- newExpr st KBool (SBVApp Or [caseLeft, eq])
-
-                    -- register the constraint:
-                    internalConstraint st False [] $ SVal KBool $ Right $ cache $ \_ -> return require
-
-                    -- We're good to go
-                    return e
+  where kb      = kindOf (Proxy @b)
+        res st = do ms <- sbvToSV st sab
+                    newExpr st kb (SBVApp (EitherAccess True) [ms])
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Data/SBV/Internals.hs b/Data/SBV/Internals.hs
--- a/Data/SBV/Internals.hs
+++ b/Data/SBV/Internals.hs
@@ -136,7 +136,7 @@
 -- >>> prove $ \x -> fpIsNegativeZero x .|| sComparableSWord32AsSFloat (sFloatAsComparableSWord32 x) `fpIsEqualObject` x
 -- Q.E.D.
 sComparableSWord32AsSFloat :: SWord32 -> SFloat
-sComparableSWord32AsSFloat = CF.sComparableSWord32AsSFloat 
+sComparableSWord32AsSFloat = CF.sComparableSWord32AsSFloat
 
 -- | Inverse transformation to 'sDoubleAsComparableSWord64'. Note that this isn't a perfect inverse, since @-0@ maps to @0@ and back to @0@.
 -- Otherwise, it's faithful:
@@ -146,7 +146,7 @@
 -- >>> prove $ \x -> fpIsNegativeZero x .|| sComparableSWord64AsSDouble (sDoubleAsComparableSWord64 x) `fpIsEqualObject` x
 -- Q.E.D.
 sComparableSWord64AsSDouble :: SWord64 -> SDouble
-sComparableSWord64AsSDouble = CF.sComparableSWord64AsSDouble 
+sComparableSWord64AsSDouble = CF.sComparableSWord64AsSDouble
 
 -- | Inverse transformation to 'sFloatingPointAsComparableSWord'. Note that this isn't a perfect inverse, since @-0@ maps to @0@ and back to @0@.
 -- Otherwise, it's faithful:
@@ -158,4 +158,4 @@
 sComparableSWordAsSFloatingPoint :: forall eb sb. (KnownNat (eb + sb), BVIsNonZero (eb + sb), ValidFloat eb sb) => SWord (eb + sb) -> SFloatingPoint eb sb
 sComparableSWordAsSFloatingPoint = CF.sComparableSWordAsSFloatingPoint
 
-{-# ANN module ("HLint: ignore Use import/export shortcut" :: String) #-}
+{- HLint ignore module "Use import/export shortcut" -}
diff --git a/Data/SBV/Lambda.hs b/Data/SBV/Lambda.hs
--- a/Data/SBV/Lambda.hs
+++ b/Data/SBV/Lambda.hs
@@ -67,7 +67,7 @@
         --      It better be the case that in "toLambda" below, you do something with it.
         --
         -- Note the above applies to all the IORefs, which is most of the state, though
-        -- not all. For the time being, those are pathCond, stCfg, and startTime; which 
+        -- not all. For the time being, those are pathCond, stCfg, and startTime; which
         -- don't really impact anything.
         comp State {
                    -- These are not IORefs; so we share by copying  the value; changes won't be copied back
@@ -303,4 +303,4 @@
                        tableMap   = IM.empty
                        funcMap    = M.empty
 
-{-# ANN module ("HLint: ignore Use second" :: String) #-}
+{- HLint ignore module "Use second" -}
diff --git a/Data/SBV/List.hs b/Data/SBV/List.hs
--- a/Data/SBV/List.hs
+++ b/Data/SBV/List.hs
@@ -148,7 +148,7 @@
 -- Q.E.D.
 -- >>> sat $ \(l :: SList Word16) -> length l .>= 2 .&& listToListAt l 0 ./= listToListAt l (length l - 1)
 -- Satisfiable. Model:
---   s0 = [0,32] :: [Word16]
+--   s0 = [0,16] :: [Word16]
 listToListAt :: SymVal a => SList a -> SInteger -> SList a
 listToListAt s offset = subList s offset 1
 
diff --git a/Data/SBV/Maybe.hs b/Data/SBV/Maybe.hs
--- a/Data/SBV/Maybe.hs
+++ b/Data/SBV/Maybe.hs
@@ -119,29 +119,8 @@
   | True
   = SBV $ SVal ka $ Right $ cache res
   where ka     = kindOf (Proxy @a)
-        kMaybe = KMaybe ka
-
-        -- We play the usual trick here of creating a just value
-        -- and asserting equivalence under implication. This will
-        -- be underspecified as required should the value
-        -- received be `Nothing`.
-        res st = do -- grab an internal variable and make a Maybe out of it
-                    e  <- internalVariable st ka
-                    es <- newExpr st kMaybe (SBVApp (MaybeConstructor ka True) [e])
-
-                    -- Create the condition that it is equal to the input
-                    ms <- sbvToSV st ma
-                    eq <- newExpr st KBool (SBVApp Equal [es, ms])
-
-                    -- Gotta make sure we do this only when input is not nothing
-                    caseNothing <- sbvToSV st (isNothing ma)
-                    require     <- newExpr st KBool (SBVApp Or [caseNothing, eq])
-
-                    -- register the constraint:
-                    internalConstraint st False [] $ SVal KBool $ Right $ cache $ \_ -> return require
-
-                    -- We're good to go:
-                    return e
+        res st = do ms <- sbvToSV st ma
+                    newExpr st ka (SBVApp MaybeAccess [ms])
 
 -- | Construct an @SMaybe a@ from a @Maybe (SBV a)@.
 --
diff --git a/Data/SBV/Provers/Prover.hs b/Data/SBV/Provers/Prover.hs
--- a/Data/SBV/Provers/Prover.hs
+++ b/Data/SBV/Provers/Prover.hs
@@ -886,4 +886,4 @@
 instance (SymVal a, SymVal b, SymVal c, SymVal d, SymVal e, SymVal f, SymVal g, SExecutable m p) => SExecutable m ((SBV a, SBV b, SBV c, SBV d, SBV e, SBV f, SBV g) -> p) where
   sName k = mkArg >>= \a -> sName $ \b c d e f g -> k (a, b, c, d, e, f, g)
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Data/SBV/String.hs b/Data/SBV/String.hs
--- a/Data/SBV/String.hs
+++ b/Data/SBV/String.hs
@@ -439,4 +439,4 @@
 isConcretelyEmpty ss | Just s <- unliteral ss = P.null s
                      | True                   = False
 
-{-# ANN implode ("HLint: ignore Use concatMap" :: String) #-}
+{- HLint ignore implode "Use concatMap" -}
diff --git a/Data/SBV/Tools/BMC.hs b/Data/SBV/Tools/BMC.hs
--- a/Data/SBV/Tools/BMC.hs
+++ b/Data/SBV/Tools/BMC.hs
@@ -11,6 +11,8 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies     #-}
+{-# LANGUAGE TypeOperators    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -28,7 +30,7 @@
 --
 -- Note that the BMC engine does *not* guarantee that the solution is unique. However, if it does
 -- find a solution at depth @i@, it is guaranteed that there are no shorter solutions.
-bmc :: (EqSymbolic st, Queriable IO st res)
+bmc :: (EqSymbolic st, Queriable IO st, res ~ QueryResult st)
     => Maybe Int                            -- ^ Optional bound
     -> Bool                                 -- ^ Verbose: prints iteration count
     -> Symbolic ()                          -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @return ()@ if not needed.)
@@ -39,7 +41,7 @@
 bmc = bmcWith defaultSMTCfg
 
 -- | Bounded model checking, configurable with the solver
-bmcWith :: (EqSymbolic st, Queriable IO st res)
+bmcWith :: (EqSymbolic st, Queriable IO st, res ~ QueryResult st)
         => SMTConfig
         -> Maybe Int
         -> Bool
diff --git a/Data/SBV/Tools/Induction.hs b/Data/SBV/Tools/Induction.hs
--- a/Data/SBV/Tools/Induction.hs
+++ b/Data/SBV/Tools/Induction.hs
@@ -20,6 +20,8 @@
 -----------------------------------------------------------------------------
 
 {-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE TypeFamilies     #-}
+{-# LANGUAGE TypeOperators    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -80,7 +82,7 @@
 
 -- | Induction engine, using the default solver. See "Documentation.SBV.Examples.ProofTools.Strengthen"
 -- and "Documentation.SBV.Examples.ProofTools.Sum" for examples.
-induct :: (Show res, Queriable IO st res)
+induct :: (Show res, Queriable IO st, res ~ QueryResult st)
        => Bool                             -- ^ Verbose mode
        -> Symbolic ()                      -- ^ Setup code, if necessary. (Typically used for 'Data.SBV.setOption' calls. Pass @return ()@ if not needed.)
        -> (st -> SBool)                    -- ^ Initial condition
@@ -92,7 +94,7 @@
 induct = inductWith defaultSMTCfg
 
 -- | Induction engine, configurable with the solver
-inductWith :: (Show res, Queriable IO st res)
+inductWith :: (Show res, Queriable IO st, res ~ QueryResult st)
            => SMTConfig
            -> Bool
            -> Symbolic ()
diff --git a/Data/SBV/Tools/NaturalInduction.hs b/Data/SBV/Tools/NaturalInduction.hs
new file mode 100644
--- /dev/null
+++ b/Data/SBV/Tools/NaturalInduction.hs
@@ -0,0 +1,60 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Data.SBV.Tools.NaturalInduction
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Proof by induction over naturals.
+-----------------------------------------------------------------------------
+
+module Data.SBV.Tools.NaturalInduction (
+           inductNat
+         , inductNatWith
+       ) where
+
+import Data.SBV
+import Data.SBV.Tuple
+
+---------------------------------------------------------------------
+-- * Induction over natural numbers
+---------------------------------------------------------------------
+
+-- | Perform natural induction over the given function, which returns left and
+-- right hand-sides to be proven equal. Uses 'defaultSMTCfg'. That is,
+-- given @f x = (lhs x, rhs x)@, we inductively establish that @lhs@ and
+-- @rhs@ agree on @0@, @1@, ... @n@, i.e., for all non-negative integers.
+--
+-- >>> import Data.SBV
+-- >>> import Data.SBV.Tools.NaturalInduction
+-- >>> let sumToN        :: SInteger -> SInteger = smtFunction "sumToN"        $ \x -> ite (x .<= 0) 0 (x   + sumToN        (x-1))
+-- >>> let sumSquaresToN :: SInteger -> SInteger = smtFunction "sumSquaresToN" $ \x -> ite (x .<= 0) 0 (x*x + sumSquaresToN (x-1))
+-- >>> inductNat $ \n -> (sumToN n, (n*(n+1)) `sEDiv` 2)
+-- Q.E.D.
+-- >>> inductNat $ \n -> (sumSquaresToN n, (n*(n+1)*(2*n+1)) `sEDiv` 6)
+-- Q.E.D.
+-- >>> inductNat $ \n -> (sumSquaresToN n, ite (n .== 12) 0 ((n*(n+1)*(2*n+1)) `sEDiv` 6))
+-- Falsifiable. Counter-example:
+--   P(0)   =     (0,0) :: (Integer, Integer)
+--   P(k)   = (506,506) :: (Integer, Integer)
+--   P(k+1) =   (650,0) :: (Integer, Integer)
+--   k      =        11 :: Integer
+inductNat :: SymVal a => (SInteger -> (SBV a, SBV a)) -> IO ThmResult
+inductNat = inductNatWith defaultSMTCfg
+
+-- | Perform natural induction over, using the given solver.
+inductNatWith :: SymVal a => SMTConfig -> (SInteger -> (SBV a, SBV a)) -> IO ThmResult
+inductNatWith cfg p = proveWith cfg $ do
+                        k <- free "k"
+                        let at0  = observe "P(0)"   (tuple (p 0))
+                            atk  = observe "P(k)"   (tuple (p k))
+                            atk1 = observe "P(k+1)" (tuple (p (k+1)))
+                            p0   = at0^._1  .== at0^._2
+                            pk   = atk^._1  .== atk^._2
+                            pk1  = atk1^._1 .== atk1^._2
+                        constrain $ k .>= 0
+                        constrain pk
+                        pure $ p0 .&& pk1
+
+{- HLint ignore module "Redundant ^." -}
diff --git a/Data/SBV/Tools/Range.hs b/Data/SBV/Tools/Range.hs
--- a/Data/SBV/Tools/Range.hs
+++ b/Data/SBV/Tools/Range.hs
@@ -210,4 +210,4 @@
                                               Just xss -> search (xss ++ cs) sofar
                                     else search cs sofar
 
-{-# ANN rangesWith ("HLint: ignore Use fromMaybe" :: String) #-}
+{- HLint ignore rangesWith "Use fromMaybe" -}
diff --git a/Data/SBV/Tools/WeakestPreconditions.hs b/Data/SBV/Tools/WeakestPreconditions.hs
--- a/Data/SBV/Tools/WeakestPreconditions.hs
+++ b/Data/SBV/Tools/WeakestPreconditions.hs
@@ -17,6 +17,8 @@
 {-# LANGUAGE MultiParamTypeClasses  #-}
 {-# LANGUAGE NamedFieldPuns         #-}
 {-# LANGUAGE ScopedTypeVariables    #-}
+{-# LANGUAGE TypeFamilies           #-}
+{-# LANGUAGE TypeOperators          #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -206,7 +208,7 @@
 
 
 -- | Checking WP based correctness
-wpProveWith :: forall st res. (Show res, Mergeable st, Queriable IO st res) => WPConfig -> Program st -> IO (ProofResult res)
+wpProveWith :: forall st res. (Show res, Mergeable st, Queriable IO st, res ~ QueryResult st) => WPConfig -> Program st -> IO (ProofResult res)
 wpProveWith cfg@WPConfig{wpVerbose} Program{setup, precondition, program, postcondition, stability} =
    runSMTWith (wpSolver cfg) $ do setup
                                   query q
@@ -339,7 +341,7 @@
                                 ++ measureDecreases   st'
 
 -- | Check correctness using the default solver. Equivalent to @'wpProveWith' 'defaultWPCfg'@.
-wpProve :: (Show res, Mergeable st, Queriable IO st res) => Program st -> IO (ProofResult res)
+wpProve :: (Show res, Mergeable st, Queriable IO st, res ~ QueryResult st) => Program st -> IO (ProofResult res)
 wpProve = wpProveWith defaultWPCfg
 
 -- | Configuration for WP proofs.
@@ -486,4 +488,4 @@
                            where mCur = currentMeasure is
                                  zero = map (const 0) mCur
 
-{-# ANN traceExecution ("HLint: ignore Use fromMaybe" :: String) #-}
+{- HLint ignore traceExecution "Use fromMaybe" -}
diff --git a/Data/SBV/Tuple.hs b/Data/SBV/Tuple.hs
--- a/Data/SBV/Tuple.hs
+++ b/Data/SBV/Tuple.hs
@@ -433,4 +433,4 @@
                         msMaximize (nm ++ "^._7") (p^._7)
                         msMaximize (nm ++ "^._8") (p^._8)
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Data/SBV/Utils/SExpr.hs b/Data/SBV/Utils/SExpr.hs
--- a/Data/SBV/Utils/SExpr.hs
+++ b/Data/SBV/Utils/SExpr.hs
@@ -621,4 +621,4 @@
                 -- give up, and just do prefix!
                 app xs = unwords xs
 
-{-# ANN chainAssigns ("HLint: ignore Redundant if" :: String) #-}
+{- HLint ignore chainAssigns "Redundant if" -}
diff --git a/Documentation/SBV/Examples/BitPrecise/BrokenSearch.hs b/Documentation/SBV/Examples/BitPrecise/BrokenSearch.hs
--- a/Documentation/SBV/Examples/BitPrecise/BrokenSearch.hs
+++ b/Documentation/SBV/Examples/BitPrecise/BrokenSearch.hs
@@ -108,4 +108,4 @@
 
                                     return $ sFromIntegral mid .== mid'
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/BitPrecise/Legato.hs b/Documentation/SBV/Examples/BitPrecise/Legato.hs
--- a/Documentation/SBV/Examples/BitPrecise/Legato.hs
+++ b/Documentation/SBV/Examples/BitPrecise/Legato.hs
@@ -13,16 +13,16 @@
 -- Here's Legato's algorithm, as coded in Mostek assembly:
 --
 -- @
---    step1 :       LDX #8         ; load X immediate with the integer 8 
---    step2 :       LDA #0         ; load A immediate with the integer 0 
---    step3 : LOOP  ROR F1         ; rotate F1 right circular through C 
---    step4 :       BCC ZCOEF      ; branch to ZCOEF if C = 0 
---    step5 :       CLC            ; set C to 0 
---    step6 :       ADC F2         ; set A to A+F2+C and C to the carry 
---    step7 : ZCOEF ROR A          ; rotate A right circular through C 
---    step8 :       ROR LOW        ; rotate LOW right circular through C 
---    step9 :       DEX            ; set X to X-1 
---    step10:       BNE LOOP       ; branch to LOOP if Z = 0 
+--    step1 :       LDX #8         ; load X immediate with the integer 8
+--    step2 :       LDA #0         ; load A immediate with the integer 0
+--    step3 : LOOP  ROR F1         ; rotate F1 right circular through C
+--    step4 :       BCC ZCOEF      ; branch to ZCOEF if C = 0
+--    step5 :       CLC            ; set C to 0
+--    step6 :       ADC F2         ; set A to A+F2+C and C to the carry
+--    step7 : ZCOEF ROR A          ; rotate A right circular through C
+--    step8 :       ROR LOW        ; rotate LOW right circular through C
+--    step9 :       DEX            ; set X to X-1
+--    step10:       BNE LOOP       ; branch to LOOP if Z = 0
 -- @
 --
 -- This program came to be known as the Legato's challenge in the community, where
@@ -309,5 +309,5 @@
                 cgOutput "hi" hi
                 cgOutput "lo" lo
 
-{-# ANN legato ("HLint: ignore Redundant $" :: String)        #-}
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore legato "Redundant $"        -}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/BitPrecise/MergeSort.hs b/Documentation/SBV/Examples/BitPrecise/MergeSort.hs
--- a/Documentation/SBV/Examples/BitPrecise/MergeSort.hs
+++ b/Documentation/SBV/Examples/BitPrecise/MergeSort.hs
@@ -9,6 +9,8 @@
 -- Symbolic implementation of merge-sort and its correctness.
 -----------------------------------------------------------------------------
 
+{-# LANGUAGE TupleSections #-}
+
 {-# OPTIONS_GHC -Wall -Werror #-}
 
 module Documentation.SBV.Examples.BitPrecise.MergeSort where
@@ -60,7 +62,7 @@
 -- is a subset of the other, when considered as a set. The check is slightly complicated
 -- for the need to account for possibly duplicated elements.
 isPermutationOf :: [E] -> [E] -> SBool
-isPermutationOf as bs = go as (zip bs (repeat sTrue)) .&& go bs (zip as (repeat sTrue))
+isPermutationOf as bs = go as (map (, sTrue) bs) .&& go bs (map (, sTrue) as)
   where go []     _  = sTrue
         go (x:xs) ys = let (found, ys') = mark x ys in found .&& go xs ys'
         -- Go and mark off an instance of 'x' in the list, if possible. We keep track
diff --git a/Documentation/SBV/Examples/Crypto/AES.hs b/Documentation/SBV/Examples/Crypto/AES.hs
--- a/Documentation/SBV/Examples/Crypto/AES.hs
+++ b/Documentation/SBV/Examples/Crypto/AES.hs
@@ -31,7 +31,7 @@
 
 module Documentation.SBV.Examples.Crypto.AES where
 
-import Control.Monad (void)
+import Control.Monad (void, when)
 
 import Data.SBV
 import Data.SBV.Tools.CodeGen
@@ -42,6 +42,8 @@
 
 import Numeric (showHex)
 
+import Test.QuickCheck hiding (verbose)
+
 -- $setup
 -- >>> -- For doctest purposes only:
 -- >>> import Data.SBV
@@ -56,7 +58,7 @@
 
 -- | Multiplication in GF(2^8). This is simple polynomial multiplication, followed
 -- by the irreducible polynomial @x^8+x^4+x^3+x^1+1@. We simply use the 'pMult'
--- function exported by SBV to do the operation. 
+-- function exported by SBV to do the operation.
 gf28Mult :: GF28 -> GF28 -> GF28
 gf28Mult x y = pMult (x, y, [8, 4, 3, 1, 0])
 
@@ -146,13 +148,13 @@
 keyExpansion nk key = chop4 keys
    where keys :: [SWord 32]
          keys = key ++ [nextWord i prev old | i <- [nk ..] | prev <- drop (nk-1) keys | old <- keys]
-         chop4 :: [a] -> [[a]]
-         chop4 xs = let (f, r) = splitAt 4 xs in f : chop4 r
+
          nextWord :: Int -> SWord 32 -> SWord 32 -> SWord 32
          nextWord i prev old
            | i `mod` nk == 0           = old `xor` subWordRcon (prev `rotateL` 8) (roundConstants !! (i `div` nk))
            | i `mod` nk == 4 && nk > 6 = old `xor` subWordRcon prev 0
            | True                      = old `xor` prev
+
          subWordRcon :: SWord 32 -> GF28 -> SWord 32
          subWordRcon w rc = fromBytes [a `xor` rc, b, c, d]
             where [a, b, c, d] = map sbox $ toBytes w
@@ -307,7 +309,9 @@
 
 -- | Key schedule. Given a 128, 192, or 256 bit key, expand it to get key-schedules
 -- for encryption and decryption. The key is given as a sequence of 32-bit words.
--- (4 elements for 128-bits, 6 for 192, and 8 for 256.)
+-- (4 elements for 128-bits, 6 for 192, and 8 for 256.) Compare this function to 'aesInvKeySchedule'
+-- which can calculate the key-expansion for decryption on the fly, as opposed to calculating
+-- the forward key-expansion first.
 aesKeySchedule :: Key -> (KS, KS)
 aesKeySchedule key
   | nk `elem` [4, 6, 8]
@@ -342,9 +346,152 @@
   = error "aesDecrypt: Invalid cipher-text size"
 
 -----------------------------------------------------------------------------
+-- * On-the-fly decryption
+-- ${ontheflyintro}
+-----------------------------------------------------------------------------
+{- $ontheflyintro
+   While regular encryption can be fused with key-generation, the standard method of AES
+   decryption has to perform the key-expansion before decryption starts. This can be undesirable
+   as it necessarily serializes the action of key-expansion before decryption. An
+   alternative is to do on-the-fly decryption: We can expand the key in reverse, and thus
+   need not save the key-schedule. One downside of this approach, however, is that we need
+   to keep the "unwound" key: That is, instead of the common key used for encryption and
+   decryption, we need to hold on to the final value of key-expansion, so it can be run
+   in reverse. In this section, we implement on-the-fly decryption using this idea.
+-}
+
+-- | Inverse key expansion. Starting from the final round key, unwinds key generation operation
+-- to construct keys for the previous rounds. Used in on-the-fly decryption.
+invKeyExpansion :: Int -> Key -> [Key]
+invKeyExpansion nk rkey = map reverse (chop4 keys)
+   where keys :: [SWord 32]
+         keys = rkey ++ [invNextWord i prev old | i <- reverse [0 .. remaining - 1] | prev <- drop 1 keys | old <- keys]
+
+         totalWords = 4 * (nk + 6 + 1)
+         remaining  = totalWords - nk
+
+         invNextWord :: Int -> SWord 32 -> SWord 32 -> SWord 32
+         invNextWord i prev old
+           | i `mod` nk == 0           = old `xor` subWordRcon (prev `rotateL` 8) (roundConstants !! (1 + i `div` nk))
+           | i `mod` nk == 4 && nk > 6 = old `xor` subWordRcon prev 0
+           | True                      = old `xor` prev
+
+         subWordRcon :: SWord 32 -> GF28 -> SWord 32
+         subWordRcon w rc = fromBytes [a `xor` rc, b, c, d]
+            where [a, b, c, d] = map sbox $ toBytes w
+
+-- | AES inverse key schedule. Starting from the last-round key, construct the sequence of keys
+-- that can be used for doing on-the-fly decryption. Compare this function to 'aesKeySchedule' which
+-- returns both encryption and decryption schedules: In this case, we don't calculate the encryption
+-- sequence, hence we can fuse this function with the decryption operation.
+aesInvKeySchedule :: Key -> KS
+aesInvKeySchedule key
+  | nk `elem` [4, 6, 8]
+  = decKS
+  | True
+  = error "aesInvKeySchedule: Invalid key size"
+  where nk = length key
+        nr = nk + 6
+        decKS = (head rKeys, take (nr-1) (tail rKeys), rKeys !! nr)
+        rKeys = invKeyExpansion nk key
+
+-- | Block decryption, starting from the unwound key. That is, start from the final key.
+-- Also; we don't use the T-box implementation. Just pure AES inverse cipher.
+aesDecryptUnwoundKey :: [SWord 32] -> KS -> [SWord 32]
+aesDecryptUnwoundKey ct decKS
+  | length ct == 4
+  = doRounds aesInvRoundRegular decKS ct
+  | True
+  = error "aesDecrypt: Invalid cipher-text size"
+  where aesInvRoundRegular isFinal s key = u
+          where u :: State
+                u = map (f isFinal) [0 .. 3]
+                  where a   = map toBytes s
+                        kbs = map toBytes key
+                        f True j = fromBytes [ unSBox (a !! ((j+0) `mod` 4) !! 0)
+                                             , unSBox (a !! ((j+3) `mod` 4) !! 1)
+                                             , unSBox (a !! ((j+2) `mod` 4) !! 2)
+                                             , unSBox (a !! ((j+1) `mod` 4) !! 3)
+                                             ] `xor` (key !! j)
+                        f False j = e0 `xor` e1 `xor` e2 `xor` e3
+                              where e0 = otfU0 $ unSBox (a !! ((j+0) `mod` 4) !! 0) `xor` (kbs !! j !! 0)
+                                    e1 = otfU1 $ unSBox (a !! ((j+3) `mod` 4) !! 1) `xor` (kbs !! j !! 1)
+                                    e2 = otfU2 $ unSBox (a !! ((j+2) `mod` 4) !! 2) `xor` (kbs !! j !! 2)
+                                    e3 = otfU3 $ unSBox (a !! ((j+1) `mod` 4) !! 3) `xor` (kbs !! j !! 3)
+
+                otfU0Func b = [b `gf28Mult` 0xE, b `gf28Mult` 0x9, b `gf28Mult` 0xD, b `gf28Mult` 0xB]
+                otfU0 = select t0Table 0 where t0Table = [fromBytes (otfU0Func a)          | a <- [0..255]]
+                otfU1 = select t1Table 0 where t1Table = [fromBytes (otfU0Func a `rotR` 1) | a <- [0..255]]
+                otfU2 = select t2Table 0 where t2Table = [fromBytes (otfU0Func a `rotR` 2) | a <- [0..255]]
+                otfU3 = select t3Table 0 where t3Table = [fromBytes (otfU0Func a `rotR` 3) | a <- [0..255]]
+
+-----------------------------------------------------------------------------
 -- * Test vectors
 -----------------------------------------------------------------------------
 
+-- | Common plain text for test vectors
+commonPT :: [SWord 32]
+commonPT = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]
+
+-- | Key for 128-bit encryption test
+aes128Key :: Key
+aes128Key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]
+
+-- | Key for 192-bit encryption test
+aes192Key :: Key
+aes192Key = aes128Key ++ [0x10111213, 0x14151617]
+
+-- | Key for 256-bit encryption test
+aes256Key :: Key
+aes256Key = aes192Key ++ [0x18191a1b, 0x1c1d1e1f]
+
+-- | Expected cipher-text for 128-bit encryption
+aes128CT :: [SWord 32]
+aes128CT = [0x69c4e0d8, 0x6a7b0430, 0xd8cdb780, 0x70b4c55a]
+
+-- | Expected cipher-text for 192-bit encryption
+aes192CT :: [SWord 32]
+aes192CT = [0xdda97ca4, 0x864cdfe0, 0x6eaf70a0, 0xec0d7191]
+
+-- | Expected cipher-text for 256-bit encryption
+aes256CT :: [SWord 32]
+aes256CT = [0x8ea2b7ca, 0x516745bf, 0xeafc4990, 0x4b496089]
+
+-- | Calculate the 128-bit final-round key from on-the-fly decryption key schedule
+aes128InvKey :: Key
+aes128InvKey = extractFinalKey aes128Key
+
+-- | Calculate the 192-bit final-round key from on-the-fly decryption key schedule
+aes192InvKey :: Key
+aes192InvKey = extractFinalKey aes192Key
+
+-- | Calculate the 192-bit final-round key from on-the-fly decryption key schedule. Compare this
+-- to 'aes192InvKey': Typically we just need the final 6-blocks, but it is advantageous to have
+-- the entire last 8-blocks even for 192-bit keys. That is,  e store the final 256-bits of key-expansion
+-- for speed purposes for both 192 and 256 bit versions. (But only the final 128 bits for the 128-bit version.)
+aes192InvKeyExtended :: Key
+aes192InvKeyExtended = extractFinalKeyExtended aes192Key
+
+-- | Calculate the 256-bit final-round key from on-the-fly decryption key schedule
+aes256InvKey :: Key
+aes256InvKey = extractFinalKey aes256Key
+
+-- | Extract the final key for on-the-fly decryption. This will extract exactly the number of blocks we need.
+extractFinalKey :: [SWord 32] -> [SWord 32]
+extractFinalKey initKey = take nk (extractFinalKeyExtended initKey)
+  where nk = length initKey
+
+-- | Extract the extended key for on-the-fly decryption. This will extract 4-blocks for 128-bit decryption,
+-- but 256 bit for both 192 and 256-bit variants
+extractFinalKeyExtended :: [SWord 32] -> [SWord 32]
+extractFinalKeyExtended initKey = take feed (concatMap reverse (chop4 (take feed roundKeys)))
+  where nk             = length initKey
+        feed | nk == 4 = 4
+             | True    = 8
+
+        ((f, m, l), _) = aesKeySchedule initKey
+        roundKeys      = l ++ concat (reverse m) ++ f
+
 -----------------------------------------------------------------------------
 -- ** 128-bit enc/dec test
 -----------------------------------------------------------------------------
@@ -353,23 +500,17 @@
 --
 -- >>> map hex8 t128Enc
 -- ["69c4e0d8","6a7b0430","d8cdb780","70b4c55a"]
---
 t128Enc :: [SWord 32]
-t128Enc = aesEncrypt pt ks
-  where pt  = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]
-        key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]
-        (ks, _) = aesKeySchedule key
+t128Enc = aesEncrypt commonPT ks
+  where (ks, _) = aesKeySchedule aes128Key
 
 -- | 128-bit decryption test, from Appendix C.1 of the AES standard:
 --
 -- >>> map hex8 t128Dec
 -- ["00112233","44556677","8899aabb","ccddeeff"]
---
 t128Dec :: [SWord 32]
-t128Dec = aesDecrypt ct ks
-  where ct  = [0x69c4e0d8, 0x6a7b0430, 0xd8cdb780, 0x70b4c55a]
-        key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]
-        (_, ks) = aesKeySchedule key
+t128Dec = aesDecrypt aes128CT ks
+  where (_, ks) = aesKeySchedule aes128Key
 
 -----------------------------------------------------------------------------
 -- ** 192-bit enc/dec test
@@ -379,12 +520,9 @@
 --
 -- >>> map hex8 t192Enc
 -- ["dda97ca4","864cdfe0","6eaf70a0","ec0d7191"]
---
 t192Enc :: [SWord 32]
-t192Enc = aesEncrypt pt ks
-  where pt  = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]
-        key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617]
-        (ks, _) = aesKeySchedule key
+t192Enc = aesEncrypt commonPT ks
+  where (ks, _) = aesKeySchedule aes192Key
 
 -- | 192-bit decryption test, from Appendix C.2 of the AES standard:
 --
@@ -392,10 +530,8 @@
 -- ["00112233","44556677","8899aabb","ccddeeff"]
 --
 t192Dec :: [SWord 32]
-t192Dec = aesDecrypt ct ks
-  where ct  = [0xdda97ca4, 0x864cdfe0, 0x6eaf70a0, 0xec0d7191]
-        key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617]
-        (_, ks) = aesKeySchedule key
+t192Dec = aesDecrypt aes192CT ks
+  where (_, ks) = aesKeySchedule aes192Key
 
 -----------------------------------------------------------------------------
 -- ** 256-bit enc/dec test
@@ -405,25 +541,128 @@
 --
 -- >>> map hex8 t256Enc
 -- ["8ea2b7ca","516745bf","eafc4990","4b496089"]
---
 t256Enc :: [SWord 32]
-t256Enc = aesEncrypt pt ks
-  where pt  = [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]
-        key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f]
-        (ks, _) = aesKeySchedule key
+t256Enc = aesEncrypt commonPT ks
+  where (ks, _) = aesKeySchedule aes256Key
 
 -- | 256-bit decryption, from Appendix C.3 of the AES standard:
 --
 -- >>> map hex8 t256Dec
 -- ["00112233","44556677","8899aabb","ccddeeff"]
---
 t256Dec :: [SWord 32]
-t256Dec = aesDecrypt ct ks
-  where ct  = [0x8ea2b7ca, 0x516745bf, 0xeafc4990, 0x4b496089]
-        key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f, 0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f]
-        (_, ks) = aesKeySchedule key
+t256Dec = aesDecrypt aes256CT ks
+  where (_, ks) = aesKeySchedule aes256Key
 
+-- | Various tests for round-trip properties. We have:
+--
+-- >>> runAESTests False
+-- GOOD: Key generation AES128
+-- GOOD: Key generation AES192
+-- GOOD: Key generation AES256
+-- GOOD: Encryption     AES128
+-- GOOD: Decryption     AES128
+-- GOOD: Decryption-OTF AES128
+-- GOOD: Encryption     AES192
+-- GOOD: Decryption     AES192
+-- GOOD: Decryption-OTF AES192
+-- GOOD: Encryption     AES256
+-- GOOD: Decryption     AES256
+-- GOOD: Decryption-OTF AES256
+runAESTests :: Bool -> IO ()
+runAESTests runQC = do
+                 testInvKeyExpansion
 
+                 check "AES128" aes128Key aes128InvKey aes128CT
+                 check "AES192" aes192Key aes192InvKey aes192CT
+                 check "AES256" aes256Key aes256InvKey aes256CT
+
+                 -- Quick-check tests are rather slow. So only run when requested.
+                 when runQC $ do
+                   putStrLn "Quick-check AES128 roundtrip" >> quickCheck roundTrip128
+                   putStrLn "Quick-check AES192 roundtrip" >> quickCheck roundTrip192
+                   putStrLn "Quick-check AES256 roundtrip" >> quickCheck roundTrip256
+
+  where check :: String -> Key -> Key -> [SWord 32] -> IO ()
+        check what key invKey ctExpected = do eq ("Encryption     " ++ what) ctExpected ctGot
+                                              eq ("Decryption     " ++ what) commonPT   ptGot
+                                              eq ("Decryption-OTF " ++ what) commonPT   ptGotInv
+           where (encKS, decKS) = aesKeySchedule key
+                 ctGot          = aesEncrypt           commonPT   encKS
+                 ptGot          = aesDecrypt           ctExpected decKS
+                 ptGotInv       = aesDecryptUnwoundKey ctExpected (aesInvKeySchedule invKey)
+
+                 eq tag expected got
+                   | length expected /= length got
+                   = error $ unlines [ "BAD!: " ++ tag
+                                     , "Comparing different sized lists:"
+                                     , "Expected: " ++ show expected
+                                     , "Got     : " ++ show got
+                                     ]
+                   | map extract expected == map extract got
+                   = putStrLn $ "GOOD: " ++ tag
+                   | True
+                   = error $ unlines [ "BAD!: " ++ tag
+                                     , "Expected: " ++ unwords (map hex8 expected)
+                                     , "Got     : " ++ unwords (map hex8 got)
+                                     ]
+                  where extract :: SWord 32 -> Integer
+                        extract = fromIntegral . fromJust . unliteral
+
+        testInvKeyExpansion :: IO ()
+        testInvKeyExpansion = do goTestInvKey "128" aes128Key
+                                 goTestInvKey "192" aes192Key
+                                 goTestInvKey "256" aes256Key
+        goTestInvKey what k = do
+          let nk = length k
+              nr = nk + 6
+
+              feed = case nk of
+                       4 -> 4
+                       _ -> 8
+
+              ((f, m, l), _) = aesKeySchedule k
+              required       = l ++ concat (reverse m) ++ f
+              invKeySchedule = take (nr+1) $ invKeyExpansion nk (take nk (concatMap reverse (chop4 (take feed required))))
+              obtained       = concat invKeySchedule
+
+              expected = map (fromJust . unliteral) required
+              result   = map (fromJust . unliteral) obtained
+
+              sh i a b
+               | a == b = pad ++ show i ++ " " ++ disp a
+               | True   = pad ++ show i ++ " " ++ disp a ++ " |vs| " ++ disp b
+               where pad = if i < 10 then " " else ""
+
+              disp = unwords . map (hex8 . literal)
+
+              lexpected = length expected
+              lresult   = length result
+
+          when (lexpected /= lresult) $
+             error $ what ++ ": BAD! Mismatching lengths: " ++ show (lexpected, lresult)
+
+          let debugging = False
+
+          if expected == result
+             then if debugging
+                     then putStrLn $ unlines $ ("Size " ++ what ++ ": Good") : zipWith3 sh [(0::Int)..] (chop4 expected) (chop4 result)
+                     else putStrLn $ "GOOD: Key generation AES" ++ what
+             else error    $ unlines $ ("Size " ++ what ++ ": BAD!") : zipWith3 sh [(0::Int)..] (chop4 expected) (chop4 result)
+
+        roundTrip128 (i0, i1, i2, i3) (k0, k1, k2, k3)                 = roundTrip [i0, i1, i2, i3] [k0, k1, k2, k3]
+        roundTrip192 (i0, i1, i2, i3) (k0, k1, k2, k3, k4, k5)         = roundTrip [i0, i1, i2, i3] [k0, k1, k2, k3, k4, k5]
+        roundTrip256 (i0, i1, i2, i3) (k0, k1, k2, k3, k4, k5, k6, k7) = roundTrip [i0, i1, i2, i3] [k0, k1, k2, k3, k4, k5, k6, k7]
+
+        roundTrip :: [SWord32] -> [SWord32] -> SBool
+        roundTrip ptIn keyIn = pt .== pt' .&& pt .== pt''
+           where pt  = map toSized ptIn
+                 key = map toSized keyIn
+
+                 (encKS, decKS) = aesKeySchedule key
+                 ct   = aesEncrypt pt encKS
+                 pt'  = aesDecrypt ct decKS
+                 pt'' = aesDecryptUnwoundKey ct (aesInvKeySchedule (extractFinalKey key))
+
 -----------------------------------------------------------------------------
 -- * Verification
 -- ${verifIntro}
@@ -449,7 +688,7 @@
 -- @
 --   quickCheck aes128IsCorrect
 -- @
--- 
+--
 -- and get some degree of confidence in our code. Similar predicates can be easily constructed for 192, and
 -- 256 bit cases as well.
 aes128IsCorrect :: (SWord 32, SWord 32, SWord 32, SWord 32)  -- ^ plain-text words
@@ -511,9 +750,10 @@
 cgAES128BlockEncrypt = compileToC Nothing "aes128BlockEncrypt" $ do
         pt  <- cgInputArr 4 "pt"        -- plain-text as an array of 4 Word32's
         key <- cgInputArr 4 "key"       -- key as an array of 4 Word32s
+
         -- Use the test values from Appendix C.1 of the AES standard as the driver values
-        cgSetDriverValues $    [0x00112233, 0x44556677, 0x8899aabb, 0xccddeeff]
-                            ++ [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]
+        cgSetDriverValues $ map (fromIntegral . fromJust . unliteral) $ commonPT ++ aes128Key
+
         let (encKs, _) = aesKeySchedule key
         cgOutputArr "ct" $ aesEncrypt pt encKs
 
@@ -530,33 +770,65 @@
    The generated library is a typical @.a@ archive, that can be linked using the C-compiler as usual.
 -}
 
--- | Components of the AES implementation that the library is generated from
-aesLibComponents :: Int -> [(String, SBVCodeGen ())]
-aesLibComponents sz = [ ("aes" ++ show sz ++ "KeySchedule",  keySchedule)
-                      , ("aes" ++ show sz ++ "BlockEncrypt", enc)
-                      , ("aes" ++ show sz ++ "BlockDecrypt", dec)
+-- | Components of the AES implementation that the library is generated from. For each case, we provide
+-- the driver values from the AES test-vectors.
+aesLibComponents :: Int -> [(String, [Integer], SBVCodeGen ())]
+aesLibComponents sz = [ ("aes" ++ show sz ++ "KeySchedule",    keyDriverVals,    keySchedule)
+                      , ("aes" ++ show sz ++ "BlockEncrypt",   encDriverVals,    enc)
+                      , ("aes" ++ show sz ++ "BlockDecrypt",   decDriverVals,    dec)
+                      , ("aes" ++ show sz ++ "InvKeySchedule", invKeyDriverVals, invKeySchedule)
+                      , ("aes" ++ show sz ++ "OTFDecrypt",     invDecDriverVals, otfDec)
                       ]
-  where -- key-schedule
+  where badSize = error $ "aesLibComponents: Size must be one of 128, 192, or 256; received: " ++ show sz
+
+        -- key-schedule
         nk
          | sz == 128 = 4
          | sz == 192 = 6
          | sz == 256 = 8
-         | True      = error $ "aesLibComponents: Size must be one of 128, 192, or 256; received: " ++ show sz
+         | True      = badSize
+
         -- We get 4*(nr+1) keys, where nr = nk + 6
         nr = nk + 6
         xk = 4 * (nr + 1)
+
+        (keyDriverVals, invKeyDriverVals, encDriverVals, decDriverVals, invDecDriverVals)
+           | sz == 128 = (keyDriver aes128Key, keyDriver aes128InvKey, encDriver commonPT aes128Key, decDriver aes128CT aes128Key, invDecDriver aes128CT aes128InvKey)
+           | sz == 192 = (keyDriver aes192Key, keyDriver aes192InvKey, encDriver commonPT aes192Key, decDriver aes192CT aes192Key, invDecDriver aes192CT aes192InvKey)
+           | sz == 256 = (keyDriver aes256Key, keyDriver aes256InvKey, encDriver commonPT aes256Key, decDriver aes256CT aes256Key, invDecDriver aes256CT aes256InvKey)
+           | True      = badSize
+           where keyDriver       key = map cvt $ concatMap reverse (chop4 key)
+                 encDriver    pt key = map cvt $ pt ++ flatten (fst (aesKeySchedule    key))
+                 decDriver    ct key = map cvt $ ct ++ flatten (snd (aesKeySchedule    key))
+                 invDecDriver ct key = map cvt $ ct ++ flatten      (aesInvKeySchedule key)
+
+                 flatten (f, mid, l) = f ++ concat mid ++ l
+                 cvt = fromIntegral . fromJust . unliteral
+
         keySchedule = do key <- cgInputArr nk "key"     -- key
                          let (encKS, decKS) = aesKeySchedule key
                          cgOutputArr "encKS" (ksToXKey encKS)
                          cgOutputArr "decKS" (ksToXKey decKS)
+
+        invKeySchedule = do key <- cgInputArr nk "key"     -- key
+                            let decKS = aesInvKeySchedule (concatMap reverse (chop4 key))
+                            cgOutputArr "decKS" (ksToXKey decKS)
+
         -- encryption
         enc = do pt   <- cgInputArr 4  "pt"    -- plain-text
                  xkey <- cgInputArr xk "xkey"  -- expanded key
                  cgOutputArr "ct" $ aesEncrypt pt (xkeyToKS xkey)
+
         -- decryption
         dec = do pt   <- cgInputArr 4  "ct"    -- cipher-text
                  xkey <- cgInputArr xk "xkey"  -- expanded key
                  cgOutputArr "pt" $ aesDecrypt pt (xkeyToKS xkey)
+
+        -- on-the-fly decryption
+        otfDec = do ct   <- cgInputArr 4  "ct"    -- cipher-text
+                    xkey <- cgInputArr xk "xkey"  -- expanded key
+                    cgOutputArr "pt" $ aesDecryptUnwoundKey ct (xkeyToKS xkey)
+
         -- Transforming back and forth from our KS type to a flat array used by the generated C code
         -- Turn a series of expanded keys to our internal KS type
         xkeyToKS :: [SWord 32] -> KS
@@ -564,21 +836,20 @@
            where f  = take 4 xs                             -- first round key
                  m  = chop4 (take (xk - 8) (drop 4 xs))     -- middle rounds
                  l  = drop (xk - 4) xs                      -- last round key
+
         -- Turn a KS to a series of expanded key words
         ksToXKey :: KS -> [SWord 32]
         ksToXKey (f, m, l) = f ++ concat m ++ l
-        -- chunk in fours. (This function must be in some standard library, where?)
-        chop4 :: [a] -> [[a]]
-        chop4 [] = []
-        chop4 xs = let (f, r) = splitAt 4 xs in f : chop4 r
 
 -- | Generate code for AES functionality; given the key size.
 cgAESLibrary :: Int -> Maybe FilePath -> IO ()
 cgAESLibrary sz mbd
-  | sz `elem` [128, 192, 256] = void $ compileToCLib mbd nm (aesLibComponents sz)
+  | sz `elem` [128, 192, 256] = void $ compileToCLib mbd nm [(fnm, configure dvals f) | (fnm, dvals, f) <- aesLibComponents sz]
   | True                      = error $ "cgAESLibrary: Size must be one of 128, 192, or 256, received: " ++ show sz
   where nm = "aes" ++ show sz ++ "Lib"
 
+        configure dvals code = cgSetDriverValues dvals >> code
+
 -- | Generate a C library, containing functions for performing 128-bit enc/dec/key-expansion.
 -- A note on performance: In a very rough speed test, the generated code was able to do
 -- 6.3 million block encryptions per second on a decent MacBook Pro. On the same machine, OpenSSL
@@ -594,5 +865,11 @@
 hex8 v = replicate (8 - length s) '0' ++ s
   where s = flip showHex "" . fromJust . unliteral $ v
 
-{-# ANN aesRound    ("HLint: ignore Use head" :: String) #-}
-{-# ANN aesInvRound ("HLint: ignore Use head" :: String) #-}
+-- | Chunk in groups of 4. (This function must be in some standard library, where?)
+chop4 :: [a] -> [[a]]
+chop4 [] = []
+chop4 xs = let (f, r) = splitAt 4 xs in f : chop4 r
+
+{- HLint ignore aesRound             "Use head" -}
+{- HLint ignore aesInvRound          "Use head" -}
+{- HLint ignore aesDecryptUnwoundKey "Use head" -}
diff --git a/Documentation/SBV/Examples/Crypto/Prince.hs b/Documentation/SBV/Examples/Crypto/Prince.hs
new file mode 100644
--- /dev/null
+++ b/Documentation/SBV/Examples/Crypto/Prince.hs
@@ -0,0 +1,266 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module    : Documentation.SBV.Examples.Crypto.Prince
+-- Copyright : (c) Levent Erkok
+-- License   : BSD3
+-- Maintainer: erkokl@gmail.com
+-- Stability : experimental
+--
+-- Implementation of Prince encryption and decrytion, following the spec
+-- <https://eprint.iacr.org/2012/529.pdf>
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE DataKinds        #-}
+{-# LANGUAGE ParallelListComp #-}
+
+{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
+
+module Documentation.SBV.Examples.Crypto.Prince where
+
+import Prelude hiding(round)
+import Numeric
+
+import Data.SBV
+import Data.SBV.Tools.CodeGen
+
+-- $setup
+-- >>> -- For doctest purposes only:
+-- >>> import Data.SBV
+
+-- * Types
+-- | Section 2: Prince is essentially a 64-bit cipher, with 128-bit key, coming in two parts.
+type Block = SWord 64
+
+-- | Plantext is simply a block.
+type PT = Block
+
+-- | Key is again a 64-bit block.
+type Key = Block
+
+-- | Cypher text is another 64-bit block.
+type CT = Block
+
+-- | A nibble is 4-bits. Ideally, we would like to represent a nibble by @SWord 4@; and indeed SBV can do that for
+-- verification purposes just fine. Unfortunately, the SBV's C compiler doesn't support 4-bit bit-vectors, as
+-- there's nothing meaningful in the C-land that we can map it to. Thus, we represent a nibble with 8-bits. The
+-- top 4 bits will always be 0.
+type Nibble = SWord 8
+
+-- * Key expansion
+
+-- | Expanding a key, from Section 3.4 of the spec.
+expandKey :: Key -> Key
+expandKey k = (k `rotateR` 1) `xor` (k `shiftR` 63)
+
+-- | expandKey(x) = x has a unique solution. We have:
+--
+-- >>> prop_ExpandKey
+-- Q.E.D.
+prop_ExpandKey :: IO ()
+prop_ExpandKey = do let lim = 10
+                    ms <- extractModels <$> allSatWith z3{allSatMaxModelCount = Just lim}
+                                                       (\x -> x .== expandKey x)
+                    case length ms of
+                      0 -> putStrLn "No solutions to equation `x == expandKey x`!"
+                      1 -> putStrLn "Q.E.D."
+                      n -> do let qual = if n == lim then "at least " else ""
+                              putStrLn $ "Failed. There are " ++ qual ++ show n ++ " solutions to `x == expandKey x`!"
+                              mapM_ (\i -> putStrLn ("    " ++ show i)) (ms :: [WordN 64])
+
+
+-- | Section 2: Encryption
+encrypt :: PT -> Key -> Key -> CT
+encrypt pt k0 k1 = prince k0 k0' k1 pt
+   where k0' = expandKey k0
+
+-- | Decryption
+decrypt :: CT -> Key -> Key -> PT
+decrypt ct k0 k1 = prince k0' k0 (k1 `xor` alpha) ct
+  where k0'   = expandKey k0
+        alpha = 0xc0ac29b7c97c50dd
+
+-- * Main algorithm
+
+-- | Basic prince algorithm
+prince :: Block -> Key -> Key -> Key -> Block
+prince k0 k0' k1 inp = out
+   where start = inp `xor` k0
+         end   = princeCore k1 start
+         out   = end `xor` k0'
+
+-- | Core prince. It's essentially folding of 12 rounds stitched together:
+princeCore :: Key -> Block -> Block
+princeCore k1 inp = end
+   where start    = inp `xor` k1 `xor` rConstants 0
+         front5   = foldl (round k1) start    [1 .. 5]
+         midPoint = sBoxInv . m' . sBox $ front5
+         back5    = foldl (invRound k1) midPoint [6..10]
+         end      = back5 `xor` rConstants 11 `xor` k1
+
+-- | Forward round.
+round :: Key -> Block -> Int -> Block
+round k1 b i = k1 `xor` rConstants i `xor` m (sBox b)
+
+-- | Backend round.
+invRound :: Key -> Block -> Int -> Block
+invRound k1 b i = sBoxInv (mInv (rConstants i `xor` (b `xor` k1)))
+
+-- | M transformation.
+m :: Block -> Block
+m = sr . m'
+
+-- | Inverse of M.
+mInv :: Block -> Block
+mInv = m' . srInv
+
+-- | SR.
+sr :: Block -> Block
+sr b = fromNibbles [n0, n5, n10, n15, n4, n9, n14, n3, n8, n13, n2, n7, n12, n1, n6, n11]
+  where [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15] = toNibbles b
+
+-- | Inverse of SR:
+srInv :: Block -> Block
+srInv b = fromNibbles [n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12, n13, n14, n15]
+  where [n0, n5, n10, n15, n4, n9, n14, n3, n8, n13, n2, n7, n12, n1, n6, n11] = toNibbles b
+
+-- | Prove sr and srInv are inverses: We have:
+--
+-- >>> prove prop_sr
+-- Q.E.D.
+prop_sr :: Predicate
+prop_sr = do b <- free "block"
+             return $   b .== sr (srInv b)
+                    .&& b .== srInv (sr b)
+
+-- | M' transformation
+m' :: Block -> Block
+m' = mMult
+
+-- | The matrix as described in Section 3.3
+mat :: [[Int]]
+mat = res
+  where m0 = [[0, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
+        m1 = [[1, 0, 0, 0], [0, 0, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
+        m2 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 0], [0, 0, 0, 1]]
+        m3 = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 0]]
+
+        rows as bs cs ds = [a ++ b ++ c ++ d | a <- as | b <- bs | c <- cs | d <- ds ]
+
+        m0' = concat [rows m0 m1 m2 m3, rows m1 m2 m3 m0, rows m2 m3 m0 m1, rows m3 m0 m1 m2]
+        m1' = concat [rows m1 m2 m3 m0, rows m2 m3 m0 m1, rows m3 m0 m1 m2, rows m0 m1 m2 m3]
+
+        zs  = replicate 16 (replicate 16 0)
+        res = concat [rows m0' zs  zs  zs, rows zs  m1' zs  zs, rows zs  zs  m1' zs, rows zs  zs  zs  m0']
+
+-- | Multiplication.
+mMult :: Block -> Block
+mMult b | length mat /= 64           = error $ "mMult: Expected 64 rows, got       : " ++ show (length mat)
+        | any ((/= 64) . length) mat = error $ "mMult: Expected 64 on each row, got: " ++ show [p | p@(_, l) <- zip [(1::Int)..] (map length mat), l /= 64]
+        | True                       = fromBitsBE $ map mult mat
+  where bits = blastBE b
+
+        mult :: [Int] -> SBool
+        mult row = foldr (.<+>) sFalse $ zipWith mul row bits
+
+        mul :: Int -> SBool -> SBool
+        mul 0 _ = sFalse
+        mul 1 v = v
+        mul i _ = error $ "mMult: Unexpected constant: " ++ show i
+
+-- | Non-linear transformation of a block
+nonLinear :: [Nibble] -> Nibble -> Block -> Block
+nonLinear box def = fromNibbles . map s . toNibbles
+  where s :: Nibble -> Nibble
+        s = select box def
+
+-- | SBox transformation.
+sBox :: Block -> Block
+sBox = nonLinear [0xB, 0xF, 0x3, 0x2, 0xA, 0xC, 0x9, 0x1, 0x6, 0x7, 0x8, 0x0, 0xE, 0x5, 0xD, 0x4] 0x0
+
+-- | Inverse SBox transformation.
+sBoxInv :: Block -> Block
+sBoxInv = nonLinear [0xB, 0x7, 0x3, 0x2, 0xF, 0xD, 0x8, 0x9, 0xA, 0x6, 0x4, 0x0, 0x5, 0xE, 0xC, 0x1] 0x0
+
+-- | Prove that sbox and sBoxInv are inverses: We have:
+--
+-- >>> prove prop_SBox
+-- Q.E.D.
+prop_SBox :: Predicate
+prop_SBox = do b <- free "block"
+               return $   b .== sBoxInv (sBox b)
+                      .&& b .== sBox (sBoxInv b)
+
+-- * Round constants
+
+-- | Round constants
+rConstants :: Int -> SWord 64
+rConstants  0 = 0x0000000000000000
+rConstants  1 = 0x13198a2e03707344
+rConstants  2 = 0xa4093822299f31d0
+rConstants  3 = 0x082efa98ec4e6c89
+rConstants  4 = 0x452821e638d01377
+rConstants  5 = 0xbe5466cf34e90c6c
+rConstants  6 = 0x7ef84f78fd955cb1
+rConstants  7 = 0x85840851f1ac43aa
+rConstants  8 = 0xc882d32f25323c54
+rConstants  9 = 0x64a51195e0e3610d
+rConstants 10 = 0xd3b5a399ca0c2399
+rConstants 11 = 0xc0ac29b7c97c50dd
+rConstants n  = error $ "rConstants called with invalid round number: " ++ show n
+
+-- | Round-constants property: rc_i `xor` rc_{11-i} is constant. We have:
+--
+-- >>> prop_RoundKeys
+-- True
+prop_RoundKeys :: SBool
+prop_RoundKeys = sAnd [magic .== rConstants i `xor` rConstants (11-i) | i <- [0 .. 11]]
+  where magic = rConstants 11
+
+-- | Convert a 64 bit word to nibbles
+toNibbles :: SWord 64 -> [Nibble]
+toNibbles = concatMap nibbles . toBytes
+  where nibbles :: SWord 8 -> [Nibble]
+        nibbles b = [b `shiftR` 4, b .&. 0xF]
+
+-- | Convert from nibbles to a 64 bit word
+fromNibbles :: [Nibble] -> SWord 64
+fromNibbles xs
+  | length xs /= 16 = error $ "fromNibbles: Incorrect number of nibbles, expected 16, got: " ++ show (length xs)
+  | True            = fromBytes $ cvt xs
+  where cvt (n1 : n2 : ns) = (n1 `shiftL` 4 .|. n2) : cvt ns
+        cvt _              = []
+
+-- * Test vectors
+
+-- | From Appendix A of the spec. We have:
+--
+-- >>> testVectors
+-- True
+testVectors :: SBool
+testVectors = sAnd $  [encrypt pt k0 k1 .== ct | (pt, k0, k1, ct) <- tvs]
+                   ++ [decrypt ct k0 k1 .== pt | (pt, k0, k1, ct) <- tvs]
+   where tvs :: [(SWord 64, SWord 64, SWord 64, SWord 64)]
+         tvs = [ (0x0000000000000000, 0x0000000000000000, 0x0000000000000000, 0x818665aa0d02dfda)
+               , (0xffffffffffffffff, 0x0000000000000000, 0x0000000000000000, 0x604ae6ca03c20ada)
+               , (0x0000000000000000, 0xffffffffffffffff, 0x0000000000000000, 0x9fb51935fc3df524)
+               , (0x0000000000000000, 0x0000000000000000, 0xffffffffffffffff, 0x78a54cbe737bb7ef)
+               , (0x0123456789abcdef, 0x0000000000000000, 0xfedcba9876543210, 0xae25ad3ca8fa9ccf)
+               ]
+
+-- | Nicely show a concrete block.
+showBlock :: Block -> String
+showBlock b =  case unliteral b of
+                 Just v  -> "0x" ++ pad (showHex v "")
+                 Nothing -> error "showBlock: Symbolic input!"
+  where pad s = reverse $ take 16 $ reverse s ++ repeat '0'
+
+-- * Code generation
+
+-- | Generating C code for the encryption block.
+codeGen :: IO ()
+codeGen = compileToC Nothing "enc" $ do
+               input <- cgInput "inp"
+               k0    <- cgInput "k0"
+               k1    <- cgInput "k1"
+               cgOverwriteFiles True
+               cgOutput "ct"  $ encrypt input k0 k1
diff --git a/Documentation/SBV/Examples/Crypto/SHA.hs b/Documentation/SBV/Examples/Crypto/SHA.hs
--- a/Documentation/SBV/Examples/Crypto/SHA.hs
+++ b/Documentation/SBV/Examples/Crypto/SHA.hs
@@ -28,8 +28,9 @@
 import Data.SBV
 import Data.SBV.Tools.CodeGen
 
+import Prelude hiding (Foldable(..))
 import Data.Char (ord, toLower)
-import Data.List (genericLength, foldl')
+import Data.List (genericLength, length, foldl')
 import Numeric   (showHex)
 
 import Data.Proxy (Proxy(..))
diff --git a/Documentation/SBV/Examples/Existentials/CRCPolynomial.hs b/Documentation/SBV/Examples/Existentials/CRCPolynomial.hs
--- a/Documentation/SBV/Examples/Existentials/CRCPolynomial.hs
+++ b/Documentation/SBV/Examples/Existentials/CRCPolynomial.hs
@@ -79,4 +79,4 @@
 findHD4Polynomials :: Int -> IO ()
 findHD4Polynomials = genPoly 4
 
-{-# ANN crc_48_16 ("HLint: ignore Use camelCase" :: String) #-}
+{- HLint ignore crc_48_16 "Use camelCase" -}
diff --git a/Documentation/SBV/Examples/Existentials/Diophantine.hs b/Documentation/SBV/Examples/Existentials/Diophantine.hs
--- a/Documentation/SBV/Examples/Existentials/Diophantine.hs
+++ b/Documentation/SBV/Examples/Existentials/Diophantine.hs
@@ -12,6 +12,7 @@
 
 {-# LANGUAGE DataKinds           #-}
 {-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TupleSections       #-}
 {-# LANGUAGE TypeApplications    #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
@@ -36,8 +37,8 @@
 
 instance Show Solution where
   show s = case s of
-             Homogeneous        xss -> comb supplyH (zip (repeat False) xss)
-             NonHomogeneous css xss -> intercalate "\n" [comb supplyNH ((True, cs) : zip (repeat False) xss) | cs <- css]
+             Homogeneous        xss -> comb supplyH (map (False,) xss)
+             NonHomogeneous css xss -> intercalate "\n" [comb supplyNH ((True, cs) : map (False,) xss) | cs <- css]
     where supplyH  = ['k' : replicate i '\'' | i <- [0 ..]]
           supplyNH = "" : supplyH
 
@@ -107,8 +108,8 @@
 -- We have:
 --
 -- >>> test
--- (k, 2+k', 2k+k')
--- (1+k, k', 2k+k')
+-- (k', 2+k, k+2k')
+-- (1+k', k, k+2k')
 --
 -- That is, for arbitrary @k@ and @k'@, we have two different solutions. (An infinite family.)
 -- You can verify these solutuions by substituting the values for @x@, @y@ and @z@ in the above, for each choice.
diff --git a/Documentation/SBV/Examples/Lists/BoundedMutex.hs b/Documentation/SBV/Examples/Lists/BoundedMutex.hs
--- a/Documentation/SBV/Examples/Lists/BoundedMutex.hs
+++ b/Documentation/SBV/Examples/Lists/BoundedMutex.hs
@@ -163,4 +163,4 @@
                                                      io . putStrLn $ "P2: " ++ show p2V
                                                      io . putStrLn $ "Ts: " ++ show ts
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/Puzzles/AOC_2021_24.hs b/Documentation/SBV/Examples/Puzzles/AOC_2021_24.hs
--- a/Documentation/SBV/Examples/Puzzles/AOC_2021_24.hs
+++ b/Documentation/SBV/Examples/Puzzles/AOC_2021_24.hs
@@ -149,14 +149,17 @@
 -----------------------------------------------------------------------------------------------
 
 -- | We simply run the 'monad' program, and specify the constraints at the end. We take a boolean
--- as a parameter, choosing whether we want to minimize or maximize the model-number. We have:
+-- as a parameter, choosing whether we want to minimize or maximize the model-number. Note that this
+-- test takes rather long to run. We get:
 --
--- >>> puzzle True
+-- @
+-- ghci> puzzle True
 -- Optimal model:
 --   Maximum model number = 96918996924991 :: Int64
--- >>> puzzle False
+-- ghci> puzzle False
 -- Optimal model:
 --   Minimum model number = 91811241911641 :: Int64
+-- @
 puzzle :: Bool -> IO ()
 puzzle shouldMaximize = print =<< optimizeWith z3{isNonModelVar = (/= finalVar)}  Lexicographic problem
   where finalVar | shouldMaximize = "Maximum model number"
@@ -440,4 +443,4 @@
            mul y x
            add z y
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/Puzzles/Birthday.hs b/Documentation/SBV/Examples/Puzzles/Birthday.hs
--- a/Documentation/SBV/Examples/Puzzles/Birthday.hs
+++ b/Documentation/SBV/Examples/Puzzles/Birthday.hs
@@ -126,3 +126,6 @@
 -- This is the only solution.
 cheryl :: IO ()
 cheryl = print =<< allSat puzzle
+
+{- HLint ignore puzzle "Redundant lambda" -}
+{- HLint ignore puzzle "Eta reduce"       -}
diff --git a/Documentation/SBV/Examples/Puzzles/Counts.hs b/Documentation/SBV/Examples/Puzzles/Counts.hs
--- a/Documentation/SBV/Examples/Puzzles/Counts.hs
+++ b/Documentation/SBV/Examples/Puzzles/Counts.hs
@@ -83,4 +83,4 @@
                      ++ ", of 8 is " ++ show (ns !! 8)
                      ++ ", of 9 is " ++ show (ns !! 9)
                      ++ "."
-{-# ANN counts ("HLint: ignore Use head" :: String) #-}
+{- HLint ignore counts "Use head" -}
diff --git a/Documentation/SBV/Examples/Puzzles/Murder.hs b/Documentation/SBV/Examples/Puzzles/Murder.hs
--- a/Documentation/SBV/Examples/Puzzles/Murder.hs
+++ b/Documentation/SBV/Examples/Puzzles/Murder.hs
@@ -88,8 +88,8 @@
 -- Alice     48  Bar    Female  Bystander
 -- Husband   47  Beach  Male    Killer
 -- Brother   48  Beach  Male    Victim
--- Daughter  20  Alone  Female  Bystander
--- Son       21  Bar    Male    Bystander
+-- Daughter  21  Alone  Female  Bystander
+-- Son       20  Bar    Male    Bystander
 --
 -- That is, Alice's brother was the victim and Alice's husband was the killer.
 killer :: IO ()
diff --git a/Documentation/SBV/Examples/Puzzles/Sudoku.hs b/Documentation/SBV/Examples/Puzzles/Sudoku.hs
--- a/Documentation/SBV/Examples/Puzzles/Sudoku.hs
+++ b/Documentation/SBV/Examples/Puzzles/Sudoku.hs
@@ -17,7 +17,7 @@
 module Documentation.SBV.Examples.Puzzles.Sudoku where
 
 #if MIN_VERSION_base(4,18,0)
-import Control.Monad (when)
+import Control.Monad (when, zipWithM_)
 #endif
 
 import Control.Monad.State.Lazy
@@ -73,7 +73,7 @@
                 case cs of
                   Sat   -> do vals <- mapM getValue subst
                               pure $ fill id vals
-                  Unsat -> error $ "Unsolvable puzzle!"
+                  Unsat -> error "Unsolvable puzzle!"
                   _     -> error $ "Solver said: " ++ show cs
 
  where fill xform = evalState (mapM (mapM replace) board)
@@ -88,10 +88,10 @@
 sudoku board = fillBoard board >>= displayBoard
  where displayBoard :: Puzzle -> IO ()
        displayBoard puzzle = do
-            let sh       (i, r) = show r ++ if i `elem` [3, 6] then " " else ""
-                printRow (i, r) = do putStrLn $ "    " ++ unwords (map sh (zip [(1::Int)..] r))
-                                     when (i `elem` [3, 6]) $ putStrLn ""
-            mapM_ printRow (zip [(1::Int)..] puzzle)
+            let sh       i r = show r ++ if i `elem` [3, 6] then " " else ""
+                printRow i r = do putStrLn $ "    " ++ unwords (zipWith sh [(1::Int)..] r)
+                                  when (i `elem` [3, 6]) $ putStrLn ""
+            zipWithM_ printRow [(1::Int)..] puzzle
 
             let isValid = valid (map (map literal) puzzle)
             case unliteral isValid of
diff --git a/Documentation/SBV/Examples/Queries/Concurrency.hs b/Documentation/SBV/Examples/Queries/Concurrency.hs
--- a/Documentation/SBV/Examples/Queries/Concurrency.hs
+++ b/Documentation/SBV/Examples/Queries/Concurrency.hs
@@ -173,4 +173,4 @@
   results <- satConcurrentWithAll z3 [firstQuery v1 v2, secondQuery v2] (sharedDependent v1)
   print results
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/Queries/Interpolants.hs b/Documentation/SBV/Examples/Queries/Interpolants.hs
--- a/Documentation/SBV/Examples/Queries/Interpolants.hs
+++ b/Documentation/SBV/Examples/Queries/Interpolants.hs
@@ -126,4 +126,4 @@
 
        query $ getInterpolantZ3 [y .== 2*x, y .== 2*z+1]
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/Documentation/SBV/Examples/Transformers/SymbolicEval.hs b/Documentation/SBV/Examples/Transformers/SymbolicEval.hs
--- a/Documentation/SBV/Examples/Transformers/SymbolicEval.hs
+++ b/Documentation/SBV/Examples/Transformers/SymbolicEval.hs
@@ -215,3 +215,5 @@
 ex3 :: IO (Either String CheckResult)
 ex3 = check (Program  $ Var "notAValidVar")
             (Property $ Var "result" `LessThan` Lit 10)
+
+{- HLint ignore module "Use fewer imports" -}
diff --git a/Documentation/SBV/Examples/Uninterpreted/Deduce.hs b/Documentation/SBV/Examples/Uninterpreted/Deduce.hs
--- a/Documentation/SBV/Examples/Uninterpreted/Deduce.hs
+++ b/Documentation/SBV/Examples/Uninterpreted/Deduce.hs
@@ -71,3 +71,6 @@
                   r <- free "r"
                   return $   not (p `or` (q `and` r))
                          .== (not p `and` not q) `or` (not p `and` not r)
+
+-- Hlint gets confused and thinks the use of @not@ above is from the prelude. Sigh.
+{- HLint ignore test "Redundant not" -}
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/Append.hs b/Documentation/SBV/Examples/WeakestPreconditions/Append.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/Append.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/Append.hs
@@ -17,6 +17,7 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NamedFieldPuns        #-}
 {-# LANGUAGE OverloadedLists       #-}
+{-# LANGUAGE TypeFamilies          #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -60,7 +61,8 @@
   show (AppC xs ys ts zs) = "{xs = " P.++ show xs P.++ ", ys = " P.++ show ys P.++ ", ts = " P.++ show ts P.++ ", zs = " P.++ show zs P.++ "}"
 
 -- | 'Queriable' instance for the program state
-instance Queriable IO (AppS Integer) (AppC Integer) where
+instance Queriable IO (AppS Integer) where
+  type QueryResult (AppS Integer) = AppC Integer
   create                     = AppS <$> freshVar_   <*> freshVar_   <*> freshVar_   <*> freshVar_
   project (AppS xs ys ts zs) = AppC <$> getValue xs <*> getValue ys <*> getValue ts <*> getValue zs
   embed   (AppC xs ys ts zs) = return $ AppS (literal xs) (literal ys) (literal ts) (literal zs)
diff --git a/Documentation/SBV/Examples/WeakestPreconditions/Length.hs b/Documentation/SBV/Examples/WeakestPreconditions/Length.hs
--- a/Documentation/SBV/Examples/WeakestPreconditions/Length.hs
+++ b/Documentation/SBV/Examples/WeakestPreconditions/Length.hs
@@ -16,6 +16,7 @@
 {-# LANGUAGE FlexibleInstances     #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE NamedFieldPuns        #-}
+{-# LANGUAGE TypeFamilies          #-}
 
 {-# OPTIONS_GHC -Wall -Werror #-}
 
@@ -58,7 +59,8 @@
 
 -- | We have to write the bijection between 'LenS' and 'LenC' explicitly. Luckily, the
 -- definition is more or less boilerplate.
-instance Queriable IO (LenS Integer) (LenC Integer) where
+instance Queriable IO (LenS Integer) where
+  type QueryResult (LenS Integer) = LenC Integer
   create                 = LenS <$> freshVar_   <*> freshVar_   <*> freshVar_
   project (LenS xs ys l) = LenC <$> getValue xs <*> getValue ys <*> getValue l
   embed   (LenC xs ys l) = return $ LenS (literal xs) (literal ys) (literal l)
diff --git a/SBVTestSuite/GoldFiles/aes128Lib.gold b/SBVTestSuite/GoldFiles/aes128Lib.gold
--- a/SBVTestSuite/GoldFiles/aes128Lib.gold
+++ b/SBVTestSuite/GoldFiles/aes128Lib.gold
@@ -3307,209 +3307,1768 @@
   pt[3] = s1808;
 }
 == END: "aes128BlockDecrypt.c" ==================
-== BEGIN: "aes128Lib.h" ================
-/* Header file for aes128Lib. Automatically generated by SBV. Do not edit! */
-
-#ifndef __aes128Lib__HEADER_INCLUDED__
-#define __aes128Lib__HEADER_INCLUDED__
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <math.h>
-
-/* The boolean type */
-typedef bool SBool;
-
-/* The float type */
-typedef float SFloat;
-
-/* The double type */
-typedef double SDouble;
-
-/* Unsigned bit-vectors */
-typedef uint8_t  SWord8;
-typedef uint16_t SWord16;
-typedef uint32_t SWord32;
-typedef uint64_t SWord64;
-
-/* Signed bit-vectors */
-typedef int8_t  SInt8;
-typedef int16_t SInt16;
-typedef int32_t SInt32;
-typedef int64_t SInt64;
-
-/* Entry point prototypes: */
-void aes128KeySchedule(const SWord32 *key, SWord32 *encKS,
-                       SWord32 *decKS);
-void aes128BlockEncrypt(const SWord32 *pt, const SWord32 *xkey,
-                        SWord32 *ct);
-void aes128BlockDecrypt(const SWord32 *ct, const SWord32 *xkey,
-                        SWord32 *pt);
-
-#endif /* __aes128Lib__HEADER_INCLUDED__ */
-== END: "aes128Lib.h" ==================
-== BEGIN: "aes128Lib_driver.c" ================
-/* Example driver program for aes128Lib. */
-/* Automatically generated by SBV. Edit as you see fit! */
-
-#include <stdio.h>
-#include "aes128Lib.h"
-
-void aes128KeySchedule_driver(void)
-{
-  const SWord32 key[4] = {
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
-  };
-
-  printf("Contents of input array key:\n");
-  int key_ctr;
-  for(key_ctr = 0; key_ctr < 4 ; ++key_ctr)
-    printf("  key[%1d] = 0x%08"PRIx32"UL\n", key_ctr ,key[key_ctr]);
-
-  SWord32 encKS[44];
-  SWord32 decKS[44];
-
-  aes128KeySchedule(key, encKS, decKS);
-
-  printf("aes128KeySchedule(key, encKS, decKS) ->\n");
-  int encKS_ctr;
-  for(encKS_ctr = 0; encKS_ctr < 44 ; ++encKS_ctr)
-    printf("  encKS[%2d] = 0x%08"PRIx32"UL\n", encKS_ctr ,encKS[encKS_ctr]);
-  int decKS_ctr;
-  for(decKS_ctr = 0; decKS_ctr < 44 ; ++decKS_ctr)
-    printf("  decKS[%2d] = 0x%08"PRIx32"UL\n", decKS_ctr ,decKS[decKS_ctr]);
-}
-
-void aes128BlockEncrypt_driver(void)
-{
-  const SWord32 pt[4] = {
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
-  };
-
-  printf("Contents of input array pt:\n");
-  int pt_ctr;
-  for(pt_ctr = 0; pt_ctr < 4 ; ++pt_ctr)
-    printf("  pt[%1d] = 0x%08"PRIx32"UL\n", pt_ctr ,pt[pt_ctr]);
-
-  const SWord32 xkey[44] = {
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
-  };
-
-  printf("Contents of input array xkey:\n");
-  int xkey_ctr;
-  for(xkey_ctr = 0; xkey_ctr < 44 ; ++xkey_ctr)
-    printf("  xkey[%2d] = 0x%08"PRIx32"UL\n", xkey_ctr ,xkey[xkey_ctr]);
-
-  SWord32 ct[4];
-
-  aes128BlockEncrypt(pt, xkey, ct);
-
-  printf("aes128BlockEncrypt(pt, xkey, ct) ->\n");
-  int ct_ctr;
-  for(ct_ctr = 0; ct_ctr < 4 ; ++ct_ctr)
-    printf("  ct[%1d] = 0x%08"PRIx32"UL\n", ct_ctr ,ct[ct_ctr]);
-}
-
-void aes128BlockDecrypt_driver(void)
-{
-  const SWord32 ct[4] = {
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
-  };
-
-  printf("Contents of input array ct:\n");
-  int ct_ctr;
-  for(ct_ctr = 0; ct_ctr < 4 ; ++ct_ctr)
-    printf("  ct[%1d] = 0x%08"PRIx32"UL\n", ct_ctr ,ct[ct_ctr]);
-
-  const SWord32 xkey[44] = {
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
-      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
-  };
-
-  printf("Contents of input array xkey:\n");
-  int xkey_ctr;
-  for(xkey_ctr = 0; xkey_ctr < 44 ; ++xkey_ctr)
-    printf("  xkey[%2d] = 0x%08"PRIx32"UL\n", xkey_ctr ,xkey[xkey_ctr]);
-
-  SWord32 pt[4];
-
-  aes128BlockDecrypt(ct, xkey, pt);
-
-  printf("aes128BlockDecrypt(ct, xkey, pt) ->\n");
-  int pt_ctr;
-  for(pt_ctr = 0; pt_ctr < 4 ; ++pt_ctr)
-    printf("  pt[%1d] = 0x%08"PRIx32"UL\n", pt_ctr ,pt[pt_ctr]);
-}
-
-int main(void)
-{
-  printf("====================================\n");
-  printf("** Driver run for aes128KeySchedule:\n");
-  printf("====================================\n");
-  aes128KeySchedule_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for aes128BlockEncrypt:\n");
-  printf("=====================================\n");
-  aes128BlockEncrypt_driver();
-
-  printf("=====================================\n");
-  printf("** Driver run for aes128BlockDecrypt:\n");
-  printf("=====================================\n");
-  aes128BlockDecrypt_driver();
-
-  return 0;
-}
-== END: "aes128Lib_driver.c" ==================
-== BEGIN: "Makefile" ================
-# Makefile for aes128Lib. Automatically generated by SBV. Do not edit!
-
-# include any user-defined .mk file in the current directory.
--include *.mk
-
-CC?=gcc
-CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer
-AR?=ar
-ARFLAGS?=cr
-
-all: aes128Lib.a aes128Lib_driver
-
-aes128Lib.a: aes128KeySchedule.o aes128BlockEncrypt.o aes128BlockDecrypt.o
-	${AR} ${ARFLAGS} $@ $^
-
-aes128Lib_driver: aes128Lib_driver.c aes128Lib.h
-	${CC} ${CCFLAGS} $< -o $@ aes128Lib.a
-
-aes128KeySchedule.o: aes128KeySchedule.c aes128Lib.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-aes128BlockEncrypt.o: aes128BlockEncrypt.c aes128Lib.h
-	${CC} ${CCFLAGS} -c $< -o $@
-
-aes128BlockDecrypt.o: aes128BlockDecrypt.c aes128Lib.h
+== BEGIN: "aes128InvKeySchedule.c" ================
+/* File: "aes128InvKeySchedule.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Lib.h"
+
+void aes128InvKeySchedule(const SWord32 *key, SWord32 *decKS)
+{
+  const SWord32 s0 = key[0];
+  const SWord32 s1 = key[1];
+  const SWord32 s2 = key[2];
+  const SWord32 s3 = key[3];
+  static const SWord8 table0[] = {
+       99, 124, 119, 123, 242, 107, 111, 197,  48,   1, 103,  43, 254,
+      215, 171, 118, 202, 130, 201, 125, 250,  89,  71, 240, 173, 212,
+      162, 175, 156, 164, 114, 192, 183, 253, 147,  38,  54,  63, 247,
+      204,  52, 165, 229, 241, 113, 216,  49,  21,   4, 199,  35, 195,
+       24, 150,   5, 154,   7,  18, 128, 226, 235,  39, 178, 117,   9,
+      131,  44,  26,  27, 110,  90, 160,  82,  59, 214, 179,  41, 227,
+       47, 132,  83, 209,   0, 237,  32, 252, 177,  91, 106, 203, 190,
+       57,  74,  76,  88, 207, 208, 239, 170, 251,  67,  77,  51, 133,
+       69, 249,   2, 127,  80,  60, 159, 168,  81, 163,  64, 143, 146,
+      157,  56, 245, 188, 182, 218,  33,  16, 255, 243, 210, 205,  12,
+       19, 236,  95, 151,  68,  23, 196, 167, 126,  61, 100,  93,  25,
+      115,  96, 129,  79, 220,  34,  42, 144, 136,  70, 238, 184,  20,
+      222,  94,  11, 219, 224,  50,  58,  10,  73,   6,  36,  92, 194,
+      211, 172,  98, 145, 149, 228, 121, 231, 200,  55, 109, 141, 213,
+       78, 169, 108,  86, 244, 234, 101, 122, 174,   8, 186, 120,  37,
+       46,  28, 166, 180, 198, 232, 221, 116,  31,  75, 189, 139, 138,
+      112,  62, 181, 102,  72,   3, 246,  14,  97,  53,  87, 185, 134,
+      193,  29, 158, 225, 248, 152,  17, 105, 217, 142, 148, 155,  30,
+      135, 233, 206,  85,  40, 223, 140, 161, 137,  13, 191, 230,  66,
+      104,  65, 153,  45,  15, 176,  84, 187,  22
+  };
+  const SWord32 s260 = s2 ^ s3;
+  const SWord32 s261 = (s260 << 8) | (s260 >> 24);
+  const SWord8  s262 = (SWord8) (s261 >> 24);
+  const SWord8  s263 = table0[s262];
+  const SWord8  s264 = 54 ^ s263;
+  const SWord8  s265 = (SWord8) (s261 >> 16);
+  const SWord8  s266 = table0[s265];
+  const SWord16 s267 = (((SWord16) s264) << 8) | ((SWord16) s266);
+  const SWord8  s268 = (SWord8) (s261 >> 8);
+  const SWord8  s269 = table0[s268];
+  const SWord8  s270 = (SWord8) s261;
+  const SWord8  s271 = table0[s270];
+  const SWord16 s272 = (((SWord16) s269) << 8) | ((SWord16) s271);
+  const SWord32 s273 = (((SWord32) s267) << 16) | ((SWord32) s272);
+  const SWord32 s274 = s0 ^ s273;
+  const SWord32 s275 = s0 ^ s1;
+  const SWord32 s276 = s1 ^ s2;
+  const SWord32 s277 = s260 ^ s276;
+  const SWord32 s278 = (s277 << 8) | (s277 >> 24);
+  const SWord8  s279 = (SWord8) (s278 >> 24);
+  const SWord8  s280 = table0[s279];
+  const SWord8  s281 = 27 ^ s280;
+  const SWord8  s282 = (SWord8) (s278 >> 16);
+  const SWord8  s283 = table0[s282];
+  const SWord16 s284 = (((SWord16) s281) << 8) | ((SWord16) s283);
+  const SWord8  s285 = (SWord8) (s278 >> 8);
+  const SWord8  s286 = table0[s285];
+  const SWord8  s287 = (SWord8) s278;
+  const SWord8  s288 = table0[s287];
+  const SWord16 s289 = (((SWord16) s286) << 8) | ((SWord16) s288);
+  const SWord32 s290 = (((SWord32) s284) << 16) | ((SWord32) s289);
+  const SWord32 s291 = s274 ^ s290;
+  const SWord32 s292 = s274 ^ s275;
+  const SWord32 s293 = s275 ^ s276;
+  const SWord32 s294 = s277 ^ s293;
+  const SWord32 s295 = (s294 << 8) | (s294 >> 24);
+  const SWord8  s296 = (SWord8) (s295 >> 24);
+  const SWord8  s297 = table0[s296];
+  const SWord8  s298 = 128 ^ s297;
+  const SWord8  s299 = (SWord8) (s295 >> 16);
+  const SWord8  s300 = table0[s299];
+  const SWord16 s301 = (((SWord16) s298) << 8) | ((SWord16) s300);
+  const SWord8  s302 = (SWord8) (s295 >> 8);
+  const SWord8  s303 = table0[s302];
+  const SWord8  s304 = (SWord8) s295;
+  const SWord8  s305 = table0[s304];
+  const SWord16 s306 = (((SWord16) s303) << 8) | ((SWord16) s305);
+  const SWord32 s307 = (((SWord32) s301) << 16) | ((SWord32) s306);
+  const SWord32 s308 = s291 ^ s307;
+  const SWord32 s309 = s291 ^ s292;
+  const SWord32 s310 = s292 ^ s293;
+  const SWord32 s311 = s294 ^ s310;
+  const SWord32 s312 = (s311 << 8) | (s311 >> 24);
+  const SWord8  s313 = (SWord8) (s312 >> 24);
+  const SWord8  s314 = table0[s313];
+  const SWord8  s315 = 64 ^ s314;
+  const SWord8  s316 = (SWord8) (s312 >> 16);
+  const SWord8  s317 = table0[s316];
+  const SWord16 s318 = (((SWord16) s315) << 8) | ((SWord16) s317);
+  const SWord8  s319 = (SWord8) (s312 >> 8);
+  const SWord8  s320 = table0[s319];
+  const SWord8  s321 = (SWord8) s312;
+  const SWord8  s322 = table0[s321];
+  const SWord16 s323 = (((SWord16) s320) << 8) | ((SWord16) s322);
+  const SWord32 s324 = (((SWord32) s318) << 16) | ((SWord32) s323);
+  const SWord32 s325 = s308 ^ s324;
+  const SWord32 s326 = s308 ^ s309;
+  const SWord32 s327 = s309 ^ s310;
+  const SWord32 s328 = s311 ^ s327;
+  const SWord32 s329 = (s328 << 8) | (s328 >> 24);
+  const SWord8  s330 = (SWord8) (s329 >> 24);
+  const SWord8  s331 = table0[s330];
+  const SWord8  s332 = 32 ^ s331;
+  const SWord8  s333 = (SWord8) (s329 >> 16);
+  const SWord8  s334 = table0[s333];
+  const SWord16 s335 = (((SWord16) s332) << 8) | ((SWord16) s334);
+  const SWord8  s336 = (SWord8) (s329 >> 8);
+  const SWord8  s337 = table0[s336];
+  const SWord8  s338 = (SWord8) s329;
+  const SWord8  s339 = table0[s338];
+  const SWord16 s340 = (((SWord16) s337) << 8) | ((SWord16) s339);
+  const SWord32 s341 = (((SWord32) s335) << 16) | ((SWord32) s340);
+  const SWord32 s342 = s325 ^ s341;
+  const SWord32 s343 = s325 ^ s326;
+  const SWord32 s344 = s326 ^ s327;
+  const SWord32 s345 = s328 ^ s344;
+  const SWord32 s346 = (s345 << 8) | (s345 >> 24);
+  const SWord8  s347 = (SWord8) (s346 >> 24);
+  const SWord8  s348 = table0[s347];
+  const SWord8  s349 = 16 ^ s348;
+  const SWord8  s350 = (SWord8) (s346 >> 16);
+  const SWord8  s351 = table0[s350];
+  const SWord16 s352 = (((SWord16) s349) << 8) | ((SWord16) s351);
+  const SWord8  s353 = (SWord8) (s346 >> 8);
+  const SWord8  s354 = table0[s353];
+  const SWord8  s355 = (SWord8) s346;
+  const SWord8  s356 = table0[s355];
+  const SWord16 s357 = (((SWord16) s354) << 8) | ((SWord16) s356);
+  const SWord32 s358 = (((SWord32) s352) << 16) | ((SWord32) s357);
+  const SWord32 s359 = s342 ^ s358;
+  const SWord32 s360 = s342 ^ s343;
+  const SWord32 s361 = s343 ^ s344;
+  const SWord32 s362 = s345 ^ s361;
+  const SWord32 s363 = (s362 << 8) | (s362 >> 24);
+  const SWord8  s364 = (SWord8) (s363 >> 24);
+  const SWord8  s365 = table0[s364];
+  const SWord8  s366 = 8 ^ s365;
+  const SWord8  s367 = (SWord8) (s363 >> 16);
+  const SWord8  s368 = table0[s367];
+  const SWord16 s369 = (((SWord16) s366) << 8) | ((SWord16) s368);
+  const SWord8  s370 = (SWord8) (s363 >> 8);
+  const SWord8  s371 = table0[s370];
+  const SWord8  s372 = (SWord8) s363;
+  const SWord8  s373 = table0[s372];
+  const SWord16 s374 = (((SWord16) s371) << 8) | ((SWord16) s373);
+  const SWord32 s375 = (((SWord32) s369) << 16) | ((SWord32) s374);
+  const SWord32 s376 = s359 ^ s375;
+  const SWord32 s377 = s359 ^ s360;
+  const SWord32 s378 = s360 ^ s361;
+  const SWord32 s379 = s362 ^ s378;
+  const SWord32 s380 = (s379 << 8) | (s379 >> 24);
+  const SWord8  s381 = (SWord8) (s380 >> 24);
+  const SWord8  s382 = table0[s381];
+  const SWord8  s383 = 4 ^ s382;
+  const SWord8  s384 = (SWord8) (s380 >> 16);
+  const SWord8  s385 = table0[s384];
+  const SWord16 s386 = (((SWord16) s383) << 8) | ((SWord16) s385);
+  const SWord8  s387 = (SWord8) (s380 >> 8);
+  const SWord8  s388 = table0[s387];
+  const SWord8  s389 = (SWord8) s380;
+  const SWord8  s390 = table0[s389];
+  const SWord16 s391 = (((SWord16) s388) << 8) | ((SWord16) s390);
+  const SWord32 s392 = (((SWord32) s386) << 16) | ((SWord32) s391);
+  const SWord32 s393 = s376 ^ s392;
+  const SWord32 s394 = s376 ^ s377;
+  const SWord32 s395 = s377 ^ s378;
+  const SWord32 s396 = s379 ^ s395;
+  const SWord32 s397 = (s396 << 8) | (s396 >> 24);
+  const SWord8  s398 = (SWord8) (s397 >> 24);
+  const SWord8  s399 = table0[s398];
+  const SWord8  s400 = 2 ^ s399;
+  const SWord8  s401 = (SWord8) (s397 >> 16);
+  const SWord8  s402 = table0[s401];
+  const SWord16 s403 = (((SWord16) s400) << 8) | ((SWord16) s402);
+  const SWord8  s404 = (SWord8) (s397 >> 8);
+  const SWord8  s405 = table0[s404];
+  const SWord8  s406 = (SWord8) s397;
+  const SWord8  s407 = table0[s406];
+  const SWord16 s408 = (((SWord16) s405) << 8) | ((SWord16) s407);
+  const SWord32 s409 = (((SWord32) s403) << 16) | ((SWord32) s408);
+  const SWord32 s410 = s393 ^ s409;
+  const SWord32 s411 = s393 ^ s394;
+  const SWord32 s412 = s394 ^ s395;
+  const SWord32 s413 = s396 ^ s412;
+  const SWord32 s414 = (s413 << 8) | (s413 >> 24);
+  const SWord8  s415 = (SWord8) (s414 >> 24);
+  const SWord8  s416 = table0[s415];
+  const SWord8  s417 = 1 ^ s416;
+  const SWord8  s418 = (SWord8) (s414 >> 16);
+  const SWord8  s419 = table0[s418];
+  const SWord16 s420 = (((SWord16) s417) << 8) | ((SWord16) s419);
+  const SWord8  s421 = (SWord8) (s414 >> 8);
+  const SWord8  s422 = table0[s421];
+  const SWord8  s423 = (SWord8) s414;
+  const SWord8  s424 = table0[s423];
+  const SWord16 s425 = (((SWord16) s422) << 8) | ((SWord16) s424);
+  const SWord32 s426 = (((SWord32) s420) << 16) | ((SWord32) s425);
+  const SWord32 s427 = s410 ^ s426;
+  const SWord32 s428 = s410 ^ s411;
+  const SWord32 s429 = s411 ^ s412;
+
+  decKS[0] = s0;
+  decKS[1] = s1;
+  decKS[2] = s2;
+  decKS[3] = s3;
+  decKS[4] = s274;
+  decKS[5] = s275;
+  decKS[6] = s276;
+  decKS[7] = s260;
+  decKS[8] = s291;
+  decKS[9] = s292;
+  decKS[10] = s293;
+  decKS[11] = s277;
+  decKS[12] = s308;
+  decKS[13] = s309;
+  decKS[14] = s310;
+  decKS[15] = s294;
+  decKS[16] = s325;
+  decKS[17] = s326;
+  decKS[18] = s327;
+  decKS[19] = s311;
+  decKS[20] = s342;
+  decKS[21] = s343;
+  decKS[22] = s344;
+  decKS[23] = s328;
+  decKS[24] = s359;
+  decKS[25] = s360;
+  decKS[26] = s361;
+  decKS[27] = s345;
+  decKS[28] = s376;
+  decKS[29] = s377;
+  decKS[30] = s378;
+  decKS[31] = s362;
+  decKS[32] = s393;
+  decKS[33] = s394;
+  decKS[34] = s395;
+  decKS[35] = s379;
+  decKS[36] = s410;
+  decKS[37] = s411;
+  decKS[38] = s412;
+  decKS[39] = s396;
+  decKS[40] = s427;
+  decKS[41] = s428;
+  decKS[42] = s429;
+  decKS[43] = s413;
+}
+== END: "aes128InvKeySchedule.c" ==================
+== BEGIN: "aes128OTFDecrypt.c" ================
+/* File: "aes128OTFDecrypt.c". Automatically generated by SBV. Do not edit! */
+
+#include "aes128Lib.h"
+
+void aes128OTFDecrypt(const SWord32 *ct, const SWord32 *xkey,
+                      SWord32 *pt)
+{
+  const SWord32 s0 = ct[0];
+  const SWord32 s1 = ct[1];
+  const SWord32 s2 = ct[2];
+  const SWord32 s3 = ct[3];
+  const SWord32 s4 = xkey[0];
+  const SWord32 s5 = xkey[1];
+  const SWord32 s6 = xkey[2];
+  const SWord32 s7 = xkey[3];
+  const SWord32 s8 = xkey[4];
+  const SWord32 s9 = xkey[5];
+  const SWord32 s10 = xkey[6];
+  const SWord32 s11 = xkey[7];
+  const SWord32 s12 = xkey[8];
+  const SWord32 s13 = xkey[9];
+  const SWord32 s14 = xkey[10];
+  const SWord32 s15 = xkey[11];
+  const SWord32 s16 = xkey[12];
+  const SWord32 s17 = xkey[13];
+  const SWord32 s18 = xkey[14];
+  const SWord32 s19 = xkey[15];
+  const SWord32 s20 = xkey[16];
+  const SWord32 s21 = xkey[17];
+  const SWord32 s22 = xkey[18];
+  const SWord32 s23 = xkey[19];
+  const SWord32 s24 = xkey[20];
+  const SWord32 s25 = xkey[21];
+  const SWord32 s26 = xkey[22];
+  const SWord32 s27 = xkey[23];
+  const SWord32 s28 = xkey[24];
+  const SWord32 s29 = xkey[25];
+  const SWord32 s30 = xkey[26];
+  const SWord32 s31 = xkey[27];
+  const SWord32 s32 = xkey[28];
+  const SWord32 s33 = xkey[29];
+  const SWord32 s34 = xkey[30];
+  const SWord32 s35 = xkey[31];
+  const SWord32 s36 = xkey[32];
+  const SWord32 s37 = xkey[33];
+  const SWord32 s38 = xkey[34];
+  const SWord32 s39 = xkey[35];
+  const SWord32 s40 = xkey[36];
+  const SWord32 s41 = xkey[37];
+  const SWord32 s42 = xkey[38];
+  const SWord32 s43 = xkey[39];
+  const SWord32 s44 = xkey[40];
+  const SWord32 s45 = xkey[41];
+  const SWord32 s46 = xkey[42];
+  const SWord32 s47 = xkey[43];
+  static const SWord8 table0[] = {
+       82,   9, 106, 213,  48,  54, 165,  56, 191,  64, 163, 158, 129,
+      243, 215, 251, 124, 227,  57, 130, 155,  47, 255, 135,  52, 142,
+       67,  68, 196, 222, 233, 203,  84, 123, 148,  50, 166, 194,  35,
+       61, 238,  76, 149,  11,  66, 250, 195,  78,   8,  46, 161, 102,
+       40, 217,  36, 178, 118,  91, 162,  73, 109, 139, 209,  37, 114,
+      248, 246, 100, 134, 104, 152,  22, 212, 164,  92, 204,  93, 101,
+      182, 146, 108, 112,  72,  80, 253, 237, 185, 218,  94,  21,  70,
+       87, 167, 141, 157, 132, 144, 216, 171,   0, 140, 188, 211,  10,
+      247, 228,  88,   5, 184, 179,  69,   6, 208,  44,  30, 143, 202,
+       63,  15,   2, 193, 175, 189,   3,   1,  19, 138, 107,  58, 145,
+       17,  65,  79, 103, 220, 234, 151, 242, 207, 206, 240, 180, 230,
+      115, 150, 172, 116,  34, 231, 173,  53, 133, 226, 249,  55, 232,
+       28, 117, 223, 110,  71, 241,  26, 113,  29,  41, 197, 137, 111,
+      183,  98,  14, 170,  24, 190,  27, 252,  86,  62,  75, 198, 210,
+      121,  32, 154, 219, 192, 254, 120, 205,  90, 244,  31, 221, 168,
+       51, 136,   7, 199,  49, 177,  18,  16,  89,  39, 128, 236,  95,
+       96,  81, 127, 169,  25, 181,  74,  13,  45, 229, 122, 159, 147,
+      201, 156, 239, 160, 224,  59,  77, 174,  42, 245, 176, 200, 235,
+      187,  60, 131,  83, 153,  97,  23,  43,   4, 126, 186, 119, 214,
+       38, 225, 105,  20,  99,  85,  33,  12, 125
+  };
+  static const SWord32 table1[] = {
+      0x00000000UL, 0x0e090d0bUL, 0x1c121a16UL, 0x121b171dUL,
+      0x3824342cUL, 0x362d3927UL, 0x24362e3aUL, 0x2a3f2331UL,
+      0x70486858UL, 0x7e416553UL, 0x6c5a724eUL, 0x62537f45UL,
+      0x486c5c74UL, 0x4665517fUL, 0x547e4662UL, 0x5a774b69UL,
+      0xe090d0b0UL, 0xee99ddbbUL, 0xfc82caa6UL, 0xf28bc7adUL,
+      0xd8b4e49cUL, 0xd6bde997UL, 0xc4a6fe8aUL, 0xcaaff381UL,
+      0x90d8b8e8UL, 0x9ed1b5e3UL, 0x8ccaa2feUL, 0x82c3aff5UL,
+      0xa8fc8cc4UL, 0xa6f581cfUL, 0xb4ee96d2UL, 0xbae79bd9UL,
+      0xdb3bbb7bUL, 0xd532b670UL, 0xc729a16dUL, 0xc920ac66UL,
+      0xe31f8f57UL, 0xed16825cUL, 0xff0d9541UL, 0xf104984aUL,
+      0xab73d323UL, 0xa57ade28UL, 0xb761c935UL, 0xb968c43eUL,
+      0x9357e70fUL, 0x9d5eea04UL, 0x8f45fd19UL, 0x814cf012UL,
+      0x3bab6bcbUL, 0x35a266c0UL, 0x27b971ddUL, 0x29b07cd6UL,
+      0x038f5fe7UL, 0x0d8652ecUL, 0x1f9d45f1UL, 0x119448faUL,
+      0x4be30393UL, 0x45ea0e98UL, 0x57f11985UL, 0x59f8148eUL,
+      0x73c737bfUL, 0x7dce3ab4UL, 0x6fd52da9UL, 0x61dc20a2UL,
+      0xad766df6UL, 0xa37f60fdUL, 0xb16477e0UL, 0xbf6d7aebUL,
+      0x955259daUL, 0x9b5b54d1UL, 0x894043ccUL, 0x87494ec7UL,
+      0xdd3e05aeUL, 0xd33708a5UL, 0xc12c1fb8UL, 0xcf2512b3UL,
+      0xe51a3182UL, 0xeb133c89UL, 0xf9082b94UL, 0xf701269fUL,
+      0x4de6bd46UL, 0x43efb04dUL, 0x51f4a750UL, 0x5ffdaa5bUL,
+      0x75c2896aUL, 0x7bcb8461UL, 0x69d0937cUL, 0x67d99e77UL,
+      0x3daed51eUL, 0x33a7d815UL, 0x21bccf08UL, 0x2fb5c203UL,
+      0x058ae132UL, 0x0b83ec39UL, 0x1998fb24UL, 0x1791f62fUL,
+      0x764dd68dUL, 0x7844db86UL, 0x6a5fcc9bUL, 0x6456c190UL,
+      0x4e69e2a1UL, 0x4060efaaUL, 0x527bf8b7UL, 0x5c72f5bcUL,
+      0x0605bed5UL, 0x080cb3deUL, 0x1a17a4c3UL, 0x141ea9c8UL,
+      0x3e218af9UL, 0x302887f2UL, 0x223390efUL, 0x2c3a9de4UL,
+      0x96dd063dUL, 0x98d40b36UL, 0x8acf1c2bUL, 0x84c61120UL,
+      0xaef93211UL, 0xa0f03f1aUL, 0xb2eb2807UL, 0xbce2250cUL,
+      0xe6956e65UL, 0xe89c636eUL, 0xfa877473UL, 0xf48e7978UL,
+      0xdeb15a49UL, 0xd0b85742UL, 0xc2a3405fUL, 0xccaa4d54UL,
+      0x41ecdaf7UL, 0x4fe5d7fcUL, 0x5dfec0e1UL, 0x53f7cdeaUL,
+      0x79c8eedbUL, 0x77c1e3d0UL, 0x65daf4cdUL, 0x6bd3f9c6UL,
+      0x31a4b2afUL, 0x3fadbfa4UL, 0x2db6a8b9UL, 0x23bfa5b2UL,
+      0x09808683UL, 0x07898b88UL, 0x15929c95UL, 0x1b9b919eUL,
+      0xa17c0a47UL, 0xaf75074cUL, 0xbd6e1051UL, 0xb3671d5aUL,
+      0x99583e6bUL, 0x97513360UL, 0x854a247dUL, 0x8b432976UL,
+      0xd134621fUL, 0xdf3d6f14UL, 0xcd267809UL, 0xc32f7502UL,
+      0xe9105633UL, 0xe7195b38UL, 0xf5024c25UL, 0xfb0b412eUL,
+      0x9ad7618cUL, 0x94de6c87UL, 0x86c57b9aUL, 0x88cc7691UL,
+      0xa2f355a0UL, 0xacfa58abUL, 0xbee14fb6UL, 0xb0e842bdUL,
+      0xea9f09d4UL, 0xe49604dfUL, 0xf68d13c2UL, 0xf8841ec9UL,
+      0xd2bb3df8UL, 0xdcb230f3UL, 0xcea927eeUL, 0xc0a02ae5UL,
+      0x7a47b13cUL, 0x744ebc37UL, 0x6655ab2aUL, 0x685ca621UL,
+      0x42638510UL, 0x4c6a881bUL, 0x5e719f06UL, 0x5078920dUL,
+      0x0a0fd964UL, 0x0406d46fUL, 0x161dc372UL, 0x1814ce79UL,
+      0x322bed48UL, 0x3c22e043UL, 0x2e39f75eUL, 0x2030fa55UL,
+      0xec9ab701UL, 0xe293ba0aUL, 0xf088ad17UL, 0xfe81a01cUL,
+      0xd4be832dUL, 0xdab78e26UL, 0xc8ac993bUL, 0xc6a59430UL,
+      0x9cd2df59UL, 0x92dbd252UL, 0x80c0c54fUL, 0x8ec9c844UL,
+      0xa4f6eb75UL, 0xaaffe67eUL, 0xb8e4f163UL, 0xb6edfc68UL,
+      0x0c0a67b1UL, 0x02036abaUL, 0x10187da7UL, 0x1e1170acUL,
+      0x342e539dUL, 0x3a275e96UL, 0x283c498bUL, 0x26354480UL,
+      0x7c420fe9UL, 0x724b02e2UL, 0x605015ffUL, 0x6e5918f4UL,
+      0x44663bc5UL, 0x4a6f36ceUL, 0x587421d3UL, 0x567d2cd8UL,
+      0x37a10c7aUL, 0x39a80171UL, 0x2bb3166cUL, 0x25ba1b67UL,
+      0x0f853856UL, 0x018c355dUL, 0x13972240UL, 0x1d9e2f4bUL,
+      0x47e96422UL, 0x49e06929UL, 0x5bfb7e34UL, 0x55f2733fUL,
+      0x7fcd500eUL, 0x71c45d05UL, 0x63df4a18UL, 0x6dd64713UL,
+      0xd731dccaUL, 0xd938d1c1UL, 0xcb23c6dcUL, 0xc52acbd7UL,
+      0xef15e8e6UL, 0xe11ce5edUL, 0xf307f2f0UL, 0xfd0efffbUL,
+      0xa779b492UL, 0xa970b999UL, 0xbb6bae84UL, 0xb562a38fUL,
+      0x9f5d80beUL, 0x91548db5UL, 0x834f9aa8UL, 0x8d4697a3UL
+  };
+  static const SWord32 table2[] = {
+      0x00000000UL, 0x0b0e090dUL, 0x161c121aUL, 0x1d121b17UL,
+      0x2c382434UL, 0x27362d39UL, 0x3a24362eUL, 0x312a3f23UL,
+      0x58704868UL, 0x537e4165UL, 0x4e6c5a72UL, 0x4562537fUL,
+      0x74486c5cUL, 0x7f466551UL, 0x62547e46UL, 0x695a774bUL,
+      0xb0e090d0UL, 0xbbee99ddUL, 0xa6fc82caUL, 0xadf28bc7UL,
+      0x9cd8b4e4UL, 0x97d6bde9UL, 0x8ac4a6feUL, 0x81caaff3UL,
+      0xe890d8b8UL, 0xe39ed1b5UL, 0xfe8ccaa2UL, 0xf582c3afUL,
+      0xc4a8fc8cUL, 0xcfa6f581UL, 0xd2b4ee96UL, 0xd9bae79bUL,
+      0x7bdb3bbbUL, 0x70d532b6UL, 0x6dc729a1UL, 0x66c920acUL,
+      0x57e31f8fUL, 0x5ced1682UL, 0x41ff0d95UL, 0x4af10498UL,
+      0x23ab73d3UL, 0x28a57adeUL, 0x35b761c9UL, 0x3eb968c4UL,
+      0x0f9357e7UL, 0x049d5eeaUL, 0x198f45fdUL, 0x12814cf0UL,
+      0xcb3bab6bUL, 0xc035a266UL, 0xdd27b971UL, 0xd629b07cUL,
+      0xe7038f5fUL, 0xec0d8652UL, 0xf11f9d45UL, 0xfa119448UL,
+      0x934be303UL, 0x9845ea0eUL, 0x8557f119UL, 0x8e59f814UL,
+      0xbf73c737UL, 0xb47dce3aUL, 0xa96fd52dUL, 0xa261dc20UL,
+      0xf6ad766dUL, 0xfda37f60UL, 0xe0b16477UL, 0xebbf6d7aUL,
+      0xda955259UL, 0xd19b5b54UL, 0xcc894043UL, 0xc787494eUL,
+      0xaedd3e05UL, 0xa5d33708UL, 0xb8c12c1fUL, 0xb3cf2512UL,
+      0x82e51a31UL, 0x89eb133cUL, 0x94f9082bUL, 0x9ff70126UL,
+      0x464de6bdUL, 0x4d43efb0UL, 0x5051f4a7UL, 0x5b5ffdaaUL,
+      0x6a75c289UL, 0x617bcb84UL, 0x7c69d093UL, 0x7767d99eUL,
+      0x1e3daed5UL, 0x1533a7d8UL, 0x0821bccfUL, 0x032fb5c2UL,
+      0x32058ae1UL, 0x390b83ecUL, 0x241998fbUL, 0x2f1791f6UL,
+      0x8d764dd6UL, 0x867844dbUL, 0x9b6a5fccUL, 0x906456c1UL,
+      0xa14e69e2UL, 0xaa4060efUL, 0xb7527bf8UL, 0xbc5c72f5UL,
+      0xd50605beUL, 0xde080cb3UL, 0xc31a17a4UL, 0xc8141ea9UL,
+      0xf93e218aUL, 0xf2302887UL, 0xef223390UL, 0xe42c3a9dUL,
+      0x3d96dd06UL, 0x3698d40bUL, 0x2b8acf1cUL, 0x2084c611UL,
+      0x11aef932UL, 0x1aa0f03fUL, 0x07b2eb28UL, 0x0cbce225UL,
+      0x65e6956eUL, 0x6ee89c63UL, 0x73fa8774UL, 0x78f48e79UL,
+      0x49deb15aUL, 0x42d0b857UL, 0x5fc2a340UL, 0x54ccaa4dUL,
+      0xf741ecdaUL, 0xfc4fe5d7UL, 0xe15dfec0UL, 0xea53f7cdUL,
+      0xdb79c8eeUL, 0xd077c1e3UL, 0xcd65daf4UL, 0xc66bd3f9UL,
+      0xaf31a4b2UL, 0xa43fadbfUL, 0xb92db6a8UL, 0xb223bfa5UL,
+      0x83098086UL, 0x8807898bUL, 0x9515929cUL, 0x9e1b9b91UL,
+      0x47a17c0aUL, 0x4caf7507UL, 0x51bd6e10UL, 0x5ab3671dUL,
+      0x6b99583eUL, 0x60975133UL, 0x7d854a24UL, 0x768b4329UL,
+      0x1fd13462UL, 0x14df3d6fUL, 0x09cd2678UL, 0x02c32f75UL,
+      0x33e91056UL, 0x38e7195bUL, 0x25f5024cUL, 0x2efb0b41UL,
+      0x8c9ad761UL, 0x8794de6cUL, 0x9a86c57bUL, 0x9188cc76UL,
+      0xa0a2f355UL, 0xabacfa58UL, 0xb6bee14fUL, 0xbdb0e842UL,
+      0xd4ea9f09UL, 0xdfe49604UL, 0xc2f68d13UL, 0xc9f8841eUL,
+      0xf8d2bb3dUL, 0xf3dcb230UL, 0xeecea927UL, 0xe5c0a02aUL,
+      0x3c7a47b1UL, 0x37744ebcUL, 0x2a6655abUL, 0x21685ca6UL,
+      0x10426385UL, 0x1b4c6a88UL, 0x065e719fUL, 0x0d507892UL,
+      0x640a0fd9UL, 0x6f0406d4UL, 0x72161dc3UL, 0x791814ceUL,
+      0x48322bedUL, 0x433c22e0UL, 0x5e2e39f7UL, 0x552030faUL,
+      0x01ec9ab7UL, 0x0ae293baUL, 0x17f088adUL, 0x1cfe81a0UL,
+      0x2dd4be83UL, 0x26dab78eUL, 0x3bc8ac99UL, 0x30c6a594UL,
+      0x599cd2dfUL, 0x5292dbd2UL, 0x4f80c0c5UL, 0x448ec9c8UL,
+      0x75a4f6ebUL, 0x7eaaffe6UL, 0x63b8e4f1UL, 0x68b6edfcUL,
+      0xb10c0a67UL, 0xba02036aUL, 0xa710187dUL, 0xac1e1170UL,
+      0x9d342e53UL, 0x963a275eUL, 0x8b283c49UL, 0x80263544UL,
+      0xe97c420fUL, 0xe2724b02UL, 0xff605015UL, 0xf46e5918UL,
+      0xc544663bUL, 0xce4a6f36UL, 0xd3587421UL, 0xd8567d2cUL,
+      0x7a37a10cUL, 0x7139a801UL, 0x6c2bb316UL, 0x6725ba1bUL,
+      0x560f8538UL, 0x5d018c35UL, 0x40139722UL, 0x4b1d9e2fUL,
+      0x2247e964UL, 0x2949e069UL, 0x345bfb7eUL, 0x3f55f273UL,
+      0x0e7fcd50UL, 0x0571c45dUL, 0x1863df4aUL, 0x136dd647UL,
+      0xcad731dcUL, 0xc1d938d1UL, 0xdccb23c6UL, 0xd7c52acbUL,
+      0xe6ef15e8UL, 0xede11ce5UL, 0xf0f307f2UL, 0xfbfd0effUL,
+      0x92a779b4UL, 0x99a970b9UL, 0x84bb6baeUL, 0x8fb562a3UL,
+      0xbe9f5d80UL, 0xb591548dUL, 0xa8834f9aUL, 0xa38d4697UL
+  };
+  static const SWord32 table3[] = {
+      0x00000000UL, 0x0d0b0e09UL, 0x1a161c12UL, 0x171d121bUL,
+      0x342c3824UL, 0x3927362dUL, 0x2e3a2436UL, 0x23312a3fUL,
+      0x68587048UL, 0x65537e41UL, 0x724e6c5aUL, 0x7f456253UL,
+      0x5c74486cUL, 0x517f4665UL, 0x4662547eUL, 0x4b695a77UL,
+      0xd0b0e090UL, 0xddbbee99UL, 0xcaa6fc82UL, 0xc7adf28bUL,
+      0xe49cd8b4UL, 0xe997d6bdUL, 0xfe8ac4a6UL, 0xf381caafUL,
+      0xb8e890d8UL, 0xb5e39ed1UL, 0xa2fe8ccaUL, 0xaff582c3UL,
+      0x8cc4a8fcUL, 0x81cfa6f5UL, 0x96d2b4eeUL, 0x9bd9bae7UL,
+      0xbb7bdb3bUL, 0xb670d532UL, 0xa16dc729UL, 0xac66c920UL,
+      0x8f57e31fUL, 0x825ced16UL, 0x9541ff0dUL, 0x984af104UL,
+      0xd323ab73UL, 0xde28a57aUL, 0xc935b761UL, 0xc43eb968UL,
+      0xe70f9357UL, 0xea049d5eUL, 0xfd198f45UL, 0xf012814cUL,
+      0x6bcb3babUL, 0x66c035a2UL, 0x71dd27b9UL, 0x7cd629b0UL,
+      0x5fe7038fUL, 0x52ec0d86UL, 0x45f11f9dUL, 0x48fa1194UL,
+      0x03934be3UL, 0x0e9845eaUL, 0x198557f1UL, 0x148e59f8UL,
+      0x37bf73c7UL, 0x3ab47dceUL, 0x2da96fd5UL, 0x20a261dcUL,
+      0x6df6ad76UL, 0x60fda37fUL, 0x77e0b164UL, 0x7aebbf6dUL,
+      0x59da9552UL, 0x54d19b5bUL, 0x43cc8940UL, 0x4ec78749UL,
+      0x05aedd3eUL, 0x08a5d337UL, 0x1fb8c12cUL, 0x12b3cf25UL,
+      0x3182e51aUL, 0x3c89eb13UL, 0x2b94f908UL, 0x269ff701UL,
+      0xbd464de6UL, 0xb04d43efUL, 0xa75051f4UL, 0xaa5b5ffdUL,
+      0x896a75c2UL, 0x84617bcbUL, 0x937c69d0UL, 0x9e7767d9UL,
+      0xd51e3daeUL, 0xd81533a7UL, 0xcf0821bcUL, 0xc2032fb5UL,
+      0xe132058aUL, 0xec390b83UL, 0xfb241998UL, 0xf62f1791UL,
+      0xd68d764dUL, 0xdb867844UL, 0xcc9b6a5fUL, 0xc1906456UL,
+      0xe2a14e69UL, 0xefaa4060UL, 0xf8b7527bUL, 0xf5bc5c72UL,
+      0xbed50605UL, 0xb3de080cUL, 0xa4c31a17UL, 0xa9c8141eUL,
+      0x8af93e21UL, 0x87f23028UL, 0x90ef2233UL, 0x9de42c3aUL,
+      0x063d96ddUL, 0x0b3698d4UL, 0x1c2b8acfUL, 0x112084c6UL,
+      0x3211aef9UL, 0x3f1aa0f0UL, 0x2807b2ebUL, 0x250cbce2UL,
+      0x6e65e695UL, 0x636ee89cUL, 0x7473fa87UL, 0x7978f48eUL,
+      0x5a49deb1UL, 0x5742d0b8UL, 0x405fc2a3UL, 0x4d54ccaaUL,
+      0xdaf741ecUL, 0xd7fc4fe5UL, 0xc0e15dfeUL, 0xcdea53f7UL,
+      0xeedb79c8UL, 0xe3d077c1UL, 0xf4cd65daUL, 0xf9c66bd3UL,
+      0xb2af31a4UL, 0xbfa43fadUL, 0xa8b92db6UL, 0xa5b223bfUL,
+      0x86830980UL, 0x8b880789UL, 0x9c951592UL, 0x919e1b9bUL,
+      0x0a47a17cUL, 0x074caf75UL, 0x1051bd6eUL, 0x1d5ab367UL,
+      0x3e6b9958UL, 0x33609751UL, 0x247d854aUL, 0x29768b43UL,
+      0x621fd134UL, 0x6f14df3dUL, 0x7809cd26UL, 0x7502c32fUL,
+      0x5633e910UL, 0x5b38e719UL, 0x4c25f502UL, 0x412efb0bUL,
+      0x618c9ad7UL, 0x6c8794deUL, 0x7b9a86c5UL, 0x769188ccUL,
+      0x55a0a2f3UL, 0x58abacfaUL, 0x4fb6bee1UL, 0x42bdb0e8UL,
+      0x09d4ea9fUL, 0x04dfe496UL, 0x13c2f68dUL, 0x1ec9f884UL,
+      0x3df8d2bbUL, 0x30f3dcb2UL, 0x27eecea9UL, 0x2ae5c0a0UL,
+      0xb13c7a47UL, 0xbc37744eUL, 0xab2a6655UL, 0xa621685cUL,
+      0x85104263UL, 0x881b4c6aUL, 0x9f065e71UL, 0x920d5078UL,
+      0xd9640a0fUL, 0xd46f0406UL, 0xc372161dUL, 0xce791814UL,
+      0xed48322bUL, 0xe0433c22UL, 0xf75e2e39UL, 0xfa552030UL,
+      0xb701ec9aUL, 0xba0ae293UL, 0xad17f088UL, 0xa01cfe81UL,
+      0x832dd4beUL, 0x8e26dab7UL, 0x993bc8acUL, 0x9430c6a5UL,
+      0xdf599cd2UL, 0xd25292dbUL, 0xc54f80c0UL, 0xc8448ec9UL,
+      0xeb75a4f6UL, 0xe67eaaffUL, 0xf163b8e4UL, 0xfc68b6edUL,
+      0x67b10c0aUL, 0x6aba0203UL, 0x7da71018UL, 0x70ac1e11UL,
+      0x539d342eUL, 0x5e963a27UL, 0x498b283cUL, 0x44802635UL,
+      0x0fe97c42UL, 0x02e2724bUL, 0x15ff6050UL, 0x18f46e59UL,
+      0x3bc54466UL, 0x36ce4a6fUL, 0x21d35874UL, 0x2cd8567dUL,
+      0x0c7a37a1UL, 0x017139a8UL, 0x166c2bb3UL, 0x1b6725baUL,
+      0x38560f85UL, 0x355d018cUL, 0x22401397UL, 0x2f4b1d9eUL,
+      0x642247e9UL, 0x692949e0UL, 0x7e345bfbUL, 0x733f55f2UL,
+      0x500e7fcdUL, 0x5d0571c4UL, 0x4a1863dfUL, 0x47136dd6UL,
+      0xdccad731UL, 0xd1c1d938UL, 0xc6dccb23UL, 0xcbd7c52aUL,
+      0xe8e6ef15UL, 0xe5ede11cUL, 0xf2f0f307UL, 0xfffbfd0eUL,
+      0xb492a779UL, 0xb999a970UL, 0xae84bb6bUL, 0xa38fb562UL,
+      0x80be9f5dUL, 0x8db59154UL, 0x9aa8834fUL, 0x97a38d46UL
+  };
+  static const SWord32 table4[] = {
+      0x00000000UL, 0x090d0b0eUL, 0x121a161cUL, 0x1b171d12UL,
+      0x24342c38UL, 0x2d392736UL, 0x362e3a24UL, 0x3f23312aUL,
+      0x48685870UL, 0x4165537eUL, 0x5a724e6cUL, 0x537f4562UL,
+      0x6c5c7448UL, 0x65517f46UL, 0x7e466254UL, 0x774b695aUL,
+      0x90d0b0e0UL, 0x99ddbbeeUL, 0x82caa6fcUL, 0x8bc7adf2UL,
+      0xb4e49cd8UL, 0xbde997d6UL, 0xa6fe8ac4UL, 0xaff381caUL,
+      0xd8b8e890UL, 0xd1b5e39eUL, 0xcaa2fe8cUL, 0xc3aff582UL,
+      0xfc8cc4a8UL, 0xf581cfa6UL, 0xee96d2b4UL, 0xe79bd9baUL,
+      0x3bbb7bdbUL, 0x32b670d5UL, 0x29a16dc7UL, 0x20ac66c9UL,
+      0x1f8f57e3UL, 0x16825cedUL, 0x0d9541ffUL, 0x04984af1UL,
+      0x73d323abUL, 0x7ade28a5UL, 0x61c935b7UL, 0x68c43eb9UL,
+      0x57e70f93UL, 0x5eea049dUL, 0x45fd198fUL, 0x4cf01281UL,
+      0xab6bcb3bUL, 0xa266c035UL, 0xb971dd27UL, 0xb07cd629UL,
+      0x8f5fe703UL, 0x8652ec0dUL, 0x9d45f11fUL, 0x9448fa11UL,
+      0xe303934bUL, 0xea0e9845UL, 0xf1198557UL, 0xf8148e59UL,
+      0xc737bf73UL, 0xce3ab47dUL, 0xd52da96fUL, 0xdc20a261UL,
+      0x766df6adUL, 0x7f60fda3UL, 0x6477e0b1UL, 0x6d7aebbfUL,
+      0x5259da95UL, 0x5b54d19bUL, 0x4043cc89UL, 0x494ec787UL,
+      0x3e05aeddUL, 0x3708a5d3UL, 0x2c1fb8c1UL, 0x2512b3cfUL,
+      0x1a3182e5UL, 0x133c89ebUL, 0x082b94f9UL, 0x01269ff7UL,
+      0xe6bd464dUL, 0xefb04d43UL, 0xf4a75051UL, 0xfdaa5b5fUL,
+      0xc2896a75UL, 0xcb84617bUL, 0xd0937c69UL, 0xd99e7767UL,
+      0xaed51e3dUL, 0xa7d81533UL, 0xbccf0821UL, 0xb5c2032fUL,
+      0x8ae13205UL, 0x83ec390bUL, 0x98fb2419UL, 0x91f62f17UL,
+      0x4dd68d76UL, 0x44db8678UL, 0x5fcc9b6aUL, 0x56c19064UL,
+      0x69e2a14eUL, 0x60efaa40UL, 0x7bf8b752UL, 0x72f5bc5cUL,
+      0x05bed506UL, 0x0cb3de08UL, 0x17a4c31aUL, 0x1ea9c814UL,
+      0x218af93eUL, 0x2887f230UL, 0x3390ef22UL, 0x3a9de42cUL,
+      0xdd063d96UL, 0xd40b3698UL, 0xcf1c2b8aUL, 0xc6112084UL,
+      0xf93211aeUL, 0xf03f1aa0UL, 0xeb2807b2UL, 0xe2250cbcUL,
+      0x956e65e6UL, 0x9c636ee8UL, 0x877473faUL, 0x8e7978f4UL,
+      0xb15a49deUL, 0xb85742d0UL, 0xa3405fc2UL, 0xaa4d54ccUL,
+      0xecdaf741UL, 0xe5d7fc4fUL, 0xfec0e15dUL, 0xf7cdea53UL,
+      0xc8eedb79UL, 0xc1e3d077UL, 0xdaf4cd65UL, 0xd3f9c66bUL,
+      0xa4b2af31UL, 0xadbfa43fUL, 0xb6a8b92dUL, 0xbfa5b223UL,
+      0x80868309UL, 0x898b8807UL, 0x929c9515UL, 0x9b919e1bUL,
+      0x7c0a47a1UL, 0x75074cafUL, 0x6e1051bdUL, 0x671d5ab3UL,
+      0x583e6b99UL, 0x51336097UL, 0x4a247d85UL, 0x4329768bUL,
+      0x34621fd1UL, 0x3d6f14dfUL, 0x267809cdUL, 0x2f7502c3UL,
+      0x105633e9UL, 0x195b38e7UL, 0x024c25f5UL, 0x0b412efbUL,
+      0xd7618c9aUL, 0xde6c8794UL, 0xc57b9a86UL, 0xcc769188UL,
+      0xf355a0a2UL, 0xfa58abacUL, 0xe14fb6beUL, 0xe842bdb0UL,
+      0x9f09d4eaUL, 0x9604dfe4UL, 0x8d13c2f6UL, 0x841ec9f8UL,
+      0xbb3df8d2UL, 0xb230f3dcUL, 0xa927eeceUL, 0xa02ae5c0UL,
+      0x47b13c7aUL, 0x4ebc3774UL, 0x55ab2a66UL, 0x5ca62168UL,
+      0x63851042UL, 0x6a881b4cUL, 0x719f065eUL, 0x78920d50UL,
+      0x0fd9640aUL, 0x06d46f04UL, 0x1dc37216UL, 0x14ce7918UL,
+      0x2bed4832UL, 0x22e0433cUL, 0x39f75e2eUL, 0x30fa5520UL,
+      0x9ab701ecUL, 0x93ba0ae2UL, 0x88ad17f0UL, 0x81a01cfeUL,
+      0xbe832dd4UL, 0xb78e26daUL, 0xac993bc8UL, 0xa59430c6UL,
+      0xd2df599cUL, 0xdbd25292UL, 0xc0c54f80UL, 0xc9c8448eUL,
+      0xf6eb75a4UL, 0xffe67eaaUL, 0xe4f163b8UL, 0xedfc68b6UL,
+      0x0a67b10cUL, 0x036aba02UL, 0x187da710UL, 0x1170ac1eUL,
+      0x2e539d34UL, 0x275e963aUL, 0x3c498b28UL, 0x35448026UL,
+      0x420fe97cUL, 0x4b02e272UL, 0x5015ff60UL, 0x5918f46eUL,
+      0x663bc544UL, 0x6f36ce4aUL, 0x7421d358UL, 0x7d2cd856UL,
+      0xa10c7a37UL, 0xa8017139UL, 0xb3166c2bUL, 0xba1b6725UL,
+      0x8538560fUL, 0x8c355d01UL, 0x97224013UL, 0x9e2f4b1dUL,
+      0xe9642247UL, 0xe0692949UL, 0xfb7e345bUL, 0xf2733f55UL,
+      0xcd500e7fUL, 0xc45d0571UL, 0xdf4a1863UL, 0xd647136dUL,
+      0x31dccad7UL, 0x38d1c1d9UL, 0x23c6dccbUL, 0x2acbd7c5UL,
+      0x15e8e6efUL, 0x1ce5ede1UL, 0x07f2f0f3UL, 0x0efffbfdUL,
+      0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL,
+      0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL
+  };
+  const SWord32 s560 = s0 ^ s4;
+  const SWord8  s561 = (SWord8) (s560 >> 24);
+  const SWord8  s562 = table0[s561];
+  const SWord8  s563 = (SWord8) (s8 >> 24);
+  const SWord8  s564 = s562 ^ s563;
+  const SWord32 s565 = table1[s564];
+  const SWord32 s821 = s3 ^ s7;
+  const SWord8  s822 = (SWord8) (s821 >> 16);
+  const SWord8  s823 = table0[s822];
+  const SWord8  s824 = (SWord8) (s8 >> 16);
+  const SWord8  s825 = s823 ^ s824;
+  const SWord32 s826 = table2[s825];
+  const SWord32 s827 = s565 ^ s826;
+  const SWord32 s1083 = s2 ^ s6;
+  const SWord8  s1084 = (SWord8) (s1083 >> 8);
+  const SWord8  s1085 = table0[s1084];
+  const SWord8  s1086 = (SWord8) (s8 >> 8);
+  const SWord8  s1087 = s1085 ^ s1086;
+  const SWord32 s1088 = table3[s1087];
+  const SWord32 s1089 = s827 ^ s1088;
+  const SWord32 s1345 = s1 ^ s5;
+  const SWord8  s1346 = (SWord8) s1345;
+  const SWord8  s1347 = table0[s1346];
+  const SWord8  s1348 = (SWord8) s8;
+  const SWord8  s1349 = s1347 ^ s1348;
+  const SWord32 s1350 = table4[s1349];
+  const SWord32 s1351 = s1089 ^ s1350;
+  const SWord8  s1352 = (SWord8) (s1351 >> 24);
+  const SWord8  s1353 = table0[s1352];
+  const SWord8  s1354 = (SWord8) (s12 >> 24);
+  const SWord8  s1355 = s1353 ^ s1354;
+  const SWord32 s1356 = table1[s1355];
+  const SWord8  s1357 = (SWord8) (s821 >> 24);
+  const SWord8  s1358 = table0[s1357];
+  const SWord8  s1359 = (SWord8) (s11 >> 24);
+  const SWord8  s1360 = s1358 ^ s1359;
+  const SWord32 s1361 = table1[s1360];
+  const SWord8  s1362 = (SWord8) (s1083 >> 16);
+  const SWord8  s1363 = table0[s1362];
+  const SWord8  s1364 = (SWord8) (s11 >> 16);
+  const SWord8  s1365 = s1363 ^ s1364;
+  const SWord32 s1366 = table2[s1365];
+  const SWord32 s1367 = s1361 ^ s1366;
+  const SWord8  s1368 = (SWord8) (s1345 >> 8);
+  const SWord8  s1369 = table0[s1368];
+  const SWord8  s1370 = (SWord8) (s11 >> 8);
+  const SWord8  s1371 = s1369 ^ s1370;
+  const SWord32 s1372 = table3[s1371];
+  const SWord32 s1373 = s1367 ^ s1372;
+  const SWord8  s1374 = (SWord8) s560;
+  const SWord8  s1375 = table0[s1374];
+  const SWord8  s1376 = (SWord8) s11;
+  const SWord8  s1377 = s1375 ^ s1376;
+  const SWord32 s1378 = table4[s1377];
+  const SWord32 s1379 = s1373 ^ s1378;
+  const SWord8  s1380 = (SWord8) (s1379 >> 16);
+  const SWord8  s1381 = table0[s1380];
+  const SWord8  s1382 = (SWord8) (s12 >> 16);
+  const SWord8  s1383 = s1381 ^ s1382;
+  const SWord32 s1384 = table2[s1383];
+  const SWord32 s1385 = s1356 ^ s1384;
+  const SWord8  s1386 = (SWord8) (s1083 >> 24);
+  const SWord8  s1387 = table0[s1386];
+  const SWord8  s1388 = (SWord8) (s10 >> 24);
+  const SWord8  s1389 = s1387 ^ s1388;
+  const SWord32 s1390 = table1[s1389];
+  const SWord8  s1391 = (SWord8) (s1345 >> 16);
+  const SWord8  s1392 = table0[s1391];
+  const SWord8  s1393 = (SWord8) (s10 >> 16);
+  const SWord8  s1394 = s1392 ^ s1393;
+  const SWord32 s1395 = table2[s1394];
+  const SWord32 s1396 = s1390 ^ s1395;
+  const SWord8  s1397 = (SWord8) (s560 >> 8);
+  const SWord8  s1398 = table0[s1397];
+  const SWord8  s1399 = (SWord8) (s10 >> 8);
+  const SWord8  s1400 = s1398 ^ s1399;
+  const SWord32 s1401 = table3[s1400];
+  const SWord32 s1402 = s1396 ^ s1401;
+  const SWord8  s1403 = (SWord8) s821;
+  const SWord8  s1404 = table0[s1403];
+  const SWord8  s1405 = (SWord8) s10;
+  const SWord8  s1406 = s1404 ^ s1405;
+  const SWord32 s1407 = table4[s1406];
+  const SWord32 s1408 = s1402 ^ s1407;
+  const SWord8  s1409 = (SWord8) (s1408 >> 8);
+  const SWord8  s1410 = table0[s1409];
+  const SWord8  s1411 = (SWord8) (s12 >> 8);
+  const SWord8  s1412 = s1410 ^ s1411;
+  const SWord32 s1413 = table3[s1412];
+  const SWord32 s1414 = s1385 ^ s1413;
+  const SWord8  s1415 = (SWord8) (s1345 >> 24);
+  const SWord8  s1416 = table0[s1415];
+  const SWord8  s1417 = (SWord8) (s9 >> 24);
+  const SWord8  s1418 = s1416 ^ s1417;
+  const SWord32 s1419 = table1[s1418];
+  const SWord8  s1420 = (SWord8) (s560 >> 16);
+  const SWord8  s1421 = table0[s1420];
+  const SWord8  s1422 = (SWord8) (s9 >> 16);
+  const SWord8  s1423 = s1421 ^ s1422;
+  const SWord32 s1424 = table2[s1423];
+  const SWord32 s1425 = s1419 ^ s1424;
+  const SWord8  s1426 = (SWord8) (s821 >> 8);
+  const SWord8  s1427 = table0[s1426];
+  const SWord8  s1428 = (SWord8) (s9 >> 8);
+  const SWord8  s1429 = s1427 ^ s1428;
+  const SWord32 s1430 = table3[s1429];
+  const SWord32 s1431 = s1425 ^ s1430;
+  const SWord8  s1432 = (SWord8) s1083;
+  const SWord8  s1433 = table0[s1432];
+  const SWord8  s1434 = (SWord8) s9;
+  const SWord8  s1435 = s1433 ^ s1434;
+  const SWord32 s1436 = table4[s1435];
+  const SWord32 s1437 = s1431 ^ s1436;
+  const SWord8  s1438 = (SWord8) s1437;
+  const SWord8  s1439 = table0[s1438];
+  const SWord8  s1440 = (SWord8) s12;
+  const SWord8  s1441 = s1439 ^ s1440;
+  const SWord32 s1442 = table4[s1441];
+  const SWord32 s1443 = s1414 ^ s1442;
+  const SWord8  s1444 = (SWord8) (s1443 >> 24);
+  const SWord8  s1445 = table0[s1444];
+  const SWord8  s1446 = (SWord8) (s16 >> 24);
+  const SWord8  s1447 = s1445 ^ s1446;
+  const SWord32 s1448 = table1[s1447];
+  const SWord8  s1449 = (SWord8) (s1379 >> 24);
+  const SWord8  s1450 = table0[s1449];
+  const SWord8  s1451 = (SWord8) (s15 >> 24);
+  const SWord8  s1452 = s1450 ^ s1451;
+  const SWord32 s1453 = table1[s1452];
+  const SWord8  s1454 = (SWord8) (s1408 >> 16);
+  const SWord8  s1455 = table0[s1454];
+  const SWord8  s1456 = (SWord8) (s15 >> 16);
+  const SWord8  s1457 = s1455 ^ s1456;
+  const SWord32 s1458 = table2[s1457];
+  const SWord32 s1459 = s1453 ^ s1458;
+  const SWord8  s1460 = (SWord8) (s1437 >> 8);
+  const SWord8  s1461 = table0[s1460];
+  const SWord8  s1462 = (SWord8) (s15 >> 8);
+  const SWord8  s1463 = s1461 ^ s1462;
+  const SWord32 s1464 = table3[s1463];
+  const SWord32 s1465 = s1459 ^ s1464;
+  const SWord8  s1466 = (SWord8) s1351;
+  const SWord8  s1467 = table0[s1466];
+  const SWord8  s1468 = (SWord8) s15;
+  const SWord8  s1469 = s1467 ^ s1468;
+  const SWord32 s1470 = table4[s1469];
+  const SWord32 s1471 = s1465 ^ s1470;
+  const SWord8  s1472 = (SWord8) (s1471 >> 16);
+  const SWord8  s1473 = table0[s1472];
+  const SWord8  s1474 = (SWord8) (s16 >> 16);
+  const SWord8  s1475 = s1473 ^ s1474;
+  const SWord32 s1476 = table2[s1475];
+  const SWord32 s1477 = s1448 ^ s1476;
+  const SWord8  s1478 = (SWord8) (s1408 >> 24);
+  const SWord8  s1479 = table0[s1478];
+  const SWord8  s1480 = (SWord8) (s14 >> 24);
+  const SWord8  s1481 = s1479 ^ s1480;
+  const SWord32 s1482 = table1[s1481];
+  const SWord8  s1483 = (SWord8) (s1437 >> 16);
+  const SWord8  s1484 = table0[s1483];
+  const SWord8  s1485 = (SWord8) (s14 >> 16);
+  const SWord8  s1486 = s1484 ^ s1485;
+  const SWord32 s1487 = table2[s1486];
+  const SWord32 s1488 = s1482 ^ s1487;
+  const SWord8  s1489 = (SWord8) (s1351 >> 8);
+  const SWord8  s1490 = table0[s1489];
+  const SWord8  s1491 = (SWord8) (s14 >> 8);
+  const SWord8  s1492 = s1490 ^ s1491;
+  const SWord32 s1493 = table3[s1492];
+  const SWord32 s1494 = s1488 ^ s1493;
+  const SWord8  s1495 = (SWord8) s1379;
+  const SWord8  s1496 = table0[s1495];
+  const SWord8  s1497 = (SWord8) s14;
+  const SWord8  s1498 = s1496 ^ s1497;
+  const SWord32 s1499 = table4[s1498];
+  const SWord32 s1500 = s1494 ^ s1499;
+  const SWord8  s1501 = (SWord8) (s1500 >> 8);
+  const SWord8  s1502 = table0[s1501];
+  const SWord8  s1503 = (SWord8) (s16 >> 8);
+  const SWord8  s1504 = s1502 ^ s1503;
+  const SWord32 s1505 = table3[s1504];
+  const SWord32 s1506 = s1477 ^ s1505;
+  const SWord8  s1507 = (SWord8) (s1437 >> 24);
+  const SWord8  s1508 = table0[s1507];
+  const SWord8  s1509 = (SWord8) (s13 >> 24);
+  const SWord8  s1510 = s1508 ^ s1509;
+  const SWord32 s1511 = table1[s1510];
+  const SWord8  s1512 = (SWord8) (s1351 >> 16);
+  const SWord8  s1513 = table0[s1512];
+  const SWord8  s1514 = (SWord8) (s13 >> 16);
+  const SWord8  s1515 = s1513 ^ s1514;
+  const SWord32 s1516 = table2[s1515];
+  const SWord32 s1517 = s1511 ^ s1516;
+  const SWord8  s1518 = (SWord8) (s1379 >> 8);
+  const SWord8  s1519 = table0[s1518];
+  const SWord8  s1520 = (SWord8) (s13 >> 8);
+  const SWord8  s1521 = s1519 ^ s1520;
+  const SWord32 s1522 = table3[s1521];
+  const SWord32 s1523 = s1517 ^ s1522;
+  const SWord8  s1524 = (SWord8) s1408;
+  const SWord8  s1525 = table0[s1524];
+  const SWord8  s1526 = (SWord8) s13;
+  const SWord8  s1527 = s1525 ^ s1526;
+  const SWord32 s1528 = table4[s1527];
+  const SWord32 s1529 = s1523 ^ s1528;
+  const SWord8  s1530 = (SWord8) s1529;
+  const SWord8  s1531 = table0[s1530];
+  const SWord8  s1532 = (SWord8) s16;
+  const SWord8  s1533 = s1531 ^ s1532;
+  const SWord32 s1534 = table4[s1533];
+  const SWord32 s1535 = s1506 ^ s1534;
+  const SWord8  s1536 = (SWord8) (s1535 >> 24);
+  const SWord8  s1537 = table0[s1536];
+  const SWord8  s1538 = (SWord8) (s20 >> 24);
+  const SWord8  s1539 = s1537 ^ s1538;
+  const SWord32 s1540 = table1[s1539];
+  const SWord8  s1541 = (SWord8) (s1471 >> 24);
+  const SWord8  s1542 = table0[s1541];
+  const SWord8  s1543 = (SWord8) (s19 >> 24);
+  const SWord8  s1544 = s1542 ^ s1543;
+  const SWord32 s1545 = table1[s1544];
+  const SWord8  s1546 = (SWord8) (s1500 >> 16);
+  const SWord8  s1547 = table0[s1546];
+  const SWord8  s1548 = (SWord8) (s19 >> 16);
+  const SWord8  s1549 = s1547 ^ s1548;
+  const SWord32 s1550 = table2[s1549];
+  const SWord32 s1551 = s1545 ^ s1550;
+  const SWord8  s1552 = (SWord8) (s1529 >> 8);
+  const SWord8  s1553 = table0[s1552];
+  const SWord8  s1554 = (SWord8) (s19 >> 8);
+  const SWord8  s1555 = s1553 ^ s1554;
+  const SWord32 s1556 = table3[s1555];
+  const SWord32 s1557 = s1551 ^ s1556;
+  const SWord8  s1558 = (SWord8) s1443;
+  const SWord8  s1559 = table0[s1558];
+  const SWord8  s1560 = (SWord8) s19;
+  const SWord8  s1561 = s1559 ^ s1560;
+  const SWord32 s1562 = table4[s1561];
+  const SWord32 s1563 = s1557 ^ s1562;
+  const SWord8  s1564 = (SWord8) (s1563 >> 16);
+  const SWord8  s1565 = table0[s1564];
+  const SWord8  s1566 = (SWord8) (s20 >> 16);
+  const SWord8  s1567 = s1565 ^ s1566;
+  const SWord32 s1568 = table2[s1567];
+  const SWord32 s1569 = s1540 ^ s1568;
+  const SWord8  s1570 = (SWord8) (s1500 >> 24);
+  const SWord8  s1571 = table0[s1570];
+  const SWord8  s1572 = (SWord8) (s18 >> 24);
+  const SWord8  s1573 = s1571 ^ s1572;
+  const SWord32 s1574 = table1[s1573];
+  const SWord8  s1575 = (SWord8) (s1529 >> 16);
+  const SWord8  s1576 = table0[s1575];
+  const SWord8  s1577 = (SWord8) (s18 >> 16);
+  const SWord8  s1578 = s1576 ^ s1577;
+  const SWord32 s1579 = table2[s1578];
+  const SWord32 s1580 = s1574 ^ s1579;
+  const SWord8  s1581 = (SWord8) (s1443 >> 8);
+  const SWord8  s1582 = table0[s1581];
+  const SWord8  s1583 = (SWord8) (s18 >> 8);
+  const SWord8  s1584 = s1582 ^ s1583;
+  const SWord32 s1585 = table3[s1584];
+  const SWord32 s1586 = s1580 ^ s1585;
+  const SWord8  s1587 = (SWord8) s1471;
+  const SWord8  s1588 = table0[s1587];
+  const SWord8  s1589 = (SWord8) s18;
+  const SWord8  s1590 = s1588 ^ s1589;
+  const SWord32 s1591 = table4[s1590];
+  const SWord32 s1592 = s1586 ^ s1591;
+  const SWord8  s1593 = (SWord8) (s1592 >> 8);
+  const SWord8  s1594 = table0[s1593];
+  const SWord8  s1595 = (SWord8) (s20 >> 8);
+  const SWord8  s1596 = s1594 ^ s1595;
+  const SWord32 s1597 = table3[s1596];
+  const SWord32 s1598 = s1569 ^ s1597;
+  const SWord8  s1599 = (SWord8) (s1529 >> 24);
+  const SWord8  s1600 = table0[s1599];
+  const SWord8  s1601 = (SWord8) (s17 >> 24);
+  const SWord8  s1602 = s1600 ^ s1601;
+  const SWord32 s1603 = table1[s1602];
+  const SWord8  s1604 = (SWord8) (s1443 >> 16);
+  const SWord8  s1605 = table0[s1604];
+  const SWord8  s1606 = (SWord8) (s17 >> 16);
+  const SWord8  s1607 = s1605 ^ s1606;
+  const SWord32 s1608 = table2[s1607];
+  const SWord32 s1609 = s1603 ^ s1608;
+  const SWord8  s1610 = (SWord8) (s1471 >> 8);
+  const SWord8  s1611 = table0[s1610];
+  const SWord8  s1612 = (SWord8) (s17 >> 8);
+  const SWord8  s1613 = s1611 ^ s1612;
+  const SWord32 s1614 = table3[s1613];
+  const SWord32 s1615 = s1609 ^ s1614;
+  const SWord8  s1616 = (SWord8) s1500;
+  const SWord8  s1617 = table0[s1616];
+  const SWord8  s1618 = (SWord8) s17;
+  const SWord8  s1619 = s1617 ^ s1618;
+  const SWord32 s1620 = table4[s1619];
+  const SWord32 s1621 = s1615 ^ s1620;
+  const SWord8  s1622 = (SWord8) s1621;
+  const SWord8  s1623 = table0[s1622];
+  const SWord8  s1624 = (SWord8) s20;
+  const SWord8  s1625 = s1623 ^ s1624;
+  const SWord32 s1626 = table4[s1625];
+  const SWord32 s1627 = s1598 ^ s1626;
+  const SWord8  s1628 = (SWord8) (s1627 >> 24);
+  const SWord8  s1629 = table0[s1628];
+  const SWord8  s1630 = (SWord8) (s24 >> 24);
+  const SWord8  s1631 = s1629 ^ s1630;
+  const SWord32 s1632 = table1[s1631];
+  const SWord8  s1633 = (SWord8) (s1563 >> 24);
+  const SWord8  s1634 = table0[s1633];
+  const SWord8  s1635 = (SWord8) (s23 >> 24);
+  const SWord8  s1636 = s1634 ^ s1635;
+  const SWord32 s1637 = table1[s1636];
+  const SWord8  s1638 = (SWord8) (s1592 >> 16);
+  const SWord8  s1639 = table0[s1638];
+  const SWord8  s1640 = (SWord8) (s23 >> 16);
+  const SWord8  s1641 = s1639 ^ s1640;
+  const SWord32 s1642 = table2[s1641];
+  const SWord32 s1643 = s1637 ^ s1642;
+  const SWord8  s1644 = (SWord8) (s1621 >> 8);
+  const SWord8  s1645 = table0[s1644];
+  const SWord8  s1646 = (SWord8) (s23 >> 8);
+  const SWord8  s1647 = s1645 ^ s1646;
+  const SWord32 s1648 = table3[s1647];
+  const SWord32 s1649 = s1643 ^ s1648;
+  const SWord8  s1650 = (SWord8) s1535;
+  const SWord8  s1651 = table0[s1650];
+  const SWord8  s1652 = (SWord8) s23;
+  const SWord8  s1653 = s1651 ^ s1652;
+  const SWord32 s1654 = table4[s1653];
+  const SWord32 s1655 = s1649 ^ s1654;
+  const SWord8  s1656 = (SWord8) (s1655 >> 16);
+  const SWord8  s1657 = table0[s1656];
+  const SWord8  s1658 = (SWord8) (s24 >> 16);
+  const SWord8  s1659 = s1657 ^ s1658;
+  const SWord32 s1660 = table2[s1659];
+  const SWord32 s1661 = s1632 ^ s1660;
+  const SWord8  s1662 = (SWord8) (s1592 >> 24);
+  const SWord8  s1663 = table0[s1662];
+  const SWord8  s1664 = (SWord8) (s22 >> 24);
+  const SWord8  s1665 = s1663 ^ s1664;
+  const SWord32 s1666 = table1[s1665];
+  const SWord8  s1667 = (SWord8) (s1621 >> 16);
+  const SWord8  s1668 = table0[s1667];
+  const SWord8  s1669 = (SWord8) (s22 >> 16);
+  const SWord8  s1670 = s1668 ^ s1669;
+  const SWord32 s1671 = table2[s1670];
+  const SWord32 s1672 = s1666 ^ s1671;
+  const SWord8  s1673 = (SWord8) (s1535 >> 8);
+  const SWord8  s1674 = table0[s1673];
+  const SWord8  s1675 = (SWord8) (s22 >> 8);
+  const SWord8  s1676 = s1674 ^ s1675;
+  const SWord32 s1677 = table3[s1676];
+  const SWord32 s1678 = s1672 ^ s1677;
+  const SWord8  s1679 = (SWord8) s1563;
+  const SWord8  s1680 = table0[s1679];
+  const SWord8  s1681 = (SWord8) s22;
+  const SWord8  s1682 = s1680 ^ s1681;
+  const SWord32 s1683 = table4[s1682];
+  const SWord32 s1684 = s1678 ^ s1683;
+  const SWord8  s1685 = (SWord8) (s1684 >> 8);
+  const SWord8  s1686 = table0[s1685];
+  const SWord8  s1687 = (SWord8) (s24 >> 8);
+  const SWord8  s1688 = s1686 ^ s1687;
+  const SWord32 s1689 = table3[s1688];
+  const SWord32 s1690 = s1661 ^ s1689;
+  const SWord8  s1691 = (SWord8) (s1621 >> 24);
+  const SWord8  s1692 = table0[s1691];
+  const SWord8  s1693 = (SWord8) (s21 >> 24);
+  const SWord8  s1694 = s1692 ^ s1693;
+  const SWord32 s1695 = table1[s1694];
+  const SWord8  s1696 = (SWord8) (s1535 >> 16);
+  const SWord8  s1697 = table0[s1696];
+  const SWord8  s1698 = (SWord8) (s21 >> 16);
+  const SWord8  s1699 = s1697 ^ s1698;
+  const SWord32 s1700 = table2[s1699];
+  const SWord32 s1701 = s1695 ^ s1700;
+  const SWord8  s1702 = (SWord8) (s1563 >> 8);
+  const SWord8  s1703 = table0[s1702];
+  const SWord8  s1704 = (SWord8) (s21 >> 8);
+  const SWord8  s1705 = s1703 ^ s1704;
+  const SWord32 s1706 = table3[s1705];
+  const SWord32 s1707 = s1701 ^ s1706;
+  const SWord8  s1708 = (SWord8) s1592;
+  const SWord8  s1709 = table0[s1708];
+  const SWord8  s1710 = (SWord8) s21;
+  const SWord8  s1711 = s1709 ^ s1710;
+  const SWord32 s1712 = table4[s1711];
+  const SWord32 s1713 = s1707 ^ s1712;
+  const SWord8  s1714 = (SWord8) s1713;
+  const SWord8  s1715 = table0[s1714];
+  const SWord8  s1716 = (SWord8) s24;
+  const SWord8  s1717 = s1715 ^ s1716;
+  const SWord32 s1718 = table4[s1717];
+  const SWord32 s1719 = s1690 ^ s1718;
+  const SWord8  s1720 = (SWord8) (s1719 >> 24);
+  const SWord8  s1721 = table0[s1720];
+  const SWord8  s1722 = (SWord8) (s28 >> 24);
+  const SWord8  s1723 = s1721 ^ s1722;
+  const SWord32 s1724 = table1[s1723];
+  const SWord8  s1725 = (SWord8) (s1655 >> 24);
+  const SWord8  s1726 = table0[s1725];
+  const SWord8  s1727 = (SWord8) (s27 >> 24);
+  const SWord8  s1728 = s1726 ^ s1727;
+  const SWord32 s1729 = table1[s1728];
+  const SWord8  s1730 = (SWord8) (s1684 >> 16);
+  const SWord8  s1731 = table0[s1730];
+  const SWord8  s1732 = (SWord8) (s27 >> 16);
+  const SWord8  s1733 = s1731 ^ s1732;
+  const SWord32 s1734 = table2[s1733];
+  const SWord32 s1735 = s1729 ^ s1734;
+  const SWord8  s1736 = (SWord8) (s1713 >> 8);
+  const SWord8  s1737 = table0[s1736];
+  const SWord8  s1738 = (SWord8) (s27 >> 8);
+  const SWord8  s1739 = s1737 ^ s1738;
+  const SWord32 s1740 = table3[s1739];
+  const SWord32 s1741 = s1735 ^ s1740;
+  const SWord8  s1742 = (SWord8) s1627;
+  const SWord8  s1743 = table0[s1742];
+  const SWord8  s1744 = (SWord8) s27;
+  const SWord8  s1745 = s1743 ^ s1744;
+  const SWord32 s1746 = table4[s1745];
+  const SWord32 s1747 = s1741 ^ s1746;
+  const SWord8  s1748 = (SWord8) (s1747 >> 16);
+  const SWord8  s1749 = table0[s1748];
+  const SWord8  s1750 = (SWord8) (s28 >> 16);
+  const SWord8  s1751 = s1749 ^ s1750;
+  const SWord32 s1752 = table2[s1751];
+  const SWord32 s1753 = s1724 ^ s1752;
+  const SWord8  s1754 = (SWord8) (s1684 >> 24);
+  const SWord8  s1755 = table0[s1754];
+  const SWord8  s1756 = (SWord8) (s26 >> 24);
+  const SWord8  s1757 = s1755 ^ s1756;
+  const SWord32 s1758 = table1[s1757];
+  const SWord8  s1759 = (SWord8) (s1713 >> 16);
+  const SWord8  s1760 = table0[s1759];
+  const SWord8  s1761 = (SWord8) (s26 >> 16);
+  const SWord8  s1762 = s1760 ^ s1761;
+  const SWord32 s1763 = table2[s1762];
+  const SWord32 s1764 = s1758 ^ s1763;
+  const SWord8  s1765 = (SWord8) (s1627 >> 8);
+  const SWord8  s1766 = table0[s1765];
+  const SWord8  s1767 = (SWord8) (s26 >> 8);
+  const SWord8  s1768 = s1766 ^ s1767;
+  const SWord32 s1769 = table3[s1768];
+  const SWord32 s1770 = s1764 ^ s1769;
+  const SWord8  s1771 = (SWord8) s1655;
+  const SWord8  s1772 = table0[s1771];
+  const SWord8  s1773 = (SWord8) s26;
+  const SWord8  s1774 = s1772 ^ s1773;
+  const SWord32 s1775 = table4[s1774];
+  const SWord32 s1776 = s1770 ^ s1775;
+  const SWord8  s1777 = (SWord8) (s1776 >> 8);
+  const SWord8  s1778 = table0[s1777];
+  const SWord8  s1779 = (SWord8) (s28 >> 8);
+  const SWord8  s1780 = s1778 ^ s1779;
+  const SWord32 s1781 = table3[s1780];
+  const SWord32 s1782 = s1753 ^ s1781;
+  const SWord8  s1783 = (SWord8) (s1713 >> 24);
+  const SWord8  s1784 = table0[s1783];
+  const SWord8  s1785 = (SWord8) (s25 >> 24);
+  const SWord8  s1786 = s1784 ^ s1785;
+  const SWord32 s1787 = table1[s1786];
+  const SWord8  s1788 = (SWord8) (s1627 >> 16);
+  const SWord8  s1789 = table0[s1788];
+  const SWord8  s1790 = (SWord8) (s25 >> 16);
+  const SWord8  s1791 = s1789 ^ s1790;
+  const SWord32 s1792 = table2[s1791];
+  const SWord32 s1793 = s1787 ^ s1792;
+  const SWord8  s1794 = (SWord8) (s1655 >> 8);
+  const SWord8  s1795 = table0[s1794];
+  const SWord8  s1796 = (SWord8) (s25 >> 8);
+  const SWord8  s1797 = s1795 ^ s1796;
+  const SWord32 s1798 = table3[s1797];
+  const SWord32 s1799 = s1793 ^ s1798;
+  const SWord8  s1800 = (SWord8) s1684;
+  const SWord8  s1801 = table0[s1800];
+  const SWord8  s1802 = (SWord8) s25;
+  const SWord8  s1803 = s1801 ^ s1802;
+  const SWord32 s1804 = table4[s1803];
+  const SWord32 s1805 = s1799 ^ s1804;
+  const SWord8  s1806 = (SWord8) s1805;
+  const SWord8  s1807 = table0[s1806];
+  const SWord8  s1808 = (SWord8) s28;
+  const SWord8  s1809 = s1807 ^ s1808;
+  const SWord32 s1810 = table4[s1809];
+  const SWord32 s1811 = s1782 ^ s1810;
+  const SWord8  s1812 = (SWord8) (s1811 >> 24);
+  const SWord8  s1813 = table0[s1812];
+  const SWord8  s1814 = (SWord8) (s32 >> 24);
+  const SWord8  s1815 = s1813 ^ s1814;
+  const SWord32 s1816 = table1[s1815];
+  const SWord8  s1817 = (SWord8) (s1747 >> 24);
+  const SWord8  s1818 = table0[s1817];
+  const SWord8  s1819 = (SWord8) (s31 >> 24);
+  const SWord8  s1820 = s1818 ^ s1819;
+  const SWord32 s1821 = table1[s1820];
+  const SWord8  s1822 = (SWord8) (s1776 >> 16);
+  const SWord8  s1823 = table0[s1822];
+  const SWord8  s1824 = (SWord8) (s31 >> 16);
+  const SWord8  s1825 = s1823 ^ s1824;
+  const SWord32 s1826 = table2[s1825];
+  const SWord32 s1827 = s1821 ^ s1826;
+  const SWord8  s1828 = (SWord8) (s1805 >> 8);
+  const SWord8  s1829 = table0[s1828];
+  const SWord8  s1830 = (SWord8) (s31 >> 8);
+  const SWord8  s1831 = s1829 ^ s1830;
+  const SWord32 s1832 = table3[s1831];
+  const SWord32 s1833 = s1827 ^ s1832;
+  const SWord8  s1834 = (SWord8) s1719;
+  const SWord8  s1835 = table0[s1834];
+  const SWord8  s1836 = (SWord8) s31;
+  const SWord8  s1837 = s1835 ^ s1836;
+  const SWord32 s1838 = table4[s1837];
+  const SWord32 s1839 = s1833 ^ s1838;
+  const SWord8  s1840 = (SWord8) (s1839 >> 16);
+  const SWord8  s1841 = table0[s1840];
+  const SWord8  s1842 = (SWord8) (s32 >> 16);
+  const SWord8  s1843 = s1841 ^ s1842;
+  const SWord32 s1844 = table2[s1843];
+  const SWord32 s1845 = s1816 ^ s1844;
+  const SWord8  s1846 = (SWord8) (s1776 >> 24);
+  const SWord8  s1847 = table0[s1846];
+  const SWord8  s1848 = (SWord8) (s30 >> 24);
+  const SWord8  s1849 = s1847 ^ s1848;
+  const SWord32 s1850 = table1[s1849];
+  const SWord8  s1851 = (SWord8) (s1805 >> 16);
+  const SWord8  s1852 = table0[s1851];
+  const SWord8  s1853 = (SWord8) (s30 >> 16);
+  const SWord8  s1854 = s1852 ^ s1853;
+  const SWord32 s1855 = table2[s1854];
+  const SWord32 s1856 = s1850 ^ s1855;
+  const SWord8  s1857 = (SWord8) (s1719 >> 8);
+  const SWord8  s1858 = table0[s1857];
+  const SWord8  s1859 = (SWord8) (s30 >> 8);
+  const SWord8  s1860 = s1858 ^ s1859;
+  const SWord32 s1861 = table3[s1860];
+  const SWord32 s1862 = s1856 ^ s1861;
+  const SWord8  s1863 = (SWord8) s1747;
+  const SWord8  s1864 = table0[s1863];
+  const SWord8  s1865 = (SWord8) s30;
+  const SWord8  s1866 = s1864 ^ s1865;
+  const SWord32 s1867 = table4[s1866];
+  const SWord32 s1868 = s1862 ^ s1867;
+  const SWord8  s1869 = (SWord8) (s1868 >> 8);
+  const SWord8  s1870 = table0[s1869];
+  const SWord8  s1871 = (SWord8) (s32 >> 8);
+  const SWord8  s1872 = s1870 ^ s1871;
+  const SWord32 s1873 = table3[s1872];
+  const SWord32 s1874 = s1845 ^ s1873;
+  const SWord8  s1875 = (SWord8) (s1805 >> 24);
+  const SWord8  s1876 = table0[s1875];
+  const SWord8  s1877 = (SWord8) (s29 >> 24);
+  const SWord8  s1878 = s1876 ^ s1877;
+  const SWord32 s1879 = table1[s1878];
+  const SWord8  s1880 = (SWord8) (s1719 >> 16);
+  const SWord8  s1881 = table0[s1880];
+  const SWord8  s1882 = (SWord8) (s29 >> 16);
+  const SWord8  s1883 = s1881 ^ s1882;
+  const SWord32 s1884 = table2[s1883];
+  const SWord32 s1885 = s1879 ^ s1884;
+  const SWord8  s1886 = (SWord8) (s1747 >> 8);
+  const SWord8  s1887 = table0[s1886];
+  const SWord8  s1888 = (SWord8) (s29 >> 8);
+  const SWord8  s1889 = s1887 ^ s1888;
+  const SWord32 s1890 = table3[s1889];
+  const SWord32 s1891 = s1885 ^ s1890;
+  const SWord8  s1892 = (SWord8) s1776;
+  const SWord8  s1893 = table0[s1892];
+  const SWord8  s1894 = (SWord8) s29;
+  const SWord8  s1895 = s1893 ^ s1894;
+  const SWord32 s1896 = table4[s1895];
+  const SWord32 s1897 = s1891 ^ s1896;
+  const SWord8  s1898 = (SWord8) s1897;
+  const SWord8  s1899 = table0[s1898];
+  const SWord8  s1900 = (SWord8) s32;
+  const SWord8  s1901 = s1899 ^ s1900;
+  const SWord32 s1902 = table4[s1901];
+  const SWord32 s1903 = s1874 ^ s1902;
+  const SWord8  s1904 = (SWord8) (s1903 >> 24);
+  const SWord8  s1905 = table0[s1904];
+  const SWord8  s1906 = (SWord8) (s36 >> 24);
+  const SWord8  s1907 = s1905 ^ s1906;
+  const SWord32 s1908 = table1[s1907];
+  const SWord8  s1909 = (SWord8) (s1839 >> 24);
+  const SWord8  s1910 = table0[s1909];
+  const SWord8  s1911 = (SWord8) (s35 >> 24);
+  const SWord8  s1912 = s1910 ^ s1911;
+  const SWord32 s1913 = table1[s1912];
+  const SWord8  s1914 = (SWord8) (s1868 >> 16);
+  const SWord8  s1915 = table0[s1914];
+  const SWord8  s1916 = (SWord8) (s35 >> 16);
+  const SWord8  s1917 = s1915 ^ s1916;
+  const SWord32 s1918 = table2[s1917];
+  const SWord32 s1919 = s1913 ^ s1918;
+  const SWord8  s1920 = (SWord8) (s1897 >> 8);
+  const SWord8  s1921 = table0[s1920];
+  const SWord8  s1922 = (SWord8) (s35 >> 8);
+  const SWord8  s1923 = s1921 ^ s1922;
+  const SWord32 s1924 = table3[s1923];
+  const SWord32 s1925 = s1919 ^ s1924;
+  const SWord8  s1926 = (SWord8) s1811;
+  const SWord8  s1927 = table0[s1926];
+  const SWord8  s1928 = (SWord8) s35;
+  const SWord8  s1929 = s1927 ^ s1928;
+  const SWord32 s1930 = table4[s1929];
+  const SWord32 s1931 = s1925 ^ s1930;
+  const SWord8  s1932 = (SWord8) (s1931 >> 16);
+  const SWord8  s1933 = table0[s1932];
+  const SWord8  s1934 = (SWord8) (s36 >> 16);
+  const SWord8  s1935 = s1933 ^ s1934;
+  const SWord32 s1936 = table2[s1935];
+  const SWord32 s1937 = s1908 ^ s1936;
+  const SWord8  s1938 = (SWord8) (s1868 >> 24);
+  const SWord8  s1939 = table0[s1938];
+  const SWord8  s1940 = (SWord8) (s34 >> 24);
+  const SWord8  s1941 = s1939 ^ s1940;
+  const SWord32 s1942 = table1[s1941];
+  const SWord8  s1943 = (SWord8) (s1897 >> 16);
+  const SWord8  s1944 = table0[s1943];
+  const SWord8  s1945 = (SWord8) (s34 >> 16);
+  const SWord8  s1946 = s1944 ^ s1945;
+  const SWord32 s1947 = table2[s1946];
+  const SWord32 s1948 = s1942 ^ s1947;
+  const SWord8  s1949 = (SWord8) (s1811 >> 8);
+  const SWord8  s1950 = table0[s1949];
+  const SWord8  s1951 = (SWord8) (s34 >> 8);
+  const SWord8  s1952 = s1950 ^ s1951;
+  const SWord32 s1953 = table3[s1952];
+  const SWord32 s1954 = s1948 ^ s1953;
+  const SWord8  s1955 = (SWord8) s1839;
+  const SWord8  s1956 = table0[s1955];
+  const SWord8  s1957 = (SWord8) s34;
+  const SWord8  s1958 = s1956 ^ s1957;
+  const SWord32 s1959 = table4[s1958];
+  const SWord32 s1960 = s1954 ^ s1959;
+  const SWord8  s1961 = (SWord8) (s1960 >> 8);
+  const SWord8  s1962 = table0[s1961];
+  const SWord8  s1963 = (SWord8) (s36 >> 8);
+  const SWord8  s1964 = s1962 ^ s1963;
+  const SWord32 s1965 = table3[s1964];
+  const SWord32 s1966 = s1937 ^ s1965;
+  const SWord8  s1967 = (SWord8) (s1897 >> 24);
+  const SWord8  s1968 = table0[s1967];
+  const SWord8  s1969 = (SWord8) (s33 >> 24);
+  const SWord8  s1970 = s1968 ^ s1969;
+  const SWord32 s1971 = table1[s1970];
+  const SWord8  s1972 = (SWord8) (s1811 >> 16);
+  const SWord8  s1973 = table0[s1972];
+  const SWord8  s1974 = (SWord8) (s33 >> 16);
+  const SWord8  s1975 = s1973 ^ s1974;
+  const SWord32 s1976 = table2[s1975];
+  const SWord32 s1977 = s1971 ^ s1976;
+  const SWord8  s1978 = (SWord8) (s1839 >> 8);
+  const SWord8  s1979 = table0[s1978];
+  const SWord8  s1980 = (SWord8) (s33 >> 8);
+  const SWord8  s1981 = s1979 ^ s1980;
+  const SWord32 s1982 = table3[s1981];
+  const SWord32 s1983 = s1977 ^ s1982;
+  const SWord8  s1984 = (SWord8) s1868;
+  const SWord8  s1985 = table0[s1984];
+  const SWord8  s1986 = (SWord8) s33;
+  const SWord8  s1987 = s1985 ^ s1986;
+  const SWord32 s1988 = table4[s1987];
+  const SWord32 s1989 = s1983 ^ s1988;
+  const SWord8  s1990 = (SWord8) s1989;
+  const SWord8  s1991 = table0[s1990];
+  const SWord8  s1992 = (SWord8) s36;
+  const SWord8  s1993 = s1991 ^ s1992;
+  const SWord32 s1994 = table4[s1993];
+  const SWord32 s1995 = s1966 ^ s1994;
+  const SWord8  s1996 = (SWord8) (s1995 >> 24);
+  const SWord8  s1997 = table0[s1996];
+  const SWord8  s1998 = (SWord8) (s40 >> 24);
+  const SWord8  s1999 = s1997 ^ s1998;
+  const SWord32 s2000 = table1[s1999];
+  const SWord8  s2001 = (SWord8) (s1931 >> 24);
+  const SWord8  s2002 = table0[s2001];
+  const SWord8  s2003 = (SWord8) (s39 >> 24);
+  const SWord8  s2004 = s2002 ^ s2003;
+  const SWord32 s2005 = table1[s2004];
+  const SWord8  s2006 = (SWord8) (s1960 >> 16);
+  const SWord8  s2007 = table0[s2006];
+  const SWord8  s2008 = (SWord8) (s39 >> 16);
+  const SWord8  s2009 = s2007 ^ s2008;
+  const SWord32 s2010 = table2[s2009];
+  const SWord32 s2011 = s2005 ^ s2010;
+  const SWord8  s2012 = (SWord8) (s1989 >> 8);
+  const SWord8  s2013 = table0[s2012];
+  const SWord8  s2014 = (SWord8) (s39 >> 8);
+  const SWord8  s2015 = s2013 ^ s2014;
+  const SWord32 s2016 = table3[s2015];
+  const SWord32 s2017 = s2011 ^ s2016;
+  const SWord8  s2018 = (SWord8) s1903;
+  const SWord8  s2019 = table0[s2018];
+  const SWord8  s2020 = (SWord8) s39;
+  const SWord8  s2021 = s2019 ^ s2020;
+  const SWord32 s2022 = table4[s2021];
+  const SWord32 s2023 = s2017 ^ s2022;
+  const SWord8  s2024 = (SWord8) (s2023 >> 16);
+  const SWord8  s2025 = table0[s2024];
+  const SWord8  s2026 = (SWord8) (s40 >> 16);
+  const SWord8  s2027 = s2025 ^ s2026;
+  const SWord32 s2028 = table2[s2027];
+  const SWord32 s2029 = s2000 ^ s2028;
+  const SWord8  s2030 = (SWord8) (s1960 >> 24);
+  const SWord8  s2031 = table0[s2030];
+  const SWord8  s2032 = (SWord8) (s38 >> 24);
+  const SWord8  s2033 = s2031 ^ s2032;
+  const SWord32 s2034 = table1[s2033];
+  const SWord8  s2035 = (SWord8) (s1989 >> 16);
+  const SWord8  s2036 = table0[s2035];
+  const SWord8  s2037 = (SWord8) (s38 >> 16);
+  const SWord8  s2038 = s2036 ^ s2037;
+  const SWord32 s2039 = table2[s2038];
+  const SWord32 s2040 = s2034 ^ s2039;
+  const SWord8  s2041 = (SWord8) (s1903 >> 8);
+  const SWord8  s2042 = table0[s2041];
+  const SWord8  s2043 = (SWord8) (s38 >> 8);
+  const SWord8  s2044 = s2042 ^ s2043;
+  const SWord32 s2045 = table3[s2044];
+  const SWord32 s2046 = s2040 ^ s2045;
+  const SWord8  s2047 = (SWord8) s1931;
+  const SWord8  s2048 = table0[s2047];
+  const SWord8  s2049 = (SWord8) s38;
+  const SWord8  s2050 = s2048 ^ s2049;
+  const SWord32 s2051 = table4[s2050];
+  const SWord32 s2052 = s2046 ^ s2051;
+  const SWord8  s2053 = (SWord8) (s2052 >> 8);
+  const SWord8  s2054 = table0[s2053];
+  const SWord8  s2055 = (SWord8) (s40 >> 8);
+  const SWord8  s2056 = s2054 ^ s2055;
+  const SWord32 s2057 = table3[s2056];
+  const SWord32 s2058 = s2029 ^ s2057;
+  const SWord8  s2059 = (SWord8) (s1989 >> 24);
+  const SWord8  s2060 = table0[s2059];
+  const SWord8  s2061 = (SWord8) (s37 >> 24);
+  const SWord8  s2062 = s2060 ^ s2061;
+  const SWord32 s2063 = table1[s2062];
+  const SWord8  s2064 = (SWord8) (s1903 >> 16);
+  const SWord8  s2065 = table0[s2064];
+  const SWord8  s2066 = (SWord8) (s37 >> 16);
+  const SWord8  s2067 = s2065 ^ s2066;
+  const SWord32 s2068 = table2[s2067];
+  const SWord32 s2069 = s2063 ^ s2068;
+  const SWord8  s2070 = (SWord8) (s1931 >> 8);
+  const SWord8  s2071 = table0[s2070];
+  const SWord8  s2072 = (SWord8) (s37 >> 8);
+  const SWord8  s2073 = s2071 ^ s2072;
+  const SWord32 s2074 = table3[s2073];
+  const SWord32 s2075 = s2069 ^ s2074;
+  const SWord8  s2076 = (SWord8) s1960;
+  const SWord8  s2077 = table0[s2076];
+  const SWord8  s2078 = (SWord8) s37;
+  const SWord8  s2079 = s2077 ^ s2078;
+  const SWord32 s2080 = table4[s2079];
+  const SWord32 s2081 = s2075 ^ s2080;
+  const SWord8  s2082 = (SWord8) s2081;
+  const SWord8  s2083 = table0[s2082];
+  const SWord8  s2084 = (SWord8) s40;
+  const SWord8  s2085 = s2083 ^ s2084;
+  const SWord32 s2086 = table4[s2085];
+  const SWord32 s2087 = s2058 ^ s2086;
+  const SWord8  s2088 = (SWord8) (s2087 >> 24);
+  const SWord8  s2089 = table0[s2088];
+  const SWord8  s2090 = (SWord8) (s2023 >> 24);
+  const SWord8  s2091 = table0[s2090];
+  const SWord8  s2092 = (SWord8) (s43 >> 24);
+  const SWord8  s2093 = s2091 ^ s2092;
+  const SWord32 s2094 = table1[s2093];
+  const SWord8  s2095 = (SWord8) (s2052 >> 16);
+  const SWord8  s2096 = table0[s2095];
+  const SWord8  s2097 = (SWord8) (s43 >> 16);
+  const SWord8  s2098 = s2096 ^ s2097;
+  const SWord32 s2099 = table2[s2098];
+  const SWord32 s2100 = s2094 ^ s2099;
+  const SWord8  s2101 = (SWord8) (s2081 >> 8);
+  const SWord8  s2102 = table0[s2101];
+  const SWord8  s2103 = (SWord8) (s43 >> 8);
+  const SWord8  s2104 = s2102 ^ s2103;
+  const SWord32 s2105 = table3[s2104];
+  const SWord32 s2106 = s2100 ^ s2105;
+  const SWord8  s2107 = (SWord8) s1995;
+  const SWord8  s2108 = table0[s2107];
+  const SWord8  s2109 = (SWord8) s43;
+  const SWord8  s2110 = s2108 ^ s2109;
+  const SWord32 s2111 = table4[s2110];
+  const SWord32 s2112 = s2106 ^ s2111;
+  const SWord8  s2113 = (SWord8) (s2112 >> 16);
+  const SWord8  s2114 = table0[s2113];
+  const SWord16 s2115 = (((SWord16) s2089) << 8) | ((SWord16) s2114);
+  const SWord8  s2116 = (SWord8) (s2052 >> 24);
+  const SWord8  s2117 = table0[s2116];
+  const SWord8  s2118 = (SWord8) (s42 >> 24);
+  const SWord8  s2119 = s2117 ^ s2118;
+  const SWord32 s2120 = table1[s2119];
+  const SWord8  s2121 = (SWord8) (s2081 >> 16);
+  const SWord8  s2122 = table0[s2121];
+  const SWord8  s2123 = (SWord8) (s42 >> 16);
+  const SWord8  s2124 = s2122 ^ s2123;
+  const SWord32 s2125 = table2[s2124];
+  const SWord32 s2126 = s2120 ^ s2125;
+  const SWord8  s2127 = (SWord8) (s1995 >> 8);
+  const SWord8  s2128 = table0[s2127];
+  const SWord8  s2129 = (SWord8) (s42 >> 8);
+  const SWord8  s2130 = s2128 ^ s2129;
+  const SWord32 s2131 = table3[s2130];
+  const SWord32 s2132 = s2126 ^ s2131;
+  const SWord8  s2133 = (SWord8) s2023;
+  const SWord8  s2134 = table0[s2133];
+  const SWord8  s2135 = (SWord8) s42;
+  const SWord8  s2136 = s2134 ^ s2135;
+  const SWord32 s2137 = table4[s2136];
+  const SWord32 s2138 = s2132 ^ s2137;
+  const SWord8  s2139 = (SWord8) (s2138 >> 8);
+  const SWord8  s2140 = table0[s2139];
+  const SWord8  s2141 = (SWord8) (s2081 >> 24);
+  const SWord8  s2142 = table0[s2141];
+  const SWord8  s2143 = (SWord8) (s41 >> 24);
+  const SWord8  s2144 = s2142 ^ s2143;
+  const SWord32 s2145 = table1[s2144];
+  const SWord8  s2146 = (SWord8) (s1995 >> 16);
+  const SWord8  s2147 = table0[s2146];
+  const SWord8  s2148 = (SWord8) (s41 >> 16);
+  const SWord8  s2149 = s2147 ^ s2148;
+  const SWord32 s2150 = table2[s2149];
+  const SWord32 s2151 = s2145 ^ s2150;
+  const SWord8  s2152 = (SWord8) (s2023 >> 8);
+  const SWord8  s2153 = table0[s2152];
+  const SWord8  s2154 = (SWord8) (s41 >> 8);
+  const SWord8  s2155 = s2153 ^ s2154;
+  const SWord32 s2156 = table3[s2155];
+  const SWord32 s2157 = s2151 ^ s2156;
+  const SWord8  s2158 = (SWord8) s2052;
+  const SWord8  s2159 = table0[s2158];
+  const SWord8  s2160 = (SWord8) s41;
+  const SWord8  s2161 = s2159 ^ s2160;
+  const SWord32 s2162 = table4[s2161];
+  const SWord32 s2163 = s2157 ^ s2162;
+  const SWord8  s2164 = (SWord8) s2163;
+  const SWord8  s2165 = table0[s2164];
+  const SWord16 s2166 = (((SWord16) s2140) << 8) | ((SWord16) s2165);
+  const SWord32 s2167 = (((SWord32) s2115) << 16) | ((SWord32) s2166);
+  const SWord32 s2168 = s44 ^ s2167;
+  const SWord8  s2169 = (SWord8) (s2163 >> 24);
+  const SWord8  s2170 = table0[s2169];
+  const SWord8  s2171 = (SWord8) (s2087 >> 16);
+  const SWord8  s2172 = table0[s2171];
+  const SWord16 s2173 = (((SWord16) s2170) << 8) | ((SWord16) s2172);
+  const SWord8  s2174 = (SWord8) (s2112 >> 8);
+  const SWord8  s2175 = table0[s2174];
+  const SWord8  s2176 = (SWord8) s2138;
+  const SWord8  s2177 = table0[s2176];
+  const SWord16 s2178 = (((SWord16) s2175) << 8) | ((SWord16) s2177);
+  const SWord32 s2179 = (((SWord32) s2173) << 16) | ((SWord32) s2178);
+  const SWord32 s2180 = s45 ^ s2179;
+  const SWord8  s2181 = (SWord8) (s2138 >> 24);
+  const SWord8  s2182 = table0[s2181];
+  const SWord8  s2183 = (SWord8) (s2163 >> 16);
+  const SWord8  s2184 = table0[s2183];
+  const SWord16 s2185 = (((SWord16) s2182) << 8) | ((SWord16) s2184);
+  const SWord8  s2186 = (SWord8) (s2087 >> 8);
+  const SWord8  s2187 = table0[s2186];
+  const SWord8  s2188 = (SWord8) s2112;
+  const SWord8  s2189 = table0[s2188];
+  const SWord16 s2190 = (((SWord16) s2187) << 8) | ((SWord16) s2189);
+  const SWord32 s2191 = (((SWord32) s2185) << 16) | ((SWord32) s2190);
+  const SWord32 s2192 = s46 ^ s2191;
+  const SWord8  s2193 = (SWord8) (s2112 >> 24);
+  const SWord8  s2194 = table0[s2193];
+  const SWord8  s2195 = (SWord8) (s2138 >> 16);
+  const SWord8  s2196 = table0[s2195];
+  const SWord16 s2197 = (((SWord16) s2194) << 8) | ((SWord16) s2196);
+  const SWord8  s2198 = (SWord8) (s2163 >> 8);
+  const SWord8  s2199 = table0[s2198];
+  const SWord8  s2200 = (SWord8) s2087;
+  const SWord8  s2201 = table0[s2200];
+  const SWord16 s2202 = (((SWord16) s2199) << 8) | ((SWord16) s2201);
+  const SWord32 s2203 = (((SWord32) s2197) << 16) | ((SWord32) s2202);
+  const SWord32 s2204 = s47 ^ s2203;
+
+  pt[0] = s2168;
+  pt[1] = s2180;
+  pt[2] = s2192;
+  pt[3] = s2204;
+}
+== END: "aes128OTFDecrypt.c" ==================
+== BEGIN: "aes128Lib.h" ================
+/* Header file for aes128Lib. Automatically generated by SBV. Do not edit! */
+
+#ifndef __aes128Lib__HEADER_INCLUDED__
+#define __aes128Lib__HEADER_INCLUDED__
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include <math.h>
+
+/* The boolean type */
+typedef bool SBool;
+
+/* The float type */
+typedef float SFloat;
+
+/* The double type */
+typedef double SDouble;
+
+/* Unsigned bit-vectors */
+typedef uint8_t  SWord8;
+typedef uint16_t SWord16;
+typedef uint32_t SWord32;
+typedef uint64_t SWord64;
+
+/* Signed bit-vectors */
+typedef int8_t  SInt8;
+typedef int16_t SInt16;
+typedef int32_t SInt32;
+typedef int64_t SInt64;
+
+/* Entry point prototypes: */
+void aes128KeySchedule(const SWord32 *key, SWord32 *encKS,
+                       SWord32 *decKS);
+void aes128BlockEncrypt(const SWord32 *pt, const SWord32 *xkey,
+                        SWord32 *ct);
+void aes128BlockDecrypt(const SWord32 *ct, const SWord32 *xkey,
+                        SWord32 *pt);
+void aes128InvKeySchedule(const SWord32 *key, SWord32 *decKS);
+void aes128OTFDecrypt(const SWord32 *ct, const SWord32 *xkey,
+                      SWord32 *pt);
+
+#endif /* __aes128Lib__HEADER_INCLUDED__ */
+== END: "aes128Lib.h" ==================
+== BEGIN: "aes128Lib_driver.c" ================
+/* Example driver program for aes128Lib. */
+/* Automatically generated by SBV. Edit as you see fit! */
+
+#include <stdio.h>
+#include "aes128Lib.h"
+
+void aes128KeySchedule_driver(void)
+{
+  const SWord32 key[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array key:\n");
+  int key_ctr;
+  for(key_ctr = 0; key_ctr < 4 ; ++key_ctr)
+    printf("  key[%1d] = 0x%08"PRIx32"UL\n", key_ctr ,key[key_ctr]);
+
+  SWord32 encKS[44];
+  SWord32 decKS[44];
+
+  aes128KeySchedule(key, encKS, decKS);
+
+  printf("aes128KeySchedule(key, encKS, decKS) ->\n");
+  int encKS_ctr;
+  for(encKS_ctr = 0; encKS_ctr < 44 ; ++encKS_ctr)
+    printf("  encKS[%2d] = 0x%08"PRIx32"UL\n", encKS_ctr ,encKS[encKS_ctr]);
+  int decKS_ctr;
+  for(decKS_ctr = 0; decKS_ctr < 44 ; ++decKS_ctr)
+    printf("  decKS[%2d] = 0x%08"PRIx32"UL\n", decKS_ctr ,decKS[decKS_ctr]);
+}
+
+void aes128BlockEncrypt_driver(void)
+{
+  const SWord32 pt[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array pt:\n");
+  int pt_ctr;
+  for(pt_ctr = 0; pt_ctr < 4 ; ++pt_ctr)
+    printf("  pt[%1d] = 0x%08"PRIx32"UL\n", pt_ctr ,pt[pt_ctr]);
+
+  const SWord32 xkey[44] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array xkey:\n");
+  int xkey_ctr;
+  for(xkey_ctr = 0; xkey_ctr < 44 ; ++xkey_ctr)
+    printf("  xkey[%2d] = 0x%08"PRIx32"UL\n", xkey_ctr ,xkey[xkey_ctr]);
+
+  SWord32 ct[4];
+
+  aes128BlockEncrypt(pt, xkey, ct);
+
+  printf("aes128BlockEncrypt(pt, xkey, ct) ->\n");
+  int ct_ctr;
+  for(ct_ctr = 0; ct_ctr < 4 ; ++ct_ctr)
+    printf("  ct[%1d] = 0x%08"PRIx32"UL\n", ct_ctr ,ct[ct_ctr]);
+}
+
+void aes128BlockDecrypt_driver(void)
+{
+  const SWord32 ct[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array ct:\n");
+  int ct_ctr;
+  for(ct_ctr = 0; ct_ctr < 4 ; ++ct_ctr)
+    printf("  ct[%1d] = 0x%08"PRIx32"UL\n", ct_ctr ,ct[ct_ctr]);
+
+  const SWord32 xkey[44] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array xkey:\n");
+  int xkey_ctr;
+  for(xkey_ctr = 0; xkey_ctr < 44 ; ++xkey_ctr)
+    printf("  xkey[%2d] = 0x%08"PRIx32"UL\n", xkey_ctr ,xkey[xkey_ctr]);
+
+  SWord32 pt[4];
+
+  aes128BlockDecrypt(ct, xkey, pt);
+
+  printf("aes128BlockDecrypt(ct, xkey, pt) ->\n");
+  int pt_ctr;
+  for(pt_ctr = 0; pt_ctr < 4 ; ++pt_ctr)
+    printf("  pt[%1d] = 0x%08"PRIx32"UL\n", pt_ctr ,pt[pt_ctr]);
+}
+
+void aes128InvKeySchedule_driver(void)
+{
+  const SWord32 key[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array key:\n");
+  int key_ctr;
+  for(key_ctr = 0; key_ctr < 4 ; ++key_ctr)
+    printf("  key[%1d] = 0x%08"PRIx32"UL\n", key_ctr ,key[key_ctr]);
+
+  SWord32 decKS[44];
+
+  aes128InvKeySchedule(key, decKS);
+
+  printf("aes128InvKeySchedule(key, decKS) ->\n");
+  int decKS_ctr;
+  for(decKS_ctr = 0; decKS_ctr < 44 ; ++decKS_ctr)
+    printf("  decKS[%2d] = 0x%08"PRIx32"UL\n", decKS_ctr ,decKS[decKS_ctr]);
+}
+
+void aes128OTFDecrypt_driver(void)
+{
+  const SWord32 ct[4] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array ct:\n");
+  int ct_ctr;
+  for(ct_ctr = 0; ct_ctr < 4 ; ++ct_ctr)
+    printf("  ct[%1d] = 0x%08"PRIx32"UL\n", ct_ctr ,ct[ct_ctr]);
+
+  const SWord32 xkey[44] = {
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL,
+      0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL
+  };
+
+  printf("Contents of input array xkey:\n");
+  int xkey_ctr;
+  for(xkey_ctr = 0; xkey_ctr < 44 ; ++xkey_ctr)
+    printf("  xkey[%2d] = 0x%08"PRIx32"UL\n", xkey_ctr ,xkey[xkey_ctr]);
+
+  SWord32 pt[4];
+
+  aes128OTFDecrypt(ct, xkey, pt);
+
+  printf("aes128OTFDecrypt(ct, xkey, pt) ->\n");
+  int pt_ctr;
+  for(pt_ctr = 0; pt_ctr < 4 ; ++pt_ctr)
+    printf("  pt[%1d] = 0x%08"PRIx32"UL\n", pt_ctr ,pt[pt_ctr]);
+}
+
+int main(void)
+{
+  printf("====================================\n");
+  printf("** Driver run for aes128KeySchedule:\n");
+  printf("====================================\n");
+  aes128KeySchedule_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for aes128BlockEncrypt:\n");
+  printf("=====================================\n");
+  aes128BlockEncrypt_driver();
+
+  printf("=====================================\n");
+  printf("** Driver run for aes128BlockDecrypt:\n");
+  printf("=====================================\n");
+  aes128BlockDecrypt_driver();
+
+  printf("=======================================\n");
+  printf("** Driver run for aes128InvKeySchedule:\n");
+  printf("=======================================\n");
+  aes128InvKeySchedule_driver();
+
+  printf("===================================\n");
+  printf("** Driver run for aes128OTFDecrypt:\n");
+  printf("===================================\n");
+  aes128OTFDecrypt_driver();
+
+  return 0;
+}
+== END: "aes128Lib_driver.c" ==================
+== BEGIN: "Makefile" ================
+# Makefile for aes128Lib. Automatically generated by SBV. Do not edit!
+
+# include any user-defined .mk file in the current directory.
+-include *.mk
+
+CC?=gcc
+CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer
+AR?=ar
+ARFLAGS?=cr
+
+all: aes128Lib.a aes128Lib_driver
+
+aes128Lib.a: aes128KeySchedule.o aes128BlockEncrypt.o aes128BlockDecrypt.o aes128InvKeySchedule.o aes128OTFDecrypt.o
+	${AR} ${ARFLAGS} $@ $^
+
+aes128Lib_driver: aes128Lib_driver.c aes128Lib.h
+	${CC} ${CCFLAGS} $< -o $@ aes128Lib.a
+
+aes128KeySchedule.o: aes128KeySchedule.c aes128Lib.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+aes128BlockEncrypt.o: aes128BlockEncrypt.c aes128Lib.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+aes128BlockDecrypt.o: aes128BlockDecrypt.c aes128Lib.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+aes128InvKeySchedule.o: aes128InvKeySchedule.c aes128Lib.h
+	${CC} ${CCFLAGS} -c $< -o $@
+
+aes128OTFDecrypt.o: aes128OTFDecrypt.c aes128Lib.h
 	${CC} ${CCFLAGS} -c $< -o $@
 
 clean:
diff --git a/SBVTestSuite/GoldFiles/allSat8.gold b/SBVTestSuite/GoldFiles/allSat8.gold
--- a/SBVTestSuite/GoldFiles/allSat8.gold
+++ b/SBVTestSuite/GoldFiles/allSat8.gold
@@ -61,4 +61,4 @@
 *** NB. If this is a use case you'd like SBV to support, please get in touch!
 
 CallStack (from HasCallStack):
-  error, called at ./Data/SBV/Control/Utils.hs:1464:57 in sbv-10.0-inplace:Data.SBV.Control.Utils
+  error, called at ./Data/SBV/Control/Utils.hs:1469:57 in sbv-10.2-inplace:Data.SBV.Control.Utils
diff --git a/SBVTestSuite/GoldFiles/charConstr01.gold b/SBVTestSuite/GoldFiles/charConstr01.gold
--- a/SBVTestSuite/GoldFiles/charConstr01.gold
+++ b/SBVTestSuite/GoldFiles/charConstr01.gold
@@ -37,7 +37,7 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (cf))
-[RECV] ((cf ((as const Array) "B")))
+[RECV] ((cf ((as const (Array Int String)) "B")))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [], modelUIFuns = [("cf",(SInteger -> SChar,Right ([],'B' :: Char)))]}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/charConstr02.gold b/SBVTestSuite/GoldFiles/charConstr02.gold
--- a/SBVTestSuite/GoldFiles/charConstr02.gold
+++ b/SBVTestSuite/GoldFiles/charConstr02.gold
@@ -47,7 +47,8 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (cf3))
-[RECV] ((cf3 ((as const Array) (mkSBVTuple3 "A" "A" "A"))))
+[RECV] ((cf3 ((as const (Array Int (SBVTuple3 String String String)))
+         (mkSBVTuple3 "A" "A" "A"))))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [], modelUIFuns = [("cf3",(SInteger -> (SChar, SChar, SChar),Right ([],('A','A','A') :: (Char, Char, Char))))]}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/charConstr11.gold b/SBVTestSuite/GoldFiles/charConstr11.gold
--- a/SBVTestSuite/GoldFiles/charConstr11.gold
+++ b/SBVTestSuite/GoldFiles/charConstr11.gold
@@ -50,7 +50,9 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (cf4))
-[RECV] ((cf4 ((as const Array) (seq.unit (mkSBVTuple2 (mkSBVTuple2 "A" "A") (seq.unit 2))))))
+[RECV] ((cf4 ((as const
+            (Array Int String (Seq (SBVTuple2 (SBVTuple2 String String) (Seq Int)))))
+         (seq.unit (mkSBVTuple2 (mkSBVTuple2 "A" "A") (seq.unit 2))))))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [("x",3 :: Integer),("c",'A' :: Char)], modelUIFuns = [("cf4",(SInteger -> SChar -> [((SChar, SChar), [SInteger])],Right ([],[(('A','A'),[2])] :: [((Char, Char), [Integer])])))]}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/lambda63.gold b/SBVTestSuite/GoldFiles/lambda63.gold
--- a/SBVTestSuite/GoldFiles/lambda63.gold
+++ b/SBVTestSuite/GoldFiles/lambda63.gold
@@ -31,7 +31,7 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (R))
-[RECV] ((R ((as const Array) false)))
+[RECV] ((R ((as const (Array Int Int Bool)) false)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
diff --git a/SBVTestSuite/GoldFiles/lambda70.gold b/SBVTestSuite/GoldFiles/lambda70.gold
--- a/SBVTestSuite/GoldFiles/lambda70.gold
+++ b/SBVTestSuite/GoldFiles/lambda70.gold
@@ -50,9 +50,9 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (x_eu1))
-[RECV] ((x_eu1 ((as const Array) 0)))
+[RECV] ((x_eu1 ((as const (Array Int Int)) 0)))
 [SEND] (get-value (x_eu2))
-[RECV] ((x_eu2 ((as const Array) 1)))
+[RECV] ((x_eu2 ((as const (Array Int Int)) 1)))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
diff --git a/SBVTestSuite/GoldFiles/query1.gold b/SBVTestSuite/GoldFiles/query1.gold
--- a/SBVTestSuite/GoldFiles/query1.gold
+++ b/SBVTestSuite/GoldFiles/query1.gold
@@ -77,7 +77,7 @@
 [SEND] (get-info :reason-unknown)
 [RECV] (:reason-unknown "state of the most recent check-sat command is not known")
 [SEND] (get-info :version)
-[RECV] (:version "4.12.2")
+[RECV] (:version "4.12.3")
 [SEND] (get-info :status)
 [RECV] (:status sat)
 [GOOD] (define-fun s16 () Int 4)
@@ -108,7 +108,7 @@
 [SEND] (get-info :reason-unknown)
 [RECV] (:reason-unknown "unknown")
 [SEND] (get-info :version)
-[RECV] (:version "4.12.2")
+[RECV] (:version "4.12.3")
 [SEND] (get-info :memory)
 [RECV] unsupported
 [SEND] (get-info :time)
diff --git a/SBVTestSuite/GoldFiles/query_uiSat_test2.gold b/SBVTestSuite/GoldFiles/query_uiSat_test2.gold
--- a/SBVTestSuite/GoldFiles/query_uiSat_test2.gold
+++ b/SBVTestSuite/GoldFiles/query_uiSat_test2.gold
@@ -35,7 +35,10 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true true true) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true true true)
+              true
+              false
+              true)))
 
 MODEL: SMTModel {modelObjectives = [], modelBindings = Nothing, modelAssocs = [], modelUIFuns = [("q2",(SBool -> SBool -> SBool,Right ([([True :: Bool,False :: Bool],True :: Bool),([True :: Bool,True :: Bool],True :: Bool)],False :: Bool)))]}
 DONE.*** Solver   : Z3
diff --git a/SBVTestSuite/GoldFiles/query_uisatex1.gold b/SBVTestSuite/GoldFiles/query_uisatex1.gold
--- a/SBVTestSuite/GoldFiles/query_uisatex1.gold
+++ b/SBVTestSuite/GoldFiles/query_uisatex1.gold
@@ -122,11 +122,16 @@
 [GOOD] (set-option :pp.min_alias_size 4294967295)
 [GOOD] (set-option :model.inline_def  true      )
 [SEND] (get-value (q1))
-[RECV] ((q1 (store (store (store ((as const Array) 12) 3 75) (- 3) 9) 0 1)))
+[RECV] ((q1 (store (store (store ((as const (Array Int Int)) 12) 3 75) (- 3) 9) 0 1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) 5) false 7 6) false 12 3)))
+[RECV] ((q2 (store (store ((as const (Array Bool Int Int)) 5) false 7 6) false 12 3)))
 [SEND] (get-value (q3))
-[RECV] ((q3 (store (store ((as const Array) (fp #b0 #x82 #b00010011001100110011010))
+[RECV] ((q3 (store (store ((as const
+                          (Array (_ FloatingPoint 8 24)
+                                 Bool
+                                 Int
+                                 (_ FloatingPoint 8 24)))
+                       (fp #b0 #x82 #b00010011001100110011010))
                      (fp #b0 #x82 #b00110011001100110011010)
                      true
                      121
@@ -136,7 +141,8 @@
               8
               (_ +oo 8 24))))
 [SEND] (get-value (q4))
-[RECV] ((q4 (store (store ((as const Array) (fp #b0 #x85 #b00111000000000000000000))
+[RECV] ((q4 (store (store ((as const (Array String String (_ FloatingPoint 8 24)))
+                       (fp #b0 #x85 #b00111000000000000000000))
                      "c"
                      "tey"
                      (fp #b0 #x85 #b01110000000000000000000))
@@ -144,7 +150,7 @@
               "foo"
               (fp #b0 #x80 #b11000000000000000000000))))
 [SEND] (get-value (q5))
-[RECV] ((q5 (store (store ((as const Array) 7)
+[RECV] ((q5 (store (store ((as const (Array (Seq Int) (Seq (_ FloatingPoint 8 24)) Int)) 7)
                      (seq.++ (seq.unit 9) (seq.unit 5))
                      (seq.++ (seq.unit (fp #b0 #x82 #b00000110011001100110011))
                              (seq.unit (fp #b0 #x82 #b00100000000000000000000)))
diff --git a/SBVTestSuite/GoldFiles/query_uisatex2.gold b/SBVTestSuite/GoldFiles/query_uisatex2.gold
--- a/SBVTestSuite/GoldFiles/query_uisatex2.gold
+++ b/SBVTestSuite/GoldFiles/query_uisatex2.gold
@@ -119,11 +119,16 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store (store (store ((as const Array) 12) 3 75) (- 3) 9) 0 1)))
+[RECV] ((q1 (store (store (store ((as const (Array Int Int)) 12) 3 75) (- 3) 9) 0 1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) 5) false 7 6) false 12 3)))
+[RECV] ((q2 (store (store ((as const (Array Bool Int Int)) 5) false 7 6) false 12 3)))
 [SEND] (get-value (q3))
-[RECV] ((q3 (store (store ((as const Array) (fp #b0 #x82 #b00010011001100110011010))
+[RECV] ((q3 (store (store ((as const
+                          (Array (_ FloatingPoint 8 24)
+                                 Bool
+                                 Int
+                                 (_ FloatingPoint 8 24)))
+                       (fp #b0 #x82 #b00010011001100110011010))
                      (fp #b0 #x82 #b00110011001100110011010)
                      true
                      121
@@ -133,7 +138,8 @@
               8
               (_ +oo 8 24))))
 [SEND] (get-value (q4))
-[RECV] ((q4 (store (store ((as const Array) (fp #b0 #x85 #b00111000000000000000000))
+[RECV] ((q4 (store (store ((as const (Array String String (_ FloatingPoint 8 24)))
+                       (fp #b0 #x85 #b00111000000000000000000))
                      "c"
                      "tey"
                      (fp #b0 #x85 #b01110000000000000000000))
@@ -141,7 +147,7 @@
               "foo"
               (fp #b0 #x80 #b11000000000000000000000))))
 [SEND] (get-value (q5))
-[RECV] ((q5 (store (store ((as const Array) 7)
+[RECV] ((q5 (store (store ((as const (Array (Seq Int) (Seq (_ FloatingPoint 8 24)) Int)) 7)
                      (seq.++ (seq.unit 9) (seq.unit 5))
                      (seq.++ (seq.unit (fp #b0 #x82 #b00000110011001100110011))
                              (seq.unit (fp #b0 #x82 #b00100000000000000000000)))
diff --git a/SBVTestSuite/GoldFiles/set_tupleSet.gold b/SBVTestSuite/GoldFiles/set_tupleSet.gold
--- a/SBVTestSuite/GoldFiles/set_tupleSet.gold
+++ b/SBVTestSuite/GoldFiles/set_tupleSet.gold
@@ -34,12 +34,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (mkSBVTuple2 (lambda ((x!1 Bool)) x!1)
+[RECV] ((s0 (mkSBVTuple2 ((as const (Array Bool Bool)) true)
                     (store ((as const (Array Bool Bool)) false) false true))))
 *** Solver   : Z3
 *** Exit code: ExitSuccess
 
 FINAL:
 Satisfiable. Model:
-  s0 = ({True},{False}) :: ({Bool}, {Bool})
+  s0 = (U,{False}) :: ({Bool}, {Bool})
 DONE!
diff --git a/SBVTestSuite/GoldFiles/set_uninterp1.gold b/SBVTestSuite/GoldFiles/set_uninterp1.gold
--- a/SBVTestSuite/GoldFiles/set_uninterp1.gold
+++ b/SBVTestSuite/GoldFiles/set_uninterp1.gold
@@ -64,9 +64,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store ((as const (Array E Bool)) true) A false)))
+[RECV] ((s0 (store ((as const (Array E Bool)) false) C true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s10 () (Array E Bool) (store ((as const (Array E Bool)) true) A false))
+[GOOD] (define-fun s10 () (Array E Bool) (store ((as const (Array E Bool)) false) C true))
 [GOOD] (define-fun s11 () Bool (= s0 s10))
 [GOOD] (define-fun s12 () Bool (not s11))
 [GOOD] (assert s12)
@@ -74,9 +74,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store ((as const (Array E Bool)) false) C true)))
+[RECV] ((s0 (store (store ((as const (Array E Bool)) false) C true) A true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s13 () (Array E Bool) (store ((as const (Array E Bool)) false) C true))
+[GOOD] (define-fun s13 () (Array E Bool) (store (store ((as const (Array E Bool)) false) C true) A true))
 [GOOD] (define-fun s14 () Bool (= s0 s13))
 [GOOD] (define-fun s15 () Bool (not s14))
 [GOOD] (assert s15)
@@ -84,9 +84,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store (store ((as const (Array E Bool)) false) B true) A true)))
+[RECV] ((s0 ((as const (Array E Bool)) true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s16 () (Array E Bool) (store (store ((as const (Array E Bool)) false) B true) A true))
+[GOOD] (define-fun s16 () (Array E Bool) ((as const (Array E Bool)) true))
 [GOOD] (define-fun s17 () Bool (= s0 s16))
 [GOOD] (define-fun s18 () Bool (not s17))
 [GOOD] (assert s18)
@@ -94,9 +94,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 (store (store ((as const (Array E Bool)) false) C true) A true)))
+[RECV] ((s0 (store (store ((as const (Array E Bool)) false) B true) A true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s19 () (Array E Bool) (store (store ((as const (Array E Bool)) false) C true) A true))
+[GOOD] (define-fun s19 () (Array E Bool) (store (store ((as const (Array E Bool)) false) B true) A true))
 [GOOD] (define-fun s20 () Bool (= s0 s19))
 [GOOD] (define-fun s21 () Bool (not s20))
 [GOOD] (assert s21)
@@ -104,9 +104,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (s0))
-[RECV] ((s0 ((as const (Array E Bool)) true)))
+[RECV] ((s0 (store (store ((as const (Array E Bool)) false) B true) C true)))
 [GOOD] (push 1)
-[GOOD] (define-fun s22 () (Array E Bool) ((as const (Array E Bool)) true))
+[GOOD] (define-fun s22 () (Array E Bool) (store (store ((as const (Array E Bool)) false) C true) B true))
 [GOOD] (define-fun s23 () Bool (= s0 s22))
 [GOOD] (define-fun s24 () Bool (not s23))
 [GOOD] (assert s24)
@@ -126,15 +126,15 @@
 
 FINAL:
 Solution #1:
-  s0 = U :: {E}
+  s0 = {B,C} :: {E}
 Solution #2:
-  s0 = {A,C} :: {E}
-Solution #3:
   s0 = {A,B} :: {E}
+Solution #3:
+  s0 = U :: {E}
 Solution #4:
-  s0 = {C} :: {E}
+  s0 = {A,C} :: {E}
 Solution #5:
-  s0 = U - {A} :: {E}
+  s0 = {C} :: {E}
 Solution #6:
   s0 = {B} :: {E}
 Solution #7:
diff --git a/SBVTestSuite/GoldFiles/uiSat_test1.gold b/SBVTestSuite/GoldFiles/uiSat_test1.gold
--- a/SBVTestSuite/GoldFiles/uiSat_test1.gold
+++ b/SBVTestSuite/GoldFiles/uiSat_test1.gold
@@ -45,7 +45,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [GOOD] (define-fun q1_model2 ((x!0 Bool)) Bool
           true
        )
@@ -59,7 +59,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [GOOD] (define-fun q1_model3 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) false
           true)
diff --git a/SBVTestSuite/GoldFiles/uiSat_test2.gold b/SBVTestSuite/GoldFiles/uiSat_test2.gold
--- a/SBVTestSuite/GoldFiles/uiSat_test2.gold
+++ b/SBVTestSuite/GoldFiles/uiSat_test2.gold
@@ -45,7 +45,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) true)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q2_model2 ((x!0 Bool) (x!1 Bool)) Bool
           true
        )
@@ -59,7 +59,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q2_model3 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 false) (= x!1 false)) false
           true)
@@ -74,7 +74,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q2_model4 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 false) (= x!1 true)) true
           false)
@@ -89,11 +89,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false true true) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q2_model5 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 true)) true
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false))
+          false)
        )
 [GOOD] (define-fun q2_model5_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -105,10 +104,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true true true)
+              false
+              true
+              true)))
 [GOOD] (define-fun q2_model6 ((x!0 Bool) (x!1 Bool)) Bool
+          (ite (and (= x!0 false) (= x!1 true)) true
           (ite (and (= x!0 true) (= x!1 true)) true
-          false)
+          false))
        )
 [GOOD] (define-fun q2_model6_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -120,10 +123,13 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true true true) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
+              true
+              false
+              true)))
 [GOOD] (define-fun q2_model7 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 false)) true
-          (ite (and (= x!0 true) (= x!1 true)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
           false))
        )
 [GOOD] (define-fun q2_model7_reject () Bool
@@ -136,11 +142,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false true true) true false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q2_model8 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 false)) true
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false))
+          false)
        )
 [GOOD] (define-fun q2_model8_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -152,10 +157,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q2_model9 ((x!0 Bool) (x!1 Bool)) Bool
+          (ite (and (= x!0 true) (= x!1 true)) true
           (ite (and (= x!0 true) (= x!1 false)) true
-          false)
+          false))
        )
 [GOOD] (define-fun q2_model9_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -167,11 +176,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false true false) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q2_model10 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true))
+          (ite (and (= x!0 false) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model10_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -183,10 +191,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q2_model11 ((x!0 Bool) (x!1 Bool)) Bool
+          (ite (and (= x!0 true) (= x!1 true)) true
           (ite (and (= x!0 false) (= x!1 false)) true
-          false)
+          false))
        )
 [GOOD] (define-fun q2_model11_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -198,10 +210,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q2_model12 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model12_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -213,11 +229,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false true false) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q2_model13 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true))
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model13_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -229,10 +244,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q2_model14 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model14_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -244,11 +263,10 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) true true false) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q2_model15 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
-          (ite (and (= x!0 true) (= x!1 true)) false
-          true))
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model15_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -260,9 +278,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q2_model16 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 true) (= x!1 true)) false
           true)
        )
 [GOOD] (define-fun q2_model16_reject () Bool
@@ -279,58 +297,58 @@
 
 RESULT: Solution #1:
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True 
+  q2 True True = False
+  q2 _    _    = True 
 Solution #2:
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 True True  = False
-  q2 _    _     = True 
+  q2 False True = False
+  q2 _     _    = True 
 Solution #3:
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True 
-Solution #4:
-  q2 :: Bool -> Bool -> Bool
   q2 True  True = False
   q2 False True = False
   q2 _     _    = True 
+Solution #4:
+  q2 :: Bool -> Bool -> Bool
+  q2 True False = False
+  q2 _    _     = True 
 Solution #5:
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True 
+  q2 True True  = False
+  q2 True False = False
+  q2 _    _     = True 
 Solution #6:
   q2 :: Bool -> Bool -> Bool
+  q2 True  True  = True 
   q2 False False = True 
   q2 _     _     = False
 Solution #7:
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = False
-  q2 False True  = False
-  q2 _     _     = True 
+  q2 False False = True 
+  q2 _     _     = False
 Solution #8:
   q2 :: Bool -> Bool -> Bool
+  q2 True True  = True 
   q2 True False = True 
   q2 _    _     = False
 Solution #9:
   q2 :: Bool -> Bool -> Bool
+  q2 True False = True 
+  q2 _    _     = False
+Solution #10:
+  q2 :: Bool -> Bool -> Bool
   q2 True  False = True 
   q2 False True  = True 
   q2 _     _     = False
-Solution #10:
-  q2 :: Bool -> Bool -> Bool
-  q2 True False = True 
-  q2 True True  = True 
-  q2 _    _     = False
 Solution #11:
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True 
-  q2 _    _    = False
-Solution #12:
-  q2 :: Bool -> Bool -> Bool
-  q2 True  True = True 
   q2 False True = True 
+  q2 True  True = True 
   q2 _     _    = False
+Solution #12:
+  q2 :: Bool -> Bool -> Bool
+  q2 True True = True 
+  q2 _    _    = False
 Solution #13:
   q2 :: Bool -> Bool -> Bool
   q2 False True = True 
diff --git a/SBVTestSuite/GoldFiles/uiSat_test3.gold b/SBVTestSuite/GoldFiles/uiSat_test3.gold
--- a/SBVTestSuite/GoldFiles/uiSat_test3.gold
+++ b/SBVTestSuite/GoldFiles/uiSat_test3.gold
@@ -59,7 +59,7 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
 [RECV] ((q2 (_ as-array q2)))
 [GOOD] (define-fun q1_model2 ((x!0 Bool)) Bool
@@ -85,9 +85,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) true)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model3 ((x!0 Bool)) Bool
           false
        )
@@ -111,9 +111,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model4 ((x!0 Bool)) Bool
           false
        )
@@ -138,9 +138,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model5 ((x!0 Bool)) Bool
           false
        )
@@ -165,9 +165,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false false true) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q1_model6 ((x!0 Bool)) Bool
           false
        )
@@ -195,7 +198,10 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false false true) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q1_model7 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -224,7 +230,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model8 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -250,21 +256,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false false true) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model9 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model9_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1        x!0)
                             (q1_model9 x!0))))
 [GOOD] (define-fun q2_model9 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
-          (ite (and (= x!0 false) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model9_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -279,20 +288,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false false true) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model10 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model10_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model10 x!0))))
 [GOOD] (define-fun q2_model10 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
-          (ite (and (= x!0 false) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model10_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -307,19 +319,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model11 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 false)) true
+          false)
        )
 [GOOD] (define-fun q1_model11_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model11 x!0))))
 [GOOD] (define-fun q2_model11 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model11_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -334,20 +351,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true false false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model12 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model12_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model12 x!0))))
 [GOOD] (define-fun q2_model12 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model12_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -362,19 +382,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) false) false true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model13 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model13_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model13 x!0))))
 [GOOD] (define-fun q2_model13 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
           true)
        )
 [GOOD] (define-fun q2_model13_reject () Bool
@@ -390,9 +410,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true false false)))
 [GOOD] (define-fun q1_model14 ((x!0 Bool)) Bool
           true
        )
@@ -401,7 +421,7 @@
                   (distinct (q1         x!0)
                             (q1_model14 x!0))))
 [GOOD] (define-fun q2_model14 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
           true)
        )
 [GOOD] (define-fun q2_model14_reject () Bool
@@ -417,12 +437,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model15 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model15_reject () Bool
           (exists ((x!0 Bool))
@@ -445,19 +465,22 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false false true) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q1_model16 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model16_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model16 x!0))))
 [GOOD] (define-fun q2_model16 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) true
+          (ite (and (= x!0 true) (= x!1 true)) true
           (ite (and (= x!0 false) (= x!1 false)) true
           false))
        )
@@ -474,20 +497,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false true false) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model17 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model17_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model17 x!0))))
 [GOOD] (define-fun q2_model17 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
-          (ite (and (= x!0 false) (= x!1 true)) false
-          true))
+          (ite (and (= x!0 false) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model17_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -502,12 +525,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false false true)))
 [GOOD] (define-fun q1_model18 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          true
        )
 [GOOD] (define-fun q1_model18_reject () Bool
           (exists ((x!0 Bool))
@@ -530,19 +552,21 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false false true) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q1_model19 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model19_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model19 x!0))))
 [GOOD] (define-fun q2_model19 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) true
+          (ite (and (= x!0 true) (= x!1 true)) true
           (ite (and (= x!0 false) (= x!1 false)) true
           false))
        )
@@ -559,19 +583,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              false
+              true)))
 [GOOD] (define-fun q1_model20 ((x!0 Bool)) Bool
-          false
+          true
        )
 [GOOD] (define-fun q1_model20_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model20 x!0))))
 [GOOD] (define-fun q2_model20 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 false)) true
+          (ite (and (= x!0 false) (= x!1 false)) true
+          false))
        )
 [GOOD] (define-fun q2_model20_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -586,19 +614,18 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model21 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model21_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model21 x!0))))
 [GOOD] (define-fun q2_model21 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 true)) false
           true)
        )
 [GOOD] (define-fun q2_model21_reject () Bool
@@ -614,11 +641,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) false) false true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false false true)
+              true
+              false
+              true)))
 [GOOD] (define-fun q1_model22 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
+          (ite (and (= x!0 true)) true
           false)
        )
 [GOOD] (define-fun q1_model22_reject () Bool
@@ -626,7 +656,9 @@
                   (distinct (q1         x!0)
                             (q1_model22 x!0))))
 [GOOD] (define-fun q2_model22 ((x!0 Bool) (x!1 Bool)) Bool
-          true
+          (ite (and (= x!0 true) (= x!1 false)) true
+          (ite (and (= x!0 false) (= x!1 false)) true
+          false))
        )
 [GOOD] (define-fun q2_model22_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -643,7 +675,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model23 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -653,7 +685,8 @@
                   (distinct (q1         x!0)
                             (q1_model23 x!0))))
 [GOOD] (define-fun q2_model23 ((x!0 Bool) (x!1 Bool)) Bool
-          true
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model23_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -670,7 +703,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model24 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -696,21 +729,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) true true false) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model25 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model25_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model25 x!0))))
 [GOOD] (define-fun q2_model25 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
           (ite (and (= x!0 true) (= x!1 true)) false
-          true))
+          true)
        )
 [GOOD] (define-fun q2_model25_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -727,7 +758,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false false false)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model26 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -737,8 +768,7 @@
                   (distinct (q1         x!0)
                             (q1_model26 x!0))))
 [GOOD] (define-fun q2_model26 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true)
+          true
        )
 [GOOD] (define-fun q2_model26_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -753,21 +783,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false false false) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model27 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model27_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model27 x!0))))
 [GOOD] (define-fun q2_model27 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true))
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model27_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -782,19 +811,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) false)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model28 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model28_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model28 x!0))))
 [GOOD] (define-fun q2_model28 ((x!0 Bool) (x!1 Bool)) Bool
-          false
+          true
        )
 [GOOD] (define-fun q2_model28_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -809,20 +838,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) true true false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model29 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model29_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model29 x!0))))
 [GOOD] (define-fun q2_model29 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model29_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -837,12 +870,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model30 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model30_reject () Bool
           (exists ((x!0 Bool))
@@ -865,9 +898,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model31 ((x!0 Bool)) Bool
           false
        )
@@ -876,8 +909,8 @@
                   (distinct (q1         x!0)
                             (q1_model31 x!0))))
 [GOOD] (define-fun q2_model31 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model31_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -892,18 +925,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model32 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model32_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model32 x!0))))
 [GOOD] (define-fun q2_model32 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
           false)
        )
 [GOOD] (define-fun q2_model32_reject () Bool
@@ -919,9 +953,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false false false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false true false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model33 ((x!0 Bool)) Bool
           false
        )
@@ -930,8 +967,9 @@
                   (distinct (q1         x!0)
                             (q1_model33 x!0))))
 [GOOD] (define-fun q2_model33 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true))
        )
 [GOOD] (define-fun q2_model33_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -946,20 +984,18 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false true true)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) true)))
 [GOOD] (define-fun q1_model34 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q1_model34_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model34 x!0))))
 [GOOD] (define-fun q2_model34 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false)
+          true
        )
 [GOOD] (define-fun q2_model34_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -976,7 +1012,7 @@
 [SEND] (get-value (q1))
 [RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) false true true)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) false)))
 [GOOD] (define-fun q1_model35 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) true
           false)
@@ -986,9 +1022,7 @@
                   (distinct (q1         x!0)
                             (q1_model35 x!0))))
 [GOOD] (define-fun q2_model35 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false))
+          false
        )
 [GOOD] (define-fun q2_model35_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1003,18 +1037,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model36 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model36_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model36 x!0))))
 [GOOD] (define-fun q2_model36 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
+          (ite (and (= x!0 true) (= x!1 false)) true
           false)
        )
 [GOOD] (define-fun q2_model36_reject () Bool
@@ -1030,20 +1065,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false false false) true false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model37 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model37_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model37 x!0))))
 [GOOD] (define-fun q2_model37 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
           (ite (and (= x!0 false) (= x!1 false)) false
-          true))
+          true)
        )
 [GOOD] (define-fun q2_model37_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1058,19 +1093,22 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
+              false
+              true
+              true)))
 [GOOD] (define-fun q1_model38 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) true
-          false)
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model38_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model38 x!0))))
 [GOOD] (define-fun q2_model38 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
           (ite (and (= x!0 true) (= x!1 false)) true
           false))
        )
@@ -1087,9 +1125,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model39 ((x!0 Bool)) Bool
           false
        )
@@ -1098,9 +1136,8 @@
                   (distinct (q1         x!0)
                             (q1_model39 x!0))))
 [GOOD] (define-fun q2_model39 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false)
        )
 [GOOD] (define-fun q2_model39_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1115,12 +1152,14 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) false) false true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
+              true
+              false
+              true)))
 [GOOD] (define-fun q1_model40 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
-          false)
+          false
        )
 [GOOD] (define-fun q1_model40_reject () Bool
           (exists ((x!0 Bool))
@@ -1128,7 +1167,8 @@
                             (q1_model40 x!0))))
 [GOOD] (define-fun q2_model40 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 false)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false))
        )
 [GOOD] (define-fun q2_model40_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1143,11 +1183,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) false) false true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model41 ((x!0 Bool)) Bool
-          (ite (and (= x!0 false)) true
+          (ite (and (= x!0 true)) true
           false)
        )
 [GOOD] (define-fun q1_model41_reject () Bool
@@ -1156,8 +1196,7 @@
                             (q1_model41 x!0))))
 [GOOD] (define-fun q2_model41 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 true)) true
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false))
+          false)
        )
 [GOOD] (define-fun q2_model41_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1172,19 +1211,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true false true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              true
+              false
+              false)))
 [GOOD] (define-fun q1_model42 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model42_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model42 x!0))))
 [GOOD] (define-fun q2_model42 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false)
+          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model42_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1199,20 +1243,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model43 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model43_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model43 x!0))))
 [GOOD] (define-fun q2_model43 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
           (ite (and (= x!0 true) (= x!1 false)) true
-          false))
+          false)
        )
 [GOOD] (define-fun q2_model43_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1227,20 +1270,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) false true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              true
+              true
+              false)))
 [GOOD] (define-fun q1_model44 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model44_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model44 x!0))))
 [GOOD] (define-fun q2_model44 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model44_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1255,19 +1302,23 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false false false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q1_model45 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model45_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model45 x!0))))
 [GOOD] (define-fun q2_model45 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true)
+          (ite (and (= x!0 true) (= x!1 true)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false))
        )
 [GOOD] (define-fun q2_model45_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1282,20 +1333,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true false true) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model46 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model46_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model46 x!0))))
 [GOOD] (define-fun q2_model46 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) true
-          (ite (and (= x!0 true) (= x!1 false)) true
-          false))
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model46_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1310,9 +1360,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false false false) true true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model47 ((x!0 Bool)) Bool
           false
        )
@@ -1321,7 +1374,7 @@
                   (distinct (q1         x!0)
                             (q1_model47 x!0))))
 [GOOD] (define-fun q2_model47 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 true)) false
           (ite (and (= x!0 false) (= x!1 false)) false
           true))
        )
@@ -1338,19 +1391,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 (lambda ((x!1 Bool)) x!1)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model48 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          (ite (and (= x!0 true)) true
+          false)
        )
 [GOOD] (define-fun q1_model48_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model48 x!0))))
 [GOOD] (define-fun q2_model48 ((x!0 Bool) (x!1 Bool)) Bool
-          false
+          (ite (and (= x!0 false) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model48_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1365,19 +1423,18 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model49 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          false
        )
 [GOOD] (define-fun q1_model49_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model49 x!0))))
 [GOOD] (define-fun q2_model49 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
+          (ite (and (= x!0 true) (= x!1 true)) true
           false)
        )
 [GOOD] (define-fun q2_model49_reject () Bool
@@ -1393,12 +1450,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true true true)))
 [GOOD] (define-fun q1_model50 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          true
        )
 [GOOD] (define-fun q1_model50_reject () Bool
           (exists ((x!0 Bool))
@@ -1421,21 +1477,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true true true) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model51 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          true
        )
 [GOOD] (define-fun q1_model51_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model51 x!0))))
 [GOOD] (define-fun q2_model51 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          (ite (and (= x!0 true) (= x!1 true)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model51_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1450,9 +1504,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) true true true) false true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) true false true)
+              true
+              true
+              true)))
 [GOOD] (define-fun q1_model52 ((x!0 Bool)) Bool
           true
        )
@@ -1461,8 +1518,8 @@
                   (distinct (q1         x!0)
                             (q1_model52 x!0))))
 [GOOD] (define-fun q2_model52 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
           (ite (and (= x!0 true) (= x!1 true)) true
+          (ite (and (= x!0 true) (= x!1 false)) true
           false))
        )
 [GOOD] (define-fun q2_model52_reject () Bool
@@ -1478,9 +1535,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false true true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model53 ((x!0 Bool)) Bool
           true
        )
@@ -1489,8 +1546,8 @@
                   (distinct (q1         x!0)
                             (q1_model53 x!0))))
 [GOOD] (define-fun q2_model53 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model53_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1505,19 +1562,21 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) false false false) true true false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              true
+              false
+              false)))
 [GOOD] (define-fun q1_model54 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          true
        )
 [GOOD] (define-fun q1_model54_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model54 x!0))))
 [GOOD] (define-fun q2_model54 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
+          (ite (and (= x!0 true) (= x!1 false)) false
           (ite (and (= x!0 false) (= x!1 false)) false
           true))
        )
@@ -1534,19 +1593,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) true true true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              true
+              false
+              false)))
 [GOOD] (define-fun q1_model55 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model55_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model55 x!0))))
 [GOOD] (define-fun q2_model55 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) true
-          false)
+          (ite (and (= x!0 true) (= x!1 false)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model55_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1561,9 +1625,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) false false false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model56 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) false
           true)
@@ -1573,8 +1637,8 @@
                   (distinct (q1         x!0)
                             (q1_model56 x!0))))
 [GOOD] (define-fun q2_model56 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) false
-          true)
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false)
        )
 [GOOD] (define-fun q2_model56_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1589,9 +1653,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) false true true)))
 [GOOD] (define-fun q1_model57 ((x!0 Bool)) Bool
           true
        )
@@ -1600,8 +1664,8 @@
                   (distinct (q1         x!0)
                             (q1_model57 x!0))))
 [GOOD] (define-fun q2_model57 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 true)) false
-          true)
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false)
        )
 [GOOD] (define-fun q2_model57_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1616,9 +1680,12 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 ((as const Array) true)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) false) false true true)
+              true
+              false
+              true)))
 [GOOD] (define-fun q1_model58 ((x!0 Bool)) Bool
           true
        )
@@ -1627,7 +1694,9 @@
                   (distinct (q1         x!0)
                             (q1_model58 x!0))))
 [GOOD] (define-fun q2_model58 ((x!0 Bool) (x!1 Bool)) Bool
-          true
+          (ite (and (= x!0 true) (= x!1 false)) true
+          (ite (and (= x!0 false) (= x!1 true)) true
+          false))
        )
 [GOOD] (define-fun q2_model58_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1642,19 +1711,19 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true false false)))
+[RECV] ((q2 ((as const (Array Bool Bool Bool)) false)))
 [GOOD] (define-fun q1_model59 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 false)) true
+          false)
        )
 [GOOD] (define-fun q1_model59_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model59 x!0))))
 [GOOD] (define-fun q2_model59 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
-          true)
+          false
        )
 [GOOD] (define-fun q2_model59_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1669,20 +1738,24 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) false) false true)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) true) true false false)))
+[RECV] ((q2 (store (store ((as const (Array Bool Bool Bool)) true) false false false)
+              false
+              true
+              false)))
 [GOOD] (define-fun q1_model60 ((x!0 Bool)) Bool
-          (ite (and (= x!0 true)) false
-          true)
+          (ite (and (= x!0 false)) true
+          false)
        )
 [GOOD] (define-fun q1_model60_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model60 x!0))))
 [GOOD] (define-fun q2_model60 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 true) (= x!1 false)) false
-          true)
+          (ite (and (= x!0 false) (= x!1 true)) false
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true))
        )
 [GOOD] (define-fun q2_model60_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1697,20 +1770,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false true true) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) false) true false true)))
 [GOOD] (define-fun q1_model61 ((x!0 Bool)) Bool
-          false
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model61_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model61 x!0))))
 [GOOD] (define-fun q2_model61 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) true
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false))
+          (ite (and (= x!0 true) (= x!1 false)) true
+          false)
        )
 [GOOD] (define-fun q2_model61_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1725,9 +1798,9 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 (store ((as const Array) true) true false)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) false) false true true) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false false false)))
 [GOOD] (define-fun q1_model62 ((x!0 Bool)) Bool
           (ite (and (= x!0 true)) false
           true)
@@ -1737,9 +1810,8 @@
                   (distinct (q1         x!0)
                             (q1_model62 x!0))))
 [GOOD] (define-fun q2_model62 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) true
-          (ite (and (= x!0 false) (= x!1 true)) true
-          false))
+          (ite (and (= x!0 false) (= x!1 false)) false
+          true)
        )
 [GOOD] (define-fun q2_model62_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1754,11 +1826,11 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 ((as const (Array Bool Bool)) false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store (store ((as const Array) true) true false false) true true false)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) true true false)))
 [GOOD] (define-fun q1_model63 ((x!0 Bool)) Bool
-          true
+          false
        )
 [GOOD] (define-fun q1_model63_reject () Bool
           (exists ((x!0 Bool))
@@ -1766,8 +1838,7 @@
                             (q1_model63 x!0))))
 [GOOD] (define-fun q2_model63 ((x!0 Bool) (x!1 Bool)) Bool
           (ite (and (= x!0 true) (= x!1 true)) false
-          (ite (and (= x!0 true) (= x!1 false)) false
-          true))
+          true)
        )
 [GOOD] (define-fun q2_model63_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1782,19 +1853,20 @@
 [SEND] (check-sat)
 [RECV] sat
 [SEND] (get-value (q1))
-[RECV] ((q1 ((as const Array) true)))
+[RECV] ((q1 (store ((as const (Array Bool Bool)) true) true false)))
 [SEND] (get-value (q2))
-[RECV] ((q2 (store ((as const Array) false) false false true)))
+[RECV] ((q2 (store ((as const (Array Bool Bool Bool)) true) false true false)))
 [GOOD] (define-fun q1_model64 ((x!0 Bool)) Bool
-          true
+          (ite (and (= x!0 true)) false
+          true)
        )
 [GOOD] (define-fun q1_model64_reject () Bool
           (exists ((x!0 Bool))
                   (distinct (q1         x!0)
                             (q1_model64 x!0))))
 [GOOD] (define-fun q2_model64 ((x!0 Bool) (x!1 Bool)) Bool
-          (ite (and (= x!0 false) (= x!1 false)) true
-          false)
+          (ite (and (= x!0 false) (= x!1 true)) false
+          true)
        )
 [GOOD] (define-fun q2_model64_reject () Bool
           (exists ((x!0 Bool) (x!1 Bool))
@@ -1813,86 +1885,89 @@
 
 RESULT: Solution #1:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True 
-  q2 _     _     = False
+  q2 False True = False
+  q2 _     _    = True 
 Solution #2:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = False
-  q2 True False = False
-  q2 _    _     = True 
+  q2 True True = False
+  q2 _    _    = True 
 Solution #3:
   q1 :: Bool -> Bool
   q1 True = False
   q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True 
-  q2 False True  = True 
-  q2 _     _     = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #4:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True 
-  q2 False True  = True 
-  q2 _     _     = False
+  q2 True False = True 
+  q2 _    _     = False
 Solution #5:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 False = True 
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True 
+  q2 False True  = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #6:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 False = True 
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 _    _     = True 
+  q2 _ _ = False
 Solution #7:
   q1 :: Bool -> Bool
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = True
+  q2 True  False = True 
+  q2 False True  = True 
+  q2 _     _     = False
 Solution #8:
   q1 :: Bool -> Bool
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True 
+  q2 False True = True 
+  q2 _     _    = False
 Solution #9:
   q1 :: Bool -> Bool
   q1 True = False
   q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = False
-  q2 _     _     = True 
+  q2 False True = True 
+  q2 _     _    = False
 Solution #10:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True 
-  q2 _    _    = False
+  q2 True  False = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #11:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = False
+  q2 True  False = False
   q2 False False = False
   q2 _     _     = True 
 Solution #12:
@@ -1900,230 +1975,224 @@
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True 
-  q2 _     _    = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #13:
   q1 :: Bool -> Bool
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True 
-  q2 True  True = True 
-  q2 _     _    = False
+  q2 True True  = True 
+  q2 True False = True 
+  q2 _    _     = False
 Solution #14:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True 
-  q2 True  True = True 
-  q2 _     _    = False
+  q2 True False = True 
+  q2 _    _     = False
 Solution #15:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
   q2 True True = True 
   q2 _    _    = False
 Solution #16:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True 
-  q2 _     _    = False
+  q2 True True = True 
+  q2 _    _    = False
 Solution #17:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = False
+  q2 False True  = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #18:
   q1 :: Bool -> Bool
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = False
+  q2 False True  = False
   q2 False False = False
   q2 _     _     = True 
 Solution #19:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = True 
-  q2 True  False = True 
-  q2 _     _     = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #20:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = False
-  q2 _     _     = True 
+  q2 True  True = True 
+  q2 False True = True 
+  q2 _     _    = False
 Solution #21:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True  = True 
-  q2 True  False = True 
-  q2 _     _     = False
+  q2 True  True  = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #22:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = True 
   q2 True False = True 
   q2 _    _     = False
 Solution #23:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True 
-  q2 _    _     = False
+  q2 True  False = False
+  q2 False False = False
+  q2 _     _     = True 
 Solution #24:
   q1 :: Bool -> Bool
-  q1 False = True 
-  q1 _     = False
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = True 
-  q2 True False = True 
-  q2 _    _     = False
+  q2 True True = True 
+  q2 _    _    = False
 Solution #25:
   q1 :: Bool -> Bool
-  q1 False = True 
-  q1 _     = False
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True 
-  q2 _    _     = False
+  q2 True  False = True 
+  q2 False True  = True 
+  q2 _     _     = False
 Solution #26:
   q1 :: Bool -> Bool
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = True 
-  q2 True False = True 
-  q2 _    _     = False
+  q2 False True = True 
+  q2 _     _    = False
 Solution #27:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True  = True 
-  q2 True False = True 
-  q2 _    _     = False
+  q2 False True  = True 
+  q2 True  False = True 
+  q2 _     _     = False
 Solution #28:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = False
   q2 False False = False
   q2 _     _     = True 
 Solution #29:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = True 
-  q2 _    _    = False
+  q2 True False = True 
+  q2 _    _     = False
 Solution #30:
   q1 :: Bool -> Bool
   q1 True = True 
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True  = True 
-  q2 True  False = True 
-  q2 _     _     = False
+  q2 _ _ = False
 Solution #31:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True 
-  q2 _     _    = False
+  q2 _ _ = True
 Solution #32:
   q1 :: Bool -> Bool
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = False
-  q2 _     _     = True 
+  q2 True  True = False
+  q2 False True = False
+  q2 _     _    = True 
 Solution #33:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True 
-  q2 _    _     = False
+  q2 False True = True 
+  q2 _     _    = False
 Solution #34:
   q1 :: Bool -> Bool
   q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = True 
-  q2 _     _    = False
+  q2 False True = False
+  q2 _     _    = True 
 Solution #35:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
   q2 True True = True 
   q2 _    _    = False
 Solution #36:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = True 
-  q2 _    _     = False
+  q2 False True = False
+  q2 True  True = False
+  q2 _     _    = True 
 Solution #37:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = False
+  q2 _ _ = True
 Solution #38:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = False
-  q2 False False = False
-  q2 _     _     = True 
+  q2 True True = False
+  q2 _    _    = True 
 Solution #39:
   q1 :: Bool -> Bool
   q1 True = True 
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False False = False
-  q2 _     _     = True 
+  q2 _ _ = True
 Solution #40:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True False = False
-  q2 True True  = False
-  q2 _    _     = True 
+  q2 True True = False
+  q2 _    _    = True 
 Solution #41:
   q1 :: Bool -> Bool
   q1 True = True 
@@ -2138,67 +2207,68 @@
   q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = True
+  q2 False True = False
+  q2 _     _    = True 
 Solution #43:
   q1 :: Bool -> Bool
-  q1 False = True 
-  q1 _     = False
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 _ _ = True
+  q2 True  False = True 
+  q2 False False = True 
+  q2 _     _     = False
 Solution #44:
   q1 :: Bool -> Bool
-  q1 False = True 
-  q1 _     = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True 
+  q2 False True = False
+  q2 _     _    = True 
 Solution #45:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True True = False
-  q2 _    _    = True 
+  q2 True  False = True 
+  q2 False False = True 
+  q2 _     _     = False
 Solution #46:
   q1 :: Bool -> Bool
-  q1 False = True 
-  q1 _     = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True 
+  q2 True  True  = True 
   q2 False False = True 
   q2 _     _     = False
 Solution #47:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
   q2 False False = True 
   q2 _     _     = False
 Solution #48:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True = False
-  q2 False True = False
-  q2 _     _    = True 
+  q2 False False = True 
+  q2 _     _     = False
 Solution #49:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  False = True 
+  q2 True  True  = True 
   q2 False False = True 
   q2 _     _     = False
 Solution #50:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
   q2 False False = True 
@@ -2208,48 +2278,50 @@
   q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True 
+  q2 True False = False
+  q2 _    _     = True 
 Solution #52:
   q1 :: Bool -> Bool
-  q1 False = True 
-  q1 _     = False
+  q1 True = False
+  q1 _    = True 
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True 
+  q2 True False = False
+  q2 _    _     = True 
 Solution #53:
   q1 :: Bool -> Bool
-  q1 True = True 
-  q1 _    = False
+  q1 _ = True
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True 
+  q2 True True  = False
+  q2 True False = False
+  q2 _    _     = True 
 Solution #54:
   q1 :: Bool -> Bool
-  q1 _ = False
+  q1 False = True 
+  q1 _     = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 False True = False
-  q2 _     _    = True 
+  q2 True True  = False
+  q2 True False = False
+  q2 _    _     = True 
 Solution #55:
   q1 :: Bool -> Bool
-  q1 _ = True
+  q1 _ = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = True 
-  q2 False False = True 
-  q2 _     _     = False
+  q2 True True  = False
+  q2 True False = False
+  q2 _    _     = True 
 Solution #56:
   q1 :: Bool -> Bool
-  q1 True = False
-  q1 _    = True 
+  q1 True = True 
+  q1 _    = False
 
   q2 :: Bool -> Bool -> Bool
-  q2 True  True  = True 
-  q2 False False = True 
-  q2 _     _     = False
+  q2 True True  = False
+  q2 True False = False
+  q2 _    _     = True 
 Solution #57:
   q1 :: Bool -> Bool
   q1 True = True 
diff --git a/SBVTestSuite/SBVHLint.hs b/SBVTestSuite/SBVHLint.hs
--- a/SBVTestSuite/SBVHLint.hs
+++ b/SBVTestSuite/SBVHLint.hs
@@ -20,6 +20,7 @@
 arguments =
     [ "Data"
     , "SBVTestSuite"
+    , "Documentation"
     , "-i", "Use otherwise"
     , "-i", "Parse error"
     , "--cpp-simple"
diff --git a/SBVTestSuite/TestSuite/Arrays/InitVals.hs b/SBVTestSuite/TestSuite/Arrays/InitVals.hs
--- a/SBVTestSuite/TestSuite/Arrays/InitVals.hs
+++ b/SBVTestSuite/TestSuite/Arrays/InitVals.hs
@@ -68,4 +68,4 @@
           t2 p goldFile = do r <- satWith defaultSMTCfg{verbose=True, redirectVerbose = Just goldFile} (constArr2 p)
                              appendFile goldFile ("\nFINAL OUTPUT:\n" ++ show r ++ "\n")
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Arrays/Query.hs b/SBVTestSuite/TestSuite/Arrays/Query.hs
--- a/SBVTestSuite/TestSuite/Arrays/Query.hs
+++ b/SBVTestSuite/TestSuite/Arrays/Query.hs
@@ -153,4 +153,4 @@
 
                 pure (r1, r2)
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/ArithNoSolver.hs b/SBVTestSuite/TestSuite/Basics/ArithNoSolver.hs
--- a/SBVTestSuite/TestSuite/Basics/ArithNoSolver.hs
+++ b/SBVTestSuite/TestSuite/Basics/ArithNoSolver.hs
@@ -784,4 +784,4 @@
 
 sst :: [STuple Integer Integer]
 sst = map literal st
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/ArithSolver.hs b/SBVTestSuite/TestSuite/Basics/ArithSolver.hs
--- a/SBVTestSuite/TestSuite/Basics/ArithSolver.hs
+++ b/SBVTestSuite/TestSuite/Basics/ArithSolver.hs
@@ -869,4 +869,4 @@
 st :: [(Integer, Integer)]
 st = [(1, 2), (-1, -5), (0, 9), (5, 5)]
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/Exceptions.hs b/SBVTestSuite/TestSuite/Basics/Exceptions.hs
--- a/SBVTestSuite/TestSuite/Basics/Exceptions.hs
+++ b/SBVTestSuite/TestSuite/Basics/Exceptions.hs
@@ -65,4 +65,4 @@
                         query $ do constrain $ x*y .== x*x
                                    show <$> checkSat
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/Lambda.hs b/SBVTestSuite/TestSuite/Basics/Lambda.hs
--- a/SBVTestSuite/TestSuite/Basics/Lambda.hs
+++ b/SBVTestSuite/TestSuite/Basics/Lambda.hs
@@ -334,13 +334,13 @@
                     _ -> error $ "Unexpected output: " P.++ show cs
 
 
-{-# ANN module ("HLint: ignore Use map once"   :: String) #-}
-{-# ANN module ("HLint: ignore Use sum"        :: String) #-}
-{-# ANN module ("HLint: ignore Fuse foldr/map" :: String) #-}
-{-# ANN module ("HLint: ignore Use zipWith"    :: String) #-}
-{-# ANN module ("HLint: ignore Use uncurry"    :: String) #-}
-{-# ANN module ("HLint: ignore Use even"       :: String) #-}
-{-# ANN module ("HLint: ignore Use odd"        :: String) #-}
-{-# ANN module ("HLint: ignore Use product"    :: String) #-}
-{-# ANN module ("HLint: ignore Avoid lambda"   :: String) #-}
-{-# ANN module ("HLint: ignore Eta reduce"     :: String) #-}
+{- HLint ignore module "Use map once"   -}
+{- HLint ignore module "Use sum"        -}
+{- HLint ignore module "Fuse foldr/map" -}
+{- HLint ignore module "Use zipWith"    -}
+{- HLint ignore module "Use uncurry"    -}
+{- HLint ignore module "Use even"       -}
+{- HLint ignore module "Use odd"        -}
+{- HLint ignore module "Use product"    -}
+{- HLint ignore module "Avoid lambda"   -}
+{- HLint ignore module "Eta reduce"     -}
diff --git a/SBVTestSuite/TestSuite/Basics/Quantifiers.hs b/SBVTestSuite/TestSuite/Basics/Quantifiers.hs
--- a/SBVTestSuite/TestSuite/Basics/Quantifiers.hs
+++ b/SBVTestSuite/TestSuite/Basics/Quantifiers.hs
@@ -82,5 +82,5 @@
          t2 A E act = pure $ quantifiedBool $ \(Forall x) (Exists y) -> act x y
          t2 A A act = pure $ quantifiedBool $ \(Forall x) (Forall y) -> act x y
 
-{-# ANN module ("HLint: ignore Reduce duplication"     :: String) #-}
-{-# ANN module ("HLint: ignore Unused LANGUAGE pragma" :: String) #-}
+{- HLint ignore module "Reduce duplication"     -}
+{- HLint ignore module "Unused LANGUAGE pragma" -}
diff --git a/SBVTestSuite/TestSuite/Basics/Set.hs b/SBVTestSuite/TestSuite/Basics/Set.hs
--- a/SBVTestSuite/TestSuite/Basics/Set.hs
+++ b/SBVTestSuite/TestSuite/Basics/Set.hs
@@ -168,4 +168,4 @@
     y <- free_
     return $ x ./= y
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/Sum.hs b/SBVTestSuite/TestSuite/Basics/Sum.hs
--- a/SBVTestSuite/TestSuite/Basics/Sum.hs
+++ b/SBVTestSuite/TestSuite/Basics/Sum.hs
@@ -142,4 +142,4 @@
 
    constrain $ isRight $ ite b x y
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Basics/Tuple.hs b/SBVTestSuite/TestSuite/Basics/Tuple.hs
--- a/SBVTestSuite/TestSuite/Basics/Tuple.hs
+++ b/SBVTestSuite/TestSuite/Basics/Tuple.hs
@@ -147,5 +147,5 @@
                 Unsat -> return ()
                 _     -> error "did not expect this!"
 
-{-# ANN module ("HLint: ignore Use ."        :: String) #-}
-{-# ANN module ("HLint: ignore Redundant ^." :: String) #-}
+{- HLint ignore module "Use ."        -}
+{- HLint ignore module "Redundant ^." -}
diff --git a/SBVTestSuite/TestSuite/Basics/UISat.hs b/SBVTestSuite/TestSuite/Basics/UISat.hs
--- a/SBVTestSuite/TestSuite/Basics/UISat.hs
+++ b/SBVTestSuite/TestSuite/Basics/UISat.hs
@@ -56,4 +56,4 @@
            registerUISMTFunction q1
            registerUISMTFunction q2
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/CRC/CCITT_Unidir.hs b/SBVTestSuite/TestSuite/CRC/CCITT_Unidir.hs
--- a/SBVTestSuite/TestSuite/CRC/CCITT_Unidir.hs
+++ b/SBVTestSuite/TestSuite/CRC/CCITT_Unidir.hs
@@ -60,4 +60,4 @@
    where frameSent     = blastLE $ mkFrame sent
          frameReceived = blastLE $ mkFrame received
 
-{-# ANN crc_48_16 ("HLint: ignore Use camelCase" :: String) #-}
+{- HLint ignore crc_48_16 "Use camelCase" -}
diff --git a/SBVTestSuite/TestSuite/CRC/GenPoly.hs b/SBVTestSuite/TestSuite/CRC/GenPoly.hs
--- a/SBVTestSuite/TestSuite/CRC/GenPoly.hs
+++ b/SBVTestSuite/TestSuite/CRC/GenPoly.hs
@@ -59,5 +59,5 @@
 mkPoly :: SWord 16 -> SWord 64
 mkPoly d = 1 # d
 
-{-# ANN crc_48_16 ("HLint: ignore Use camelCase" :: String) #-}
-{-# ANN crcGoodE  ("HLint: ignore Use <$>"       :: String) #-}
+{- HLint ignore crc_48_16 "Use camelCase" -}
+{- HLint ignore crcGoodE  "Use <$>"       -}
diff --git a/SBVTestSuite/TestSuite/CRC/USB5.hs b/SBVTestSuite/TestSuite/CRC/USB5.hs
--- a/SBVTestSuite/TestSuite/CRC/USB5.hs
+++ b/SBVTestSuite/TestSuite/CRC/USB5.hs
@@ -58,4 +58,4 @@
          frameSent     = mkFrame sent
          frameReceived = mkFrame received
 
-{-# ANN crc_11_16 ("HLint: ignore Use camelCase" :: String) #-}
+{- HLint ignore crc_11_16 "Use camelCase" -}
diff --git a/SBVTestSuite/TestSuite/Char/Char.hs b/SBVTestSuite/TestSuite/Char/Char.hs
--- a/SBVTestSuite/TestSuite/Char/Char.hs
+++ b/SBVTestSuite/TestSuite/Char/Char.hs
@@ -108,5 +108,5 @@
          c <- sChar "c"
          constrain $ L.length (cf4 x c) .== 1
 
-{-# ANN module ("HLint: ignore Use ."        :: String) #-}
-{-# ANN module ("HLint: ignore Redundant ^." :: String) #-}
+{- HLint ignore module "Use ."        -}
+{- HLint ignore module "Redundant ^." -}
diff --git a/SBVTestSuite/TestSuite/CodeGeneration/Floats.hs b/SBVTestSuite/TestSuite/CodeGeneration/Floats.hs
--- a/SBVTestSuite/TestSuite/CodeGeneration/Floats.hs
+++ b/SBVTestSuite/TestSuite/CodeGeneration/Floats.hs
@@ -164,4 +164,4 @@
           , test1 "d_FP_IsPositive"         (fpIsPositive :: SDouble -> SBool)
           ]
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Crypto/AES.hs b/SBVTestSuite/TestSuite/Crypto/AES.hs
--- a/SBVTestSuite/TestSuite/Crypto/AES.hs
+++ b/SBVTestSuite/TestSuite/Crypto/AES.hs
@@ -32,6 +32,6 @@
                                res | d    = aesEncrypt pt encKs
                                    | True = aesDecrypt pt decKs
                            cgOutputArr "ct" res
-       aes128Comps = [(f, setVals c) | (f, c) <- aesLibComponents 128]
+       aes128Comps = [(f, setVals c) | (f, _, c) <- aesLibComponents 128]
        setVals c = cgSetDriverValues (repeat 0) >> c
        thd (_, _, r) = r
diff --git a/SBVTestSuite/TestSuite/Optimization/Combined.hs b/SBVTestSuite/TestSuite/Optimization/Combined.hs
--- a/SBVTestSuite/TestSuite/Optimization/Combined.hs
+++ b/SBVTestSuite/TestSuite/Optimization/Combined.hs
@@ -84,4 +84,4 @@
              minimize "min_x"            x
              maximize "max_x_plus_x"   $ x + x
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Optimization/ExtensionField.hs b/SBVTestSuite/TestSuite/Optimization/ExtensionField.hs
--- a/SBVTestSuite/TestSuite/Optimization/ExtensionField.hs
+++ b/SBVTestSuite/TestSuite/Optimization/ExtensionField.hs
@@ -52,4 +52,4 @@
 
                   maximize "x_plus_y" $ x + y
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Optimization/Floats.hs b/SBVTestSuite/TestSuite/Optimization/Floats.hs
--- a/SBVTestSuite/TestSuite/Optimization/Floats.hs
+++ b/SBVTestSuite/TestSuite/Optimization/Floats.hs
@@ -71,4 +71,4 @@
 
        minimize "metric-min-x+y" $ observe "min-x+y" (x+y)
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Optimization/Quantified.hs b/SBVTestSuite/TestSuite/Optimization/Quantified.hs
--- a/SBVTestSuite/TestSuite/Optimization/Quantified.hs
+++ b/SBVTestSuite/TestSuite/Optimization/Quantified.hs
@@ -75,4 +75,4 @@
         constrain $ b .>= 0
         minimize "goal" $ a+b
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Overflows/Arithmetic.hs b/SBVTestSuite/TestSuite/Overflows/Arithmetic.hs
--- a/SBVTestSuite/TestSuite/Overflows/Arithmetic.hs
+++ b/SBVTestSuite/TestSuite/Overflows/Arithmetic.hs
@@ -239,4 +239,4 @@
 
                        return $ overflowHappens `exactlyWhen` (extResult `svGreaterThan` toLarge (maxBound :: SBV a))
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Queries/Interpolants.hs b/SBVTestSuite/TestSuite/Queries/Interpolants.hs
--- a/SBVTestSuite/TestSuite/Queries/Interpolants.hs
+++ b/SBVTestSuite/TestSuite/Queries/Interpolants.hs
@@ -94,4 +94,4 @@
                                  ,   a .== b .&& g c ./= g d
                                  ]
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Queries/Sums.hs b/SBVTestSuite/TestSuite/Queries/Sums.hs
--- a/SBVTestSuite/TestSuite/Queries/Sums.hs
+++ b/SBVTestSuite/TestSuite/Queries/Sums.hs
@@ -174,4 +174,4 @@
    bv <- getValue b
    return (xv, yv, bv)
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/SBVTestSuite/TestSuite/Queries/Tuples.hs b/SBVTestSuite/TestSuite/Queries/Tuples.hs
--- a/SBVTestSuite/TestSuite/Queries/Tuples.hs
+++ b/SBVTestSuite/TestSuite/Queries/Tuples.hs
@@ -64,5 +64,5 @@
        then return av
        else error $ "Didn't expect this: " ++ show av
 
-{-# ANN module ("HLint: ignore Use ."        :: String) #-}
-{-# ANN module ("HLint: ignore Redundant ^." :: String) #-}
+{- HLint ignore module "Use ."        -}
+{- HLint ignore module "Redundant ^." -}
diff --git a/SBVTestSuite/TestSuite/Queries/UISatEx.hs b/SBVTestSuite/TestSuite/Queries/UISatEx.hs
--- a/SBVTestSuite/TestSuite/Queries/UISatEx.hs
+++ b/SBVTestSuite/TestSuite/Queries/UISatEx.hs
@@ -107,4 +107,4 @@
 
 -- HLint complains about TypeApplications pragma, but if I remove it GHC complains
 -- I'm not sure who is right here; so ignore.
-{-# ANN module ("HLint: ignore Unused LANGUAGE pragma" :: String) #-}
+{- HLint ignore module "Unused LANGUAGE pragma" -}
diff --git a/SBVTestSuite/Utils/SBVTestFramework.hs b/SBVTestSuite/Utils/SBVTestFramework.hs
--- a/SBVTestSuite/Utils/SBVTestFramework.hs
+++ b/SBVTestSuite/Utils/SBVTestFramework.hs
@@ -233,4 +233,4 @@
       | True
       -> throwIO e
 
-{-# ANN module ("HLint: ignore Reduce duplication" :: String) #-}
+{- HLint ignore module "Reduce duplication" -}
diff --git a/sbv.cabal b/sbv.cabal
--- a/sbv.cabal
+++ b/sbv.cabal
@@ -1,7 +1,7 @@
 Cabal-Version: 2.2
 
 Name        : sbv
-Version     : 10.1
+Version     : 10.2
 Category    : Formal Methods, Theorem Provers, Bit vectors, Symbolic Computation, Math, SMT
 Synopsis    : SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.
 Description : Express properties about Haskell programs and automatically prove them using SMT
@@ -30,7 +30,7 @@
 common common-settings
    default-language: Haskell2010
    ghc-options     : -Wall -O2
-   build-depends   : base >= 4.11 && < 5
+   build-depends   : base >= 4.16 && < 5
 
    if impl(ghc >= 8.10.1)
       ghc-options  : -Wunused-packages
@@ -98,6 +98,7 @@
                   , Data.SBV.Tools.BoundedFix
                   , Data.SBV.Tools.CodeGen
                   , Data.SBV.Tools.GenTest
+                  , Data.SBV.Tools.NaturalInduction
                   , Data.SBV.Tools.Overflow
                   , Data.SBV.Tools.Polynomial
                   , Data.SBV.Tools.Range
@@ -119,6 +120,7 @@
                   , Documentation.SBV.Examples.CodeGeneration.Uninterpreted
                   , Documentation.SBV.Examples.Crypto.AES
                   , Documentation.SBV.Examples.Crypto.RC4
+                  , Documentation.SBV.Examples.Crypto.Prince
                   , Documentation.SBV.Examples.Crypto.SHA
                   , Documentation.SBV.Examples.DeltaSat.DeltaSat
                   , Documentation.SBV.Examples.Existentials.CRCPolynomial
